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 #include <ndrx_config.h>
0035 #include <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <memory.h>
0039 #include <libxml/xmlreader.h>
0040 #include <errno.h>
0041
0042 #include <ndrstandard.h>
0043 #include <userlog.h>
0044 #include <atmi.h>
0045 #include <sys/stat.h>
0046 #include <sys/types.h>
0047 #include <nstdutil.h>
0048 #include <exenv.h>
0049 #include <libndrxconf.h>
0050 #include <singlegrp.h>
0051
0052 #include "cpmsrv.h"
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 expublic cpm_process_t *G_clt_config=NULL;
0064
0065
0066
0067
0068 exprivate ndrx_env_group_t * M_envgrouphash = NULL;
0069
0070
0071
0072
0073 expublic ndrx_procgroups_t * ndrx_G_procgroups_config = NULL;
0074
0075 exprivate MUTEX_LOCKDECL(M_config_lock);
0076
0077
0078
0079
0080
0081
0082
0083 expublic void cpm_lock_config(void)
0084 {
0085 MUTEX_LOCK_V(M_config_lock);
0086 }
0087
0088
0089
0090
0091
0092 expublic void cpm_unlock_config(void)
0093 {
0094 MUTEX_UNLOCK_V(M_config_lock);
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 expublic void cpm_get_key(char *key_out, int key_outsz, char *tag, char *subsect)
0106 {
0107 snprintf(key_out, key_outsz, "%s%c%s", tag, NDRX_CPM_SEP, subsect);
0108 }
0109
0110
0111
0112
0113
0114
0115 expublic cpm_process_t * cpm_client_get(char *tag, char *subsect)
0116 {
0117 cpm_process_t *r=NULL;
0118
0119 char key[CPM_KEY_LEN];
0120
0121 cpm_get_key(key, sizeof(key), tag, subsect);
0122
0123 EXHASH_FIND_STR( G_clt_config, key, r);
0124
0125 if (NULL!=r)
0126 {
0127 return r;
0128 }
0129 else
0130 {
0131 return NULL;
0132 }
0133 }
0134
0135
0136
0137
0138
0139
0140 expublic cpm_process_t * cpm_get_client_by_pid(pid_t pid)
0141 {
0142 cpm_process_t *c = NULL;
0143 cpm_process_t *ct = NULL;
0144
0145
0146 EXHASH_ITER(hh, G_clt_config, c, ct)
0147 {
0148 if (c->dyn.pid == pid)
0149 {
0150 return c;
0151 }
0152 }
0153
0154 return NULL;
0155 }
0156
0157
0158
0159
0160
0161
0162 expublic cpm_process_t * cpm_start_all(void)
0163 {
0164 cpm_process_t *c = NULL;
0165 cpm_process_t *ct = NULL;
0166
0167
0168 EXHASH_ITER(hh, G_clt_config, c, ct)
0169 {
0170
0171 if (c->stat.flags & CPM_F_AUTO_START)
0172 {
0173 c->dyn.req_state = CLT_STATE_STARTED;
0174 c->dyn.cur_state = CLT_STATE_STARTING;
0175 }
0176 }
0177
0178 return NULL;
0179 }
0180
0181
0182
0183
0184
0185 expublic void cpm_set_cur_time(cpm_process_t *p_cltproc)
0186 {
0187 time (&p_cltproc->dyn.stattime);
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197 exprivate int parse_client(xmlDocPtr doc, xmlNodePtr cur)
0198 {
0199 int ret=EXSUCCEED;
0200 xmlAttrPtr attr;
0201
0202 cpm_process_t cltproc;
0203 cpm_process_t *p_cltproc = NULL;
0204 cpm_process_t *org_cltproc = NULL;
0205 char *p;
0206 cpm_process_t * p_cl;
0207 int loop_subsectfrom;
0208 int loop_subsectto;
0209 int i, genloop;
0210 char *token;
0211 char tmp_command_line[PATH_MAX+1+CPM_TAG_LEN+CPM_SUBSECT_LEN];
0212 ndrx_procgroup_t *p_grp;
0213 memset(&cltproc, 0, sizeof(cpm_process_t));
0214
0215 cltproc.stat.flags |= CPM_F_KILL_LEVEL_DEFAULT;
0216 cltproc.stat.rssmax = EXFAIL;
0217 cltproc.stat.vszmax = EXFAIL;
0218
0219 cltproc.stat.subsectfrom = EXFAIL;
0220 cltproc.stat.subsectto = EXFAIL;
0221
0222 for (attr=cur->properties; attr; attr = attr->next)
0223 {
0224 if (0==strcmp((char *)attr->name, "cmdline"))
0225 {
0226 p = (char *)xmlNodeGetContent(attr->children);
0227 NDRX_STRCPY_SAFE(cltproc.stat.command_line, p);
0228 xmlFree(p);
0229 }
0230 else if (0==strcmp((char *)attr->name, "env"))
0231 {
0232 p = (char *)xmlNodeGetContent(attr->children);
0233 NDRX_STRCPY_SAFE(cltproc.stat.env, p);
0234 xmlFree(p);
0235 }
0236 else if (0==strcmp((char *)attr->name, "cctag"))
0237 {
0238 p = (char *)xmlNodeGetContent(attr->children);
0239 NDRX_STRCPY_SAFE(cltproc.stat.cctag, p);
0240 xmlFree(p);
0241 }
0242 else if (0==strcmp((char *)attr->name, "wd"))
0243 {
0244 p = (char *)xmlNodeGetContent(attr->children);
0245 NDRX_STRCPY_SAFE(cltproc.stat.wd, p);
0246 xmlFree(p);
0247 }
0248 else if (0==strcmp((char *)attr->name, "stdout"))
0249 {
0250 p = (char *)xmlNodeGetContent(attr->children);
0251 NDRX_STRCPY_SAFE(cltproc.stat.log_stdout, p);
0252 xmlFree(p);
0253 }
0254 else if (0==strcmp((char *)attr->name, "stderr"))
0255 {
0256 p = (char *)xmlNodeGetContent(attr->children);
0257 NDRX_STRCPY_SAFE(cltproc.stat.log_stderr, p);
0258 xmlFree(p);
0259 }
0260 else if (0==strcmp((char *)attr->name, "log"))
0261 {
0262 p = (char *)xmlNodeGetContent(attr->children);
0263
0264 NDRX_STRCPY_SAFE(cltproc.stat.log_stdout, p);
0265 NDRX_STRCPY_SAFE(cltproc.stat.log_stderr, p);
0266 xmlFree(p);
0267 }
0268 else if (0==strcmp((char *)attr->name, "autostart"))
0269 {
0270 p = (char *)xmlNodeGetContent(attr->children);
0271
0272 if ('Y'==*p || 'y'==*p)
0273 {
0274 cltproc.stat.flags|=CPM_F_AUTO_START;
0275 }
0276
0277 xmlFree(p);
0278 }
0279 else if (0==strcmp((char*)attr->name, "rssmax"))
0280 {
0281 p = (char *)xmlNodeGetContent(attr->children);
0282
0283 if (EXSUCCEED!=ndrx_storage_decode(p, &cltproc.stat.rssmax))
0284 {
0285 NDRX_LOG(log_error, "Failed to parse `rssmax', invalid value");
0286 EXFAIL_OUT(ret);
0287 }
0288
0289 NDRX_LOG(log_debug, "rssmax: %ld bytes", cltproc.stat.rssmax);
0290 xmlFree(p);
0291 }
0292 else if (0==strcmp((char*)attr->name, "vszmax"))
0293 {
0294 p = (char *)xmlNodeGetContent(attr->children);
0295
0296 if (EXSUCCEED!=ndrx_storage_decode(p, &cltproc.stat.vszmax))
0297 {
0298 NDRX_LOG(log_error, "Failed to parse `vszmax', invalid value");
0299 EXFAIL_OUT(ret);
0300 }
0301
0302 NDRX_LOG(log_debug, "vszmax: %ld bytes", cltproc.stat.vszmax);
0303 xmlFree(p);
0304 }
0305 else if (0==strcmp((char*)attr->name, "subsectfrom"))
0306 {
0307 p = (char *)xmlNodeGetContent(attr->children);
0308
0309 cltproc.stat.subsectfrom = atoi(p);
0310
0311 NDRX_LOG(log_debug, "subsectfrom: %d", cltproc.stat.subsectfrom);
0312 xmlFree(p);
0313 }
0314 else if (0==strcmp((char*)attr->name, "subsectto"))
0315 {
0316 p = (char *)xmlNodeGetContent(attr->children);
0317
0318 cltproc.stat.subsectto = atoi(p);
0319
0320 NDRX_LOG(log_debug, "subsectto: %d", cltproc.stat.subsectto);
0321 xmlFree(p);
0322 }
0323 else if (0==strcmp((char *)attr->name, "klevel"))
0324 {
0325 int d;
0326 p = (char *)xmlNodeGetContent(attr->children);
0327
0328 d = atoi(p);
0329
0330 switch (d)
0331 {
0332 case 2:
0333 cltproc.stat.flags|=CPM_F_KILL_LEVEL_HIGH;
0334 case 1:
0335 cltproc.stat.flags|=CPM_F_KILL_LEVEL_LOW;
0336 break;
0337 case 0:
0338 cltproc.stat.flags&=~CPM_F_KILL_LEVEL_HIGH;
0339 cltproc.stat.flags&=~CPM_F_KILL_LEVEL_LOW;
0340 }
0341
0342 xmlFree(p);
0343 }
0344 else if (0==strcmp((char *)attr->name, "procgrp"))
0345 {
0346
0347 p = (char *)xmlNodeGetContent(attr->children);
0348 p_grp = ndrx_ndrxconf_procgroups_resolvenm(ndrx_G_procgroups_config, p);
0349
0350 if (NULL==p_grp)
0351 {
0352 NDRX_LOG(log_error, "Process group not defined: [%s]", p);
0353 userlog("Process group not defined: [%s]", p);
0354 xmlFree(p);
0355 EXFAIL_OUT(ret);
0356 }
0357
0358 cltproc.stat.procgrp_no=p_grp->grpno;
0359 NDRX_LOG(log_debug, "procgrp_no %d", cltproc.stat.procgrp_no);
0360
0361 xmlFree(p);
0362 }
0363 }
0364
0365
0366 if (EXEOS==cltproc.stat.command_line[0])
0367 {
0368 NDRX_LOG(log_error, "No client name at line %hd", cur->line);
0369 userlog("No client name at line %hd", cur->line);
0370 EXFAIL_OUT(ret);
0371 }
0372
0373
0374 cur=cur->children;
0375
0376 for (; cur; cur=cur->next)
0377 {
0378 if (0==strcmp("envs", (char *)cur->name))
0379 {
0380 if (EXSUCCEED!=ndrx_ndrxconf_envs_parse(doc, cur, &cltproc.stat.envs,
0381 M_envgrouphash, NULL))
0382 {
0383 NDRX_LOG(log_error, "Failed to parse environment groups for clients!");
0384 userlog("Failed to parse environment groups for clients!");
0385 EXFAIL_OUT(ret);
0386 }
0387 }
0388 else if (0==strcmp("exec", (char *)cur->name))
0389 {
0390
0391
0392 p_cltproc = NDRX_MALLOC(sizeof(cpm_process_t));
0393 if (NULL==p_cltproc)
0394 {
0395 NDRX_LOG(log_error, "malloc failed for p_cltproc!");
0396 userlog("malloc failed for p_cltproc!");
0397 EXFAIL_OUT(ret);
0398 }
0399
0400 memcpy(p_cltproc, &cltproc, sizeof(cltproc));
0401 p_cltproc->stat.envs = NULL;
0402
0403 if (EXSUCCEED!=ndrx_ndrxconf_envs_append(&p_cltproc->stat.envs,
0404 cltproc.stat.envs))
0405 {
0406 NDRX_LOG(log_error, "Failed to join envs %p %p", p_cltproc->stat.envs,
0407 cltproc.stat.envs);
0408 userlog("Failed to join envs %p %p", p_cltproc->stat.envs,
0409 cltproc.stat.envs);
0410 EXFAIL_OUT(ret);
0411 }
0412
0413
0414 for (attr=cur->properties; attr; attr = attr->next)
0415 {
0416 if (0==strcmp((char *)attr->name, "tag"))
0417 {
0418 p = (char *)xmlNodeGetContent(attr->children);
0419 NDRX_STRCPY_SAFE(p_cltproc->tag, p);
0420 xmlFree(p);
0421 }
0422 else if (0==strcmp((char *)attr->name, "subsect"))
0423 {
0424
0425 p = (char *)xmlNodeGetContent(attr->children);
0426 NDRX_STRCPY_SAFE(p_cltproc->subsect, p);
0427 xmlFree(p);
0428 }
0429 else if (0==strcmp((char *)attr->name, "env"))
0430 {
0431
0432 p = (char *)xmlNodeGetContent(attr->children);
0433 NDRX_STRCPY_SAFE(p_cltproc->stat.env, p);
0434 xmlFree(p);
0435 }
0436 else if (0==strcmp((char *)attr->name, "cctag"))
0437 {
0438
0439 p = (char *)xmlNodeGetContent(attr->children);
0440 NDRX_STRCPY_SAFE(p_cltproc->stat.cctag, p);
0441 xmlFree(p);
0442 }
0443 else if (0==strcmp((char *)attr->name, "wd"))
0444 {
0445
0446 p = (char *)xmlNodeGetContent(attr->children);
0447 NDRX_STRCPY_SAFE(p_cltproc->stat.wd, p);
0448 xmlFree(p);
0449 }
0450 else if (0==strcmp((char *)attr->name, "stdout"))
0451 {
0452 p = (char *)xmlNodeGetContent(attr->children);
0453 NDRX_STRCPY_SAFE(p_cltproc->stat.log_stdout, p);
0454 xmlFree(p);
0455 }
0456 else if (0==strcmp((char *)attr->name, "stderr"))
0457 {
0458 p = (char *)xmlNodeGetContent(attr->children);
0459 NDRX_STRCPY_SAFE(p_cltproc->stat.log_stderr, p);
0460 xmlFree(p);
0461 }
0462 else if (0==strcmp((char *)attr->name, "log"))
0463 {
0464 p = (char *)xmlNodeGetContent(attr->children);
0465
0466 NDRX_STRCPY_SAFE(p_cltproc->stat.log_stdout, p);
0467 NDRX_STRCPY_SAFE(p_cltproc->stat.log_stderr, p);
0468 xmlFree(p);
0469 }
0470 else if (0==strcmp((char *)attr->name, "autostart"))
0471 {
0472 p = (char *)xmlNodeGetContent(attr->children);
0473
0474 if ('Y'==*p || 'y'==*p)
0475 {
0476 p_cltproc->stat.flags|=CPM_F_AUTO_START;
0477 }
0478
0479 xmlFree(p);
0480 }
0481 else if (0==strcmp((char*)attr->name, "rssmax"))
0482 {
0483 p = (char *)xmlNodeGetContent(attr->children);
0484
0485 if (EXSUCCEED!=ndrx_storage_decode(p, &p_cltproc->stat.rssmax))
0486 {
0487 NDRX_LOG(log_error, "Failed to parse `rssmax', invalid value");
0488 EXFAIL_OUT(ret);
0489 }
0490
0491 NDRX_LOG(log_debug, "rssmax: %ld bytes", p_cltproc->stat.rssmax);
0492 xmlFree(p);
0493 }
0494 else if (0==strcmp((char*)attr->name, "vszmax"))
0495 {
0496 p = (char *)xmlNodeGetContent(attr->children);
0497
0498 if (EXSUCCEED!=ndrx_storage_decode(p, &p_cltproc->stat.vszmax))
0499 {
0500 NDRX_LOG(log_error, "Failed to parse `vszmax', invalid value");
0501 EXFAIL_OUT(ret);
0502 }
0503
0504 NDRX_LOG(log_debug, "vszmax: %ld bytes", p_cltproc->stat.vszmax);
0505 xmlFree(p);
0506 }
0507 else if (0==strcmp((char*)attr->name, "subsectfrom"))
0508 {
0509 p = (char *)xmlNodeGetContent(attr->children);
0510
0511 p_cltproc->stat.subsectfrom = atoi(p);
0512
0513 NDRX_LOG(log_debug, "subsectfrom: %d", p_cltproc->stat.subsectfrom);
0514 xmlFree(p);
0515 }
0516 else if (0==strcmp((char*)attr->name, "subsectto"))
0517 {
0518 p = (char *)xmlNodeGetContent(attr->children);
0519
0520 p_cltproc->stat.subsectto = atoi(p);
0521
0522 NDRX_LOG(log_debug, "subsectto: %d", p_cltproc->stat.subsectto);
0523 xmlFree(p);
0524 }
0525 else if (0==strcmp((char *)attr->name, "klevel"))
0526 {
0527 int d;
0528 p = (char *)xmlNodeGetContent(attr->children);
0529
0530 d = atoi(p);
0531
0532 switch (d)
0533 {
0534 case 2:
0535 p_cltproc->stat.flags|=CPM_F_KILL_LEVEL_HIGH;
0536 case 1:
0537 p_cltproc->stat.flags|=CPM_F_KILL_LEVEL_LOW;
0538 break;
0539
0540 case 0:
0541 p_cltproc->stat.flags&=~CPM_F_KILL_LEVEL_HIGH;
0542 p_cltproc->stat.flags&=~CPM_F_KILL_LEVEL_LOW;
0543 }
0544
0545 xmlFree(p);
0546 }
0547 else if (0==strcmp((char *)attr->name, "procgrp"))
0548 {
0549
0550 p = (char *)xmlNodeGetContent(attr->children);
0551 p_grp = ndrx_ndrxconf_procgroups_resolvenm(ndrx_G_procgroups_config, p);
0552
0553 if (NULL==p_grp)
0554 {
0555 NDRX_LOG(log_error, "Process group not defined: [%s]", p);
0556 userlog("Process group not defined: [%s]", p);
0557 xmlFree(p);
0558 EXFAIL_OUT(ret);
0559 }
0560
0561 p_cltproc->stat.procgrp_no=p_grp->grpno;
0562 NDRX_LOG(log_debug, "procgrp_no %d", p_cltproc->stat.procgrp_no);
0563
0564 xmlFree(p);
0565 }
0566 }
0567
0568 NDRX_LOG(log_debug, "klevel = low=%d high=%d",
0569 p_cltproc->stat.flags & CPM_F_KILL_LEVEL_LOW,
0570 p_cltproc->stat.flags & CPM_F_KILL_LEVEL_HIGH
0571 );
0572
0573
0574 if (EXEOS==p_cltproc->tag[0])
0575 {
0576 NDRX_LOG(log_error, "Missing tag at line %hd", cur->line);
0577 userlog("Missing tag at line %hd", cur->line);
0578 EXFAIL_OUT(ret);
0579 }
0580
0581 if (p_cltproc->stat.subsectfrom > EXFAIL &&
0582 p_cltproc->stat.subsectto < p_cltproc->stat.subsectfrom)
0583 {
0584 NDRX_LOG(log_error, "Invalid subsectfrom/subsectto (<) for [%s] "
0585 "range at line %hd", p_cltproc->tag, cur->line);
0586 userlog("Invalid subsectfrom/subsectto (<) for [%s] "
0587 "range at line %hd", p_cltproc->tag, cur->line);
0588 EXFAIL_OUT(ret);
0589 }
0590
0591 if (p_cltproc->stat.subsectto > EXFAIL && p_cltproc->stat.subsectfrom < 0)
0592 {
0593 NDRX_LOG(log_error, "Invalid config: subsectto (%d) > -1 && "
0594 "subsectfrom(%d) < 0 for [%s] "
0595 "range at line %hd", p_cltproc->stat.subsectto,
0596 p_cltproc->stat.subsectfrom,
0597 p_cltproc->tag, cur->line);
0598 userlog("Invalid config: subsectto (%d) > -1 && "
0599 "subsectfrom(%d) < 0 for [%s] "
0600 "range at line %hd", p_cltproc->stat.subsectto,
0601 p_cltproc->stat.subsectfrom,
0602 p_cltproc->tag, cur->line);
0603 EXFAIL_OUT(ret);
0604 }
0605
0606 if (p_cltproc->stat.subsectfrom > EXFAIL)
0607 {
0608 genloop = EXTRUE;
0609 loop_subsectfrom = p_cltproc->stat.subsectfrom;
0610 loop_subsectto = p_cltproc->stat.subsectto;
0611 org_cltproc = p_cltproc;
0612 }
0613 else
0614 {
0615 genloop = EXFALSE;
0616
0617 loop_subsectfrom = 0;
0618 loop_subsectto = 0;
0619 }
0620
0621 for (i=loop_subsectfrom; i<loop_subsectto+1; i++)
0622 {
0623 if (genloop)
0624 {
0625
0626 p_cltproc = NDRX_MALLOC(sizeof(cpm_process_t));
0627 if (NULL==p_cltproc)
0628 {
0629 NDRX_LOG(log_error, "malloc failed for p_cltproc (2) at %d!", i);
0630 userlog("malloc failed for p_cltproc (2) at %d!", i);
0631 EXFAIL_OUT(ret);
0632 }
0633
0634 memcpy(p_cltproc, org_cltproc, sizeof(cltproc));
0635
0636 snprintf(p_cltproc->subsect, sizeof(p_cltproc->subsect),
0637 "%d", i);
0638 }
0639 else
0640 {
0641
0642 if (EXEOS==p_cltproc->subsect[0])
0643 {
0644 NDRX_STRCPY_SAFE(p_cltproc->subsect, "-");
0645 }
0646 }
0647
0648
0649 if (EXSUCCEED!=setenv(NDRX_CLTTAG, p_cltproc->tag, 1))
0650 {
0651 NDRX_LOG(log_error, "Failed to set %s on line %hd",
0652 NDRX_CLTTAG, cur->line);
0653 userlog("Failed to set %s on line %hd",
0654 NDRX_CLTTAG, cur->line);
0655 EXFAIL_OUT(ret);
0656 }
0657
0658 if (EXSUCCEED!=setenv(NDRX_CLTSUBSECT, p_cltproc->subsect, 1))
0659 {
0660 NDRX_LOG(log_error, "Failed to set %s on line %hd",
0661 NDRX_CLTSUBSECT, cur->line);
0662 userlog("Failed to set %s on line %hd",
0663 NDRX_CLTSUBSECT, cur->line);
0664 EXFAIL_OUT(ret);
0665 }
0666
0667
0668 ndrx_str_env_subs_len(p_cltproc->stat.command_line,
0669 sizeof(p_cltproc->stat.command_line));
0670 ndrx_str_env_subs_len(p_cltproc->stat.env,
0671 sizeof(p_cltproc->stat.env));
0672 ndrx_str_env_subs_len(p_cltproc->stat.cctag,
0673 sizeof(p_cltproc->stat.cctag));
0674 ndrx_str_env_subs_len(p_cltproc->stat.wd,
0675 sizeof(p_cltproc->stat.wd));
0676
0677 ndrx_str_env_subs_len(p_cltproc->stat.log_stdout,
0678 sizeof(p_cltproc->stat.log_stdout));
0679 ndrx_str_env_subs_len(p_cltproc->stat.log_stderr,
0680 sizeof(p_cltproc->stat.log_stderr));
0681
0682
0683
0684 NDRX_STRCPY_SAFE(tmp_command_line, p_cltproc->stat.command_line);
0685
0686 token = ndrx_strtokblk(tmp_command_line, NDRX_CMDLINE_SEP, NDRX_CMDLINE_QUOTES);
0687
0688 if (NULL==token)
0689 {
0690 NDRX_LOG(log_error, "Invalid command line [%s]", tmp_command_line);
0691 EXFAIL_OUT(ret);
0692 }
0693
0694 NDRX_STRCPY_SAFE(p_cltproc->stat.procname, token);
0695
0696
0697 cpm_get_key(p_cltproc->key, sizeof(p_cltproc->key),
0698 p_cltproc->tag, p_cltproc->subsect);
0699
0700
0701 p_cl = cpm_client_get(p_cltproc->tag, p_cltproc->subsect);
0702
0703 if (NULL==p_cl)
0704 {
0705
0706
0707 cpm_set_cur_time(p_cltproc);
0708
0709
0710 p_cltproc->is_cfg_refresh = EXTRUE;
0711
0712
0713
0714 NDRX_LOG(log_info, "Adding %s/%s [%s] to process list",
0715 p_cltproc->tag, p_cltproc->subsect, p_cltproc->stat.command_line);
0716 EXHASH_ADD_STR( G_clt_config, key, p_cltproc );
0717 }
0718 else
0719 {
0720 NDRX_LOG(log_info, "Refreshing %s/%s [%s] ...",
0721 p_cltproc->tag, p_cltproc->subsect,
0722 p_cltproc->stat.command_line);
0723
0724 p_cl->is_cfg_refresh = EXTRUE;
0725
0726
0727
0728 memcpy(&p_cl->stat, &p_cltproc->stat, sizeof(p_cl->stat));
0729
0730 p_cl->stat.envs = NULL;
0731
0732 if (EXSUCCEED!=ndrx_ndrxconf_envs_append(&p_cl->stat.envs,
0733 p_cltproc->stat.envs))
0734 {
0735 NDRX_LOG(log_error, "Failed to join envs %p %p",
0736 &p_cl->stat.envs, p_cltproc->stat.envs);
0737 userlog("Failed to join envs %p %p", "Failed to join envs %p %p",
0738 &p_cl->stat.envs,
0739 p_cltproc->stat.envs);
0740 EXFAIL_OUT(ret);
0741 }
0742
0743
0744 ndrx_ndrxconf_envs_envs_free(&p_cltproc->stat.envs);
0745
0746 NDRX_FREE(p_cltproc);
0747 }
0748 }
0749
0750 if (genloop)
0751 {
0752
0753 NDRX_FREE(org_cltproc);
0754 }
0755 }
0756 }
0757
0758 out:
0759
0760 if (EXFAIL==ret && p_cltproc)
0761 {
0762 NDRX_FREE(p_cltproc);
0763 }
0764
0765
0766 if (NULL!=cltproc.stat.envs)
0767 {
0768 ndrx_ndrxconf_envs_envs_free(&cltproc.stat.envs);
0769 }
0770
0771 return ret;
0772 }
0773
0774
0775
0776
0777
0778
0779
0780 exprivate int parse_envs(xmlDocPtr doc, xmlNodePtr cur)
0781 {
0782 int ret=EXSUCCEED;
0783
0784 if (EXSUCCEED!=ndrx_ndrxconf_envs_group_parse(doc, cur, &M_envgrouphash))
0785 {
0786 NDRX_LOG(log_error, "Failed to parse environment groups for clients!");
0787 userlog("Failed to parse environment groups for clients!");
0788 EXFAIL_OUT(ret);
0789 }
0790
0791 out:
0792 return ret;
0793 }
0794
0795
0796
0797
0798
0799
0800
0801 exprivate int parse_clients(xmlDocPtr doc, xmlNodePtr cur)
0802 {
0803 int ret=EXSUCCEED;
0804
0805 for (; cur ; cur=cur->next)
0806 {
0807 if (0==strcmp((char*)cur->name, "client"))
0808 {
0809
0810 if (EXSUCCEED!=parse_client(doc, cur))
0811 {
0812 ret=EXFAIL;
0813 goto out;
0814 }
0815 }
0816 else if (0==strcmp((char*)cur->name, "envs")
0817 && EXSUCCEED!=parse_envs(doc, cur))
0818 {
0819 EXFAIL_OUT(ret);
0820 }
0821 }
0822 out:
0823
0824 if (NULL!=M_envgrouphash)
0825 {
0826 ndrx_ndrxconf_envs_groups_free(&M_envgrouphash);
0827 }
0828
0829 return ret;
0830 }
0831
0832
0833
0834
0835
0836
0837
0838
0839 exprivate int parse_config(xmlDocPtr doc, xmlNodePtr cur, char *config_file_short)
0840 {
0841 int ret=EXSUCCEED;
0842 ndrx_procgroups_t *tmp_conf=NULL;
0843 ndrx_ndrxconf_err_t err;
0844
0845 if (NULL==cur)
0846 {
0847 NDRX_LOG(log_error, "Empty config?");
0848 ret=EXFAIL;
0849 goto out;
0850 }
0851
0852
0853 do
0854 {
0855
0856 if (0==strcmp((char*)cur->name, "clients")
0857 && EXSUCCEED!=parse_clients(doc, cur->children))
0858 {
0859 EXFAIL_OUT(ret);
0860 }
0861 else if (0==strcmp((char*)cur->name, "procgroups"))
0862 {
0863 ret=ndrx_ndrxconf_procgroups_parse(&tmp_conf,
0864 doc, cur->children,
0865 config_file_short, &err);
0866
0867 if (EXSUCCEED!=ret)
0868 {
0869 EXFAIL_OUT(ret);
0870 }
0871
0872
0873 if (NULL!=ndrx_G_procgroups_config)
0874 {
0875 ndrx_ndrxconf_procgroups_free(ndrx_G_procgroups_config);
0876 }
0877
0878 ndrx_G_procgroups_config=tmp_conf;
0879 tmp_conf=NULL;
0880 }
0881
0882 cur=cur->next;
0883 } while (cur);
0884
0885 out:
0886
0887 if (NULL!=tmp_conf)
0888 {
0889 ndrx_ndrxconf_procgroups_free(tmp_conf);
0890 }
0891
0892 return ret;
0893 }
0894
0895
0896
0897
0898
0899
0900
0901 expublic int load_xml_config(char *config_file)
0902 {
0903 int ret=EXSUCCEED;
0904 xmlDocPtr doc;
0905 xmlNodePtr root;
0906
0907 doc = xmlReadFile(config_file, NULL, XML_PARSE_NOENT);
0908
0909 if (!doc)
0910 {
0911 NDRX_LOG(log_error, "Failed to open or parse %s", config_file);
0912 ret=EXFAIL;
0913 goto out;
0914 }
0915
0916
0917 if (!(root = xmlDocGetRootElement(doc)))
0918 {
0919 NDRX_LOG(log_error, "Failed to get root XML element");
0920 ret=EXFAIL;
0921 goto out;
0922 }
0923
0924
0925 ret=parse_config(doc, root->children, ndrx_basename(config_file));
0926
0927 out:
0928
0929 if (NULL!=doc)
0930 {
0931
0932 xmlFreeDoc(doc);
0933
0934
0935
0936
0937 xmlCleanupParser();
0938 }
0939
0940 return ret;
0941 }
0942
0943
0944
0945
0946
0947 expublic int load_config(void)
0948 {
0949 int ret = EXSUCCEED;
0950 cpm_process_t *c = NULL;
0951 cpm_process_t *ct = NULL;
0952
0953 static struct stat prev_attr;
0954 static struct stat attr;
0955
0956 static int first = EXTRUE;
0957 int was_locked = EXFALSE;
0958
0959
0960
0961 if (first)
0962 {
0963 memset(&prev_attr, 0, sizeof(prev_attr));
0964 first = EXFALSE;
0965 }
0966
0967 memset(&attr, 0, sizeof(attr));
0968
0969 if (EXSUCCEED!=stat(G_config.config_file, &attr))
0970 {
0971 NDRX_LOG(log_error, "Config file error [%s]: [%s]",
0972 G_config.config_file, strerror(errno));
0973 userlog("Config file error [%s]: [%s]",
0974 G_config.config_file, strerror(errno));
0975 EXFAIL_OUT(ret);
0976 }
0977
0978 if (0!=memcmp(&attr.st_mtime, &prev_attr.st_mtime, sizeof(attr.st_mtime)))
0979 {
0980 prev_attr = attr;
0981 }
0982 else
0983 {
0984
0985 goto out;
0986 }
0987
0988
0989 EXHASH_ITER(hh, G_clt_config, c, ct)
0990 {
0991 c->is_cfg_refresh = EXFALSE;
0992 }
0993
0994
0995
0996
0997
0998 cpm_lock_config();
0999 was_locked = EXTRUE;
1000
1001 if (EXSUCCEED!=load_xml_config(G_config.config_file))
1002 {
1003 NDRX_LOG(log_error, "Failed to parse config");
1004 userlog("Failed to parse config");
1005 EXFAIL_OUT(ret);
1006 }
1007
1008
1009 EXHASH_ITER(hh, G_clt_config, c, ct)
1010 {
1011 if (!c->is_cfg_refresh && CLT_STATE_NOTRUN==c->dyn.cur_state)
1012 {
1013 NDRX_LOG(log_error, "Removing process: [%s]", c->stat.command_line);
1014
1015
1016 if (NULL!=c->stat.envs)
1017 {
1018 ndrx_ndrxconf_envs_envs_free(&c->stat.envs);
1019 }
1020
1021 EXHASH_DEL(G_clt_config, c);
1022 NDRX_FREE(c);
1023 }
1024 }
1025
1026 out:
1027
1028 if (was_locked)
1029 {
1030 cpm_unlock_config();
1031 }
1032 return ret;
1033 }
1034
1035