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 <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <libgen.h>
0039 #include <memory.h>
0040 #include <libxml/xmlreader.h>
0041 #include <errno.h>
0042
0043 #include <ndrstandard.h>
0044 #include <ndebug.h>
0045 #include <utlist.h>
0046 #include <nstdutil.h>
0047 #include <exenv.h>
0048 #include <libndrxconf.h>
0049 #include <lcfint.h>
0050 #include <ndrxdcmn.h>
0051 #include <ndrx_intdef.h>
0052 #include <exhash.h>
0053 #include <singlegrp.h>
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 exprivate int compare_descending(const void *a, const void *b)
0066 {
0067 char *aa = (char *)a;
0068 char *bb = (char *)b;
0069
0070 if (*aa > *bb)
0071 {
0072 return -1;
0073 }
0074 else if (*aa < *bb)
0075 {
0076 return 1;
0077 }
0078 else
0079 {
0080 return 0;
0081 }
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 expublic int ndrx_appconfig_procgroup(ndrx_procgroups_t **config,
0096 xmlDocPtr doc, xmlNodePtr cur, int is_defaults, ndrx_procgroup_t *p_defaults,
0097 char *config_file_short, ndrx_ndrxconf_err_t *err)
0098 {
0099 int ret=EXSUCCEED;
0100 xmlAttrPtr attr;
0101 ndrx_procgroup_t *p_grp=NULL;
0102 ndrx_procgroup_t local;
0103 char *p;
0104 char tmp[PATH_MAX+1];
0105
0106
0107 if (is_defaults)
0108 {
0109 p_grp=p_defaults;
0110 }
0111 else
0112 {
0113 p_grp = &local;
0114 memcpy(p_grp, p_defaults, sizeof(ndrx_procgroup_t));
0115 }
0116
0117 for (attr=cur->properties; attr; attr = attr->next)
0118 {
0119 p = (char *)xmlNodeGetContent(attr->children);
0120
0121 if (0==strcmp((char *)attr->name, "name"))
0122 {
0123 int len = strlen(p);
0124
0125 if (len>MAXTIDENT || len < 1)
0126 {
0127 snprintf(err->error_msg, sizeof(err->error_msg),
0128 "(%s) invalid length %d for `name' attribute at <procgroup> near line %d",
0129 config_file_short, len, cur->line);
0130 err->error_code = NDRXD_EINVAL;
0131 NDRX_LOG(log_error, "%s", err->error_msg);
0132 xmlFree(p);
0133 EXFAIL_OUT(ret);
0134 }
0135
0136 if (!ndrx_str_valid_alphanumeric_(p, MAXTIDENT))
0137 {
0138 snprintf(err->error_msg, sizeof(err->error_msg),
0139 "(%s) invalid characters used in `name' attribute at <procgroup> near line %d",
0140 config_file_short, cur->line);
0141 err->error_code = NDRXD_EINVAL;
0142 NDRX_LOG(log_error, "%s", err->error_msg);
0143 xmlFree(p);
0144 EXFAIL_OUT(ret);
0145 }
0146 NDRX_STRCPY_SAFE(p_grp->grpname, p);
0147 }
0148 else if (0==strcmp((char *)attr->name, "grpno"))
0149 {
0150 p_grp->grpno = atoi(p);
0151
0152 if (!ndrx_sg_is_valid(p_grp->grpno))
0153 {
0154 if (ndrx_G_libnstd_cfg.pgmax > 0)
0155 {
0156 snprintf(err->error_msg, sizeof(err->error_msg),
0157 "(%s) Invalid `grpno' %d (valid values 1..%d) in <procgroup> "
0158 "section near line %d",
0159 config_file_short, p_grp->grpno, ndrx_G_libnstd_cfg.pgmax, cur->line);
0160 }
0161 else
0162 {
0163 snprintf(err->error_msg, sizeof(err->error_msg),
0164 "(%s) Process groups are disabled (NDRX_PGMAX=0) near line %d",
0165 config_file_short, cur->line);
0166 }
0167 err->error_code = NDRXD_EINVAL;
0168 NDRX_LOG(log_error, "%s", err->error_msg);
0169 xmlFree(p);
0170 EXFAIL_OUT(ret);
0171 }
0172 }
0173 else if (0==strcmp((char *)attr->name, "sg_nodes"))
0174 {
0175 ndrx_stdcfgstr_t *parsed=NULL, *el;
0176
0177 NDRX_QENV_SUBST(tmp, p);
0178
0179
0180 if (EXSUCCEED!=ndrx_stdcfgstr_parse(tmp, &parsed))
0181 {
0182 snprintf(err->error_msg, sizeof(err->error_msg),
0183 "(%s) Failed to parse `sg_nodes' %s in <procgroup> section near line %d",
0184 config_file_short, p, cur->line);
0185 err->error_code = NDRXD_EINVAL;
0186 NDRX_LOG(log_error, "%s", err->error_msg);
0187 ndrx_stdcfgstr_free(parsed);
0188 xmlFree(p);
0189 EXFAIL_OUT(ret);
0190 }
0191
0192 DL_FOREACH(parsed, el)
0193 {
0194 int nodeid = atoi(el->key);
0195
0196
0197 if (nodeid<CONF_NDRX_NODEID_MIN || nodeid>CONF_NDRX_NODEID_MAX)
0198 {
0199 snprintf(err->error_msg, sizeof(err->error_msg),
0200 "(%s) Invalid `sg_nodes' %d (valid values 1..%d) in <procgroup> "
0201 "section near line %d",
0202 config_file_short, nodeid, CONF_NDRX_NODEID_MAX, cur->line);
0203 err->error_code = NDRXD_EINVAL;
0204 NDRX_LOG(log_error, "%s", err->error_msg);
0205 xmlFree(p);
0206 ndrx_stdcfgstr_free(parsed);
0207 EXFAIL_OUT(ret);
0208 }
0209
0210
0211 p_grp->sg_nodes[nodeid-1]=nodeid;
0212 }
0213 ndrx_stdcfgstr_free(parsed);
0214
0215
0216
0217
0218 qsort(p_grp->sg_nodes, CONF_NDRX_NODEID_COUNT, sizeof(char), compare_descending);
0219 }
0220 else if (0==strcmp((char *)attr->name, "noorder"))
0221 {
0222
0223 if (NDRX_SETTING_TRUE1==*p || NDRX_SETTING_TRUE2==*p)
0224 {
0225 p_grp->flags|=NDRX_SG_NO_ORDER;
0226 }
0227 else if (NDRX_SETTING_FALSE1==*p || NDRX_SETTING_FALSE2==*p)
0228 {
0229 p_grp->flags&=~NDRX_SG_NO_ORDER;
0230 }
0231 else
0232 {
0233 snprintf(err->error_msg, sizeof(err->error_msg),
0234 "(%s) Invalid `noorder' setting [%s] in "
0235 "<procgroup> or <defaults> "
0236 "section, expected values [%c%c%c%c] near line %d",
0237 config_file_short, p,
0238 NDRX_SETTING_TRUE1, NDRX_SETTING_TRUE2,
0239 NDRX_SETTING_FALSE1, NDRX_SETTING_FALSE2, cur->line);
0240 err->error_code = NDRXD_EINVAL;
0241 NDRX_LOG(log_error, "%s", err->error_msg);
0242 xmlFree(p);
0243 EXFAIL_OUT(ret);
0244 }
0245 }
0246 else if (0==strcmp((char *)attr->name, "singleton"))
0247 {
0248
0249 if (NDRX_SETTING_TRUE1==*p || NDRX_SETTING_TRUE2==*p)
0250 {
0251 p_grp->flags|=NDRX_SG_SINGLETON;
0252 }
0253 else if (NDRX_SETTING_FALSE1==*p || NDRX_SETTING_FALSE2==*p)
0254 {
0255 p_grp->flags&=~NDRX_SG_SINGLETON;
0256 }
0257 else
0258 {
0259 snprintf(err->error_msg, sizeof(err->error_msg),
0260 "(%s) Invalid `singleton' setting [%s] in "
0261 "<procgroup> or <defaults> "
0262 "section, expected values [%c%c%c%c] near line %d",
0263 config_file_short, p,
0264 NDRX_SETTING_TRUE1, NDRX_SETTING_TRUE2,
0265 NDRX_SETTING_FALSE1, NDRX_SETTING_FALSE2, cur->line);
0266 err->error_code = NDRXD_EINVAL;
0267 NDRX_LOG(log_error, "%s", err->error_msg);
0268 xmlFree(p);
0269 EXFAIL_OUT(ret);
0270 }
0271 }
0272 else if (0==strcmp((char *)attr->name, "sg_nodes_verify"))
0273 {
0274
0275 if (NDRX_SETTING_TRUE1==*p || NDRX_SETTING_TRUE2==*p)
0276 {
0277 p_grp->flags|=NDRX_SG_VERIFY;
0278 }
0279 else if (NDRX_SETTING_FALSE1==*p || NDRX_SETTING_FALSE2==*p)
0280 {
0281 p_grp->flags&=~NDRX_SG_VERIFY;
0282 }
0283 else
0284 {
0285 snprintf(err->error_msg, sizeof(err->error_msg),
0286 "(%s) Invalid `sg_node_verify' setting [%s] in "
0287 "<procgroup> or <defaults> "
0288 "section, expected values [%c%c%c%c] near line %d",
0289 config_file_short, p,
0290 NDRX_SETTING_TRUE1, NDRX_SETTING_TRUE2,
0291 NDRX_SETTING_FALSE1, NDRX_SETTING_FALSE2, cur->line);
0292 err->error_code = NDRXD_EINVAL;
0293 NDRX_LOG(log_error, "%s", err->error_msg);
0294 xmlFree(p);
0295 EXFAIL_OUT(ret);
0296 }
0297 }
0298
0299 xmlFree(p);
0300 }
0301
0302
0303 if (!is_defaults)
0304 {
0305
0306 if (EXEOS==p_grp->grpname[0])
0307 {
0308 snprintf(err->error_msg, sizeof(err->error_msg),
0309 "(%s) `name' not set in <procgroup> section near line %d",
0310 config_file_short, cur->line);
0311 err->error_code = NDRXD_ECFGINVLD;
0312 NDRX_LOG(log_error, "%s", err->error_msg);
0313 EXFAIL_OUT(ret);
0314 }
0315
0316
0317 if (0==p_grp->grpno)
0318 {
0319 snprintf(err->error_msg, sizeof(err->error_msg),
0320 "(%s) `grpno' not set in <procgroup> section near line %d",
0321 config_file_short, cur->line);
0322 err->error_code = NDRXD_ECFGINVLD;
0323 NDRX_LOG(log_error, "%s", err->error_msg);
0324 EXFAIL_OUT(ret);
0325 }
0326
0327
0328 if (NULL!=ndrx_ndrxconf_procgroups_resolvenm(*config, p_grp->grpname))
0329 {
0330 snprintf(err->error_msg, sizeof(err->error_msg),
0331 "(%s) `name' %s is duplicate in <procgroup> section near line %d",
0332 config_file_short, p_grp->grpname, cur->line);
0333 err->error_code = NDRXD_EINVAL;
0334 NDRX_LOG(log_error, "%s", err->error_msg);
0335 EXFAIL_OUT(ret);
0336 }
0337
0338
0339 if (NULL!=ndrx_ndrxconf_procgroups_resolveno(*config, p_grp->grpno))
0340 {
0341 snprintf(err->error_msg, sizeof(err->error_msg),
0342 "(%s) `grpno' %d is duplicate in <procgroup> section near line %d",
0343 config_file_short, p_grp->grpno, cur->line);
0344 err->error_code = NDRXD_EINVAL;
0345 NDRX_LOG(log_error, "%s", err->error_msg);
0346 EXFAIL_OUT(ret);
0347 }
0348
0349 p_grp->flags|=NDRX_SG_IN_USE;
0350
0351
0352 memcpy(&(*config)->groups_by_no[p_grp->grpno-1], p_grp, sizeof(ndrx_procgroup_t));
0353
0354 p_grp=&(*config)->groups_by_no[p_grp->grpno-1];
0355
0356
0357 EXHASH_ADD_STR((*config)->groups_by_name, grpname, p_grp);
0358 }
0359 out:
0360
0361 return ret;
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374 expublic int ndrx_ndrxconf_procgroups_parse(ndrx_procgroups_t **config,
0375 xmlDocPtr doc, xmlNodePtr cur,
0376 char *config_file_short, ndrx_ndrxconf_err_t *err)
0377 {
0378 int ret=EXSUCCEED;
0379 ndrx_procgroup_t default_opt;
0380
0381 int is_procgroup;
0382 int is_defaults;
0383 int our_nodeid = ndrx_get_G_atmi_env()->our_nodeid;
0384
0385 memset(&default_opt, 0, sizeof(default_opt));
0386
0387
0388 default_opt.flags|=NDRX_SG_VERIFY;
0389
0390
0391
0392
0393 default_opt.sg_nodes[our_nodeid-1]=our_nodeid;
0394
0395 *config = NDRX_CALLOC(1, sizeof(ndrx_procgroups_t) +
0396 sizeof(ndrx_procgroup_t) * (ndrx_G_libnstd_cfg.pgmax));
0397
0398 for (; cur ; cur=cur->next)
0399 {
0400 is_procgroup= (0==strcmp((char*)cur->name, "procgroup"));
0401 is_defaults= (0==strcmp((char*)cur->name, "defaults"));
0402
0403 if (is_procgroup || is_defaults)
0404 {
0405
0406 if (EXSUCCEED!=ndrx_appconfig_procgroup(config, doc, cur,
0407 is_defaults, &default_opt, config_file_short, err))
0408 {
0409 EXFAIL_OUT(ret);
0410 }
0411 }
0412 }
0413 out:
0414
0415 return ret;
0416 }
0417
0418
0419
0420
0421
0422 expublic void ndrx_ndrxconf_procgroups_free(ndrx_procgroups_t *handle)
0423 {
0424 ndrx_procgroup_t *p_grp, *tmp;
0425
0426 if (NULL!=handle)
0427 {
0428
0429 EXHASH_ITER(hh, handle->groups_by_name, p_grp, tmp)
0430 {
0431 EXHASH_DEL(handle->groups_by_name, p_grp);
0432 }
0433
0434 NDRX_FREE(handle);
0435 }
0436 }
0437
0438
0439
0440
0441 expublic ndrx_procgroup_t* ndrx_ndrxconf_procgroups_resolvenm(ndrx_procgroups_t *handle, char *name)
0442 {
0443 ndrx_procgroup_t *ret;
0444
0445 if (NULL==name || EXEOS==name[0] || NULL==handle)
0446 {
0447 return NULL;
0448 }
0449
0450 EXHASH_FIND_STR(handle->groups_by_name, name, ret);
0451
0452 return ret;
0453 }
0454
0455
0456
0457
0458
0459
0460
0461 expublic int ndrx_ndrxconf_procgroups_is_singleton(ndrx_procgroups_t *handle, int procgrp_no)
0462 {
0463 ndrx_procgroup_t *p_grp;
0464 int ret = EXFALSE;
0465
0466 if (NULL==handle)
0467 {
0468 goto out;
0469 }
0470
0471 p_grp = &handle->groups_by_no[procgrp_no-1];
0472
0473 if (p_grp->flags & NDRX_SG_SINGLETON)
0474 {
0475 ret=EXTRUE;
0476 }
0477 else
0478 {
0479 ret=EXFALSE;
0480 }
0481
0482 out:
0483 return ret;
0484 }
0485
0486
0487
0488
0489 expublic ndrx_procgroup_t* ndrx_ndrxconf_procgroups_resolveno(ndrx_procgroups_t *handle, int procgrpno)
0490 {
0491 ndrx_procgroup_t *ret=NULL;
0492
0493 if (procgrpno<1 || procgrpno>ndrx_G_libnstd_cfg.pgmax|| NULL==handle)
0494 {
0495 goto out;
0496 }
0497
0498 ret=&handle->groups_by_no[procgrpno-1];
0499
0500 if (!(ret->flags & NDRX_SG_IN_USE))
0501 {
0502 ret=NULL;
0503 }
0504
0505 out:
0506 return ret;
0507 }
0508
0509
0510
0511
0512
0513 expublic void ndrx_ndrxconf_procgroups_apply_singlegrp(ndrx_procgroups_t *handle)
0514 {
0515 int i;
0516 unsigned short flags;
0517
0518
0519 if (NULL==handle)
0520 {
0521 return;
0522 }
0523
0524 for (i=0; i<ndrx_G_libnstd_cfg.pgmax; i++)
0525 {
0526 ndrx_procgroup_t *p_grp = &handle->groups_by_no[i];
0527 ndrx_sg_flags_set(i+1, p_grp->flags);
0528
0529
0530 ndrx_sg_nodes_set(i+1, p_grp->sg_nodes);
0531 }
0532 }
0533
0534