Changeset e781d1eba05c6dd4520aec7f96642bc77a0f9de1
- Timestamp:
- 02/15/08 17:14:47 (10 years ago)
- git-parent:
- Files:
-
- src/noit_check.c (modified) (6 diffs)
- src/noit_conf.c (modified) (21 diffs)
- src/noit_conf.h (modified) (1 diff)
- src/sample.conf (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
src/noit_check.c
re01b3ad re781d1e 156 156 options = noit_conf_get_hash(sec[i], "ancestor-or-self::node()/config/*"); 157 157 158 INHERIT(boolean, disable, &disabled); 158 159 flags = 0; 159 160 if(busted) flags |= NP_UNCONFIG; … … 162 163 if(noit_hash_retrieve(&polls, (char *)uuid, UUID_SIZE, 163 164 (void **)&existing_check)) { 165 /* Once set, we can never change it. */ 166 assert(!existing_check->module || !existing_check->module[0] || 167 !strcmp(existing_check->module, module)); 168 /* Only set it if it is not yet set */ 169 if(!existing_check->module || !existing_check->module[0]) { 170 if(existing_check->module) free(existing_check->module); 171 existing_check->module = strdup(module); 172 } 164 173 noit_check_update(existing_check, target, name, options, 165 174 period, timeout, oncheck[0] ? oncheck : NULL, … … 203 212 204 213 void 214 noit_poller_flush_epoch(int oldest_allowed) { 215 noit_hash_iter iter = NOIT_HASH_ITER_ZERO; 216 uuid_t key_id; 217 int klen; 218 noit_check_t *check, *tofree = NULL; 219 220 /* Cleanup any previous causal map */ 221 while(noit_hash_next(&polls, &iter, (const char **)key_id, &klen, 222 (void **)&check)) { 223 /* We don't free the one we're looking at... we free it on the next 224 * pass. This leaves out iterator in good shape. We just need to 225 * remember to free it one last time outside the while loop, down... 226 */ 227 if(tofree) { 228 noit_poller_deschedule(tofree->checkid); 229 tofree = NULL; 230 } 231 if(check->generation < oldest_allowed) { 232 tofree = check; 233 } 234 } 235 /* ... here */ 236 if(tofree) noit_poller_deschedule(tofree->checkid); 237 } 238 239 void 205 240 noit_poller_make_causal_map() { 206 241 noit_hash_iter iter = NOIT_HASH_ITER_ZERO; … … 219 254 } 220 255 256 memset(&iter, 0, sizeof(iter)); 221 257 /* Walk all checks and add check dependencies to their parents */ 222 258 while(noit_hash_next(&polls, &iter, (const char **)key_id, &klen, … … 228 264 char *target = NULL; 229 265 266 noitL(noit_debug, "Searching for upstream trigger on %s\n", name); 230 267 if((target = strchr(check->oncheck, '`')) != NULL) { 231 268 strlcpy(fullcheck, check->oncheck, target - check->oncheck); … … 258 295 { 259 296 noit_poller_process_checks(xpath ? xpath : "/noit/checks//check"); 297 if(!xpath) { 298 /* Full reload, we need to wipe old checks */ 299 noit_poller_flush_epoch(__config_load_generation); 300 } 260 301 noit_poller_make_causal_map(); 261 302 noit_poller_initiate(); src/noit_conf.c
r129a0ba re781d1e 67 67 master_config = new_config; 68 68 xpath_ctxt = xmlXPathNewContext(master_config); 69 realpath(path, master_config_file);69 if(path != master_config_file) realpath(path, master_config_file); 70 70 return 0; 71 71 } … … 202 202 return 1; 203 203 } 204 int noit_conf_get_uuid(noit_conf_section_t section, 205 const char *path, uuid_t out) { 206 char *str; 207 if(_noit_conf_get_string(section,NULL,path,&str)) { 208 if(uuid_parse(str, out) == 0) return 1; 209 return 0; 210 } 211 return 0; 212 } 204 213 int noit_conf_get_string(noit_conf_section_t section, 205 214 const char *path, char **value) { … … 313 322 char argcopy[1024], *target, *name; 314 323 315 strlcpy(argcopy, arg, sizeof(argcopy)); 324 argcopy[0] = '\0'; 325 if(arg) strlcpy(argcopy, arg, sizeof(argcopy)); 326 316 327 if(uuid_parse(argcopy, checkid) == 0) { 317 328 /* If they kill by uuid, we'll seek and destroy -- find it anywhere */ … … 334 345 else { 335 346 char *path = (!info || !strcmp(info->path, "/")) ? "" : info->path; 336 snprintf(xpath, len, "/noit%s/%s[@uuid]", path, arg); 347 snprintf(xpath, len, "/noit%s%s%s[@uuid]", 348 path, arg ? "/" : "", arg ? arg : ""); 337 349 } 338 350 return 0; … … 358 370 nc_write(ncct, "\n", 1); 359 371 } 372 static void 373 refresh_subchecks(noit_console_closure_t ncct, 374 noit_conf_t_userdata_t *info) { 375 char *path; 376 char xpath[1024]; 377 378 path = info->path; 379 if(!strcmp(path, "/")) path = ""; 380 381 /* The first one is just a process_checks, the second is the reload. 382 * Reload does a lot of work and there is no need to do it twice. 383 */ 384 snprintf(xpath, sizeof(xpath), "/noit/%s[@uuid]", path); 385 noit_poller_process_checks(xpath); 386 snprintf(xpath, sizeof(xpath), "/noit/%s//check[@uuid]", path); 387 noit_poller_reload(xpath); 388 } 389 static int 390 noit_conf_mkcheck_under(const char *ppath, uuid_t out) { 391 int rv = -1; 392 const char *path; 393 char xpath[1024]; 394 xmlXPathObjectPtr pobj = NULL; 395 xmlNodePtr node = NULL, newnode; 396 397 path = strcmp(ppath, "/") ? ppath : ""; 398 snprintf(xpath, sizeof(xpath), "/noit%s", path); 399 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 400 if(!pobj || pobj->type != XPATH_NODESET || 401 xmlXPathNodeSetGetLength(pobj->nodesetval) != 1) { 402 goto out; 403 } 404 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 405 if((newnode = xmlNewChild(node, NULL, (xmlChar *)"check", NULL)) != NULL) { 406 char outstr[37]; 407 uuid_generate(out); 408 uuid_unparse_lower(out, outstr); 409 xmlSetProp(newnode, (xmlChar *)"uuid", (xmlChar *)outstr); 410 rv = 0; 411 } 412 out: 413 if(pobj) xmlXPathFreeObject(pobj); 414 return rv; 415 } 360 416 static int 361 417 noit_console_check(noit_console_closure_t ncct, 362 418 int argc, char **argv, 363 419 noit_console_state_t *state, void *closure) { 364 int i,cnt;420 int cnt; 365 421 noit_conf_t_userdata_t *info; 366 char xpath[1024]; 422 char xpath[1024], newuuid_str[37]; 423 char *uuid_conf, *wanted; 424 uuid_t checkid; 367 425 xmlXPathObjectPtr pobj = NULL; 426 xmlNodePtr node = NULL; 427 noit_conf_boolean creating_new = noit_false; 368 428 369 429 if(argc > 1) { … … 373 433 374 434 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 435 wanted = argc ? argv[0] : NULL; 436 if(!wanted) { 437 /* We are creating a new node */ 438 uuid_t out; 439 creating_new = noit_true; 440 if(noit_conf_mkcheck_under(info->path, out)) { 441 nc_printf(ncct, "Error creating new check\n"); 442 return -1; 443 } 444 newuuid_str[0] = '\0'; 445 uuid_unparse_lower(out, newuuid_str); 446 wanted = newuuid_str; 447 } 375 448 /* We many not be in conf-t mode -- that's fine */ 376 if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, 377 argc ? argv[0] : ".")) { 378 nc_printf(ncct, "could not find check '%s'\n", argv[0]); 449 if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, wanted)) { 450 nc_printf(ncct, "could not find check '%s'\n", wanted); 379 451 return -1; 380 452 } … … 391 463 goto out; 392 464 } 465 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); 466 uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); 467 if(!uuid_conf || uuid_parse(uuid_conf, checkid)) { 468 nc_printf(ncct, "%s has invalid or missing UUID!\n", 469 (char *)xmlGetNodePath(node) + strlen("/noit")); 470 goto out; 471 } 472 if(info) { 473 if(info->path) free(info->path); 474 info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit")); 475 uuid_copy(info->current_check, checkid); 476 if(creating_new) refresh_subchecks(ncct, info); 477 noit_console_state_push_state(ncct, state); 478 noit_console_state_init(ncct); 479 goto out; 480 } 481 out: 482 if(pobj) xmlXPathFreeObject(pobj); 483 return 0; 484 } 485 static int 486 noit_console_show_check(noit_console_closure_t ncct, 487 int argc, char **argv, 488 noit_console_state_t *state, void *closure) { 489 int i, cnt; 490 noit_conf_t_userdata_t *info; 491 char xpath[1024]; 492 xmlXPathObjectPtr pobj = NULL; 493 494 if(argc > 1) { 495 nc_printf(ncct, "requires zero or one arguments\n"); 496 return -1; 497 } 498 499 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 500 /* We many not be in conf-t mode -- that's fine */ 501 if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, 502 argc ? argv[0] : NULL)) { 503 nc_printf(ncct, "could not find check '%s'\n", argv[0]); 504 return -1; 505 } 506 507 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 508 if(!pobj || pobj->type != XPATH_NODESET || 509 xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 510 nc_printf(ncct, "no checks found\n"); 511 goto out; 512 } 513 cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); 514 if(info && cnt != 1) { 515 nc_printf(ncct, "Ambiguous check specified\n"); 516 goto out; 517 } 393 518 for(i=0; i<cnt; i++) { 394 519 uuid_t checkid; 520 noit_check_t *check; 395 521 xmlNodePtr node, anode, mnode = NULL; 396 522 char *uuid_conf; … … 398 524 399 525 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); 400 if(info) {401 if(info->path) free(info->path);402 info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit"));403 }404 526 uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); 405 527 if(!uuid_conf || uuid_parse(uuid_conf, checkid)) { … … 430 552 SHOW_ATTR(timeout); 431 553 SHOW_ATTR(oncheck); 554 SHOW_ATTR(disable); 555 check = noit_poller_lookup(checkid); 556 if(!check) { 557 nc_printf(ncct, " ERROR: not in running system\n"); 558 } 559 else { 560 int idx = 0; 561 nc_printf(ncct, " currently: "); 562 if(NOIT_CHECK_RUNNING(check)) nc_printf(ncct, "%srunning", idx++?",":""); 563 if(NOIT_CHECK_KILLED(check)) nc_printf(ncct, "%skilled", idx++?",":""); 564 if(!NOIT_CHECK_CONFIGURED(check)) nc_printf(ncct, "%sunconfig", idx++?",":""); 565 if(NOIT_CHECK_DISABLED(check)) nc_printf(ncct, "%sdisabled", idx++?",":""); 566 nc_write(ncct, "\n", 1); 567 if(check->stats.current.status) 568 nc_printf(ncct, " recently: %s\n", check->stats.current.status); 569 } 432 570 } 433 571 out: … … 582 720 xmlXPathContextPtr current_ctxt; 583 721 xmlNodePtr node = NULL; 584 585 if(argc != 1) { 722 char *dest; 723 724 if(argc != 1 && !closure) { 586 725 nc_printf(ncct, "requires one argument\n"); 587 726 return -1; 588 727 } 728 dest = argc ? argv[0] : (char *)closure; 589 729 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 590 if( argv[0][0] == '/')591 snprintf(xpath, sizeof(xpath), "/noit%s", argv[0]);730 if(dest[0] == '/') 731 snprintf(xpath, sizeof(xpath), "/noit%s", dest); 592 732 else { 593 snprintf(xpath, sizeof(xpath), "/noit%s/%s", info->path, argv[0]);733 snprintf(xpath, sizeof(xpath), "/noit%s/%s", info->path, dest); 594 734 } 595 735 if(xpath[strlen(xpath)-1] == '/') xpath[strlen(xpath)-1] = '\0'; … … 623 763 info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit")); 624 764 if(pobj) xmlXPathFreeObject(pobj); 765 if(closure) noit_console_state_pop(ncct, argc, argv, NULL, NULL); 625 766 return 0; 626 767 bad: … … 703 844 /* _shorten string_ turning last { / @ * } to { / * } */ 704 845 strlcpy(xpath + strlen(xpath) - 2, "*", 2); 705 nc_printf(ncct, "Looking up path '%s'\n", xpath);706 846 pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); 707 847 if(!pobj || pobj->type != XPATH_NODESET) { … … 761 901 762 902 static char * 903 conf_t_check_prompt(EditLine *el) { 904 noit_console_closure_t ncct; 905 noit_conf_t_userdata_t *info; 906 noit_check_t *check; 907 static char *tl = "noit(conf)# "; 908 static char *pfmt = "noit(conf:%s%s%s)# "; 909 910 el_get(el, EL_USERDATA, (void *)&ncct); 911 if(!ncct) return tl; 912 info = noit_console_userdata_get(ncct, NOIT_CONF_T_USERDATA); 913 if(!info) return tl; 914 915 check = noit_poller_lookup(info->current_check); 916 if(check && 917 check->target && check->target[0] && 918 check->name && check->name[0]) 919 snprintf(info->prompt, sizeof(info->prompt), 920 pfmt, check->target, "`", check->name); 921 else { 922 char uuid_str[37]; 923 uuid_unparse_lower(info->current_check, uuid_str); 924 snprintf(info->prompt, sizeof(info->prompt), pfmt, "[", uuid_str, "]"); 925 } 926 return info->prompt; 927 } 928 static char * 763 929 conf_t_prompt(EditLine *el) { 764 930 noit_console_closure_t ncct; … … 865 1031 { "/checks", "timeout", "@timeout", 0 }, 866 1032 { "/checks", "oncheck", "@oncheck", 0 }, 1033 { "/checks", "disable", "@disable", 0 }, 867 1034 { "/checks", "module", "@module", 1 }, 868 1035 }; … … 896 1063 noit_conf_t_userdata_t *info, struct _valid_attr_t *attrinfo, 897 1064 const char *value) { 898 int cnt, rv = -1;1065 int i, cnt, rv = -1, active = 0; 899 1066 xmlXPathObjectPtr pobj = NULL; 900 1067 xmlNodePtr node; … … 912 1079 snprintf(xpath, sizeof(xpath), "/noit/%s//check[@uuid]", path); 913 1080 pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); 914 if(pobj && pobj->type == XPATH_NODESET && 915 !xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { 916 nc_printf(ncct, "Cannot set '%s', it would effect live checks\n", 917 attrinfo->name); 918 goto out; 1081 if(!pobj || pobj->type != XPATH_NODESET) goto out; 1082 cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); 1083 for(i=0; i<cnt; i++) { 1084 uuid_t checkid; 1085 node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); 1086 if(noit_conf_get_uuid(node, "@uuid", checkid)) { 1087 noit_check_t *check; 1088 check = noit_poller_lookup(checkid); 1089 if(NOIT_CHECK_LIVE(check)) active++; 1090 } 919 1091 } 920 1092 if(pobj) xmlXPathFreeObject(pobj); … … 931 1103 if(attrinfo->checks_fixate && 932 1104 !strcmp((const char *)node->name, "check")) { 1105 uuid_t checkid; 933 1106 /* Detect if we are actually a <check> node and attempting to 934 1107 * change something we shouldn't. 935 1108 * This is the counterpart noted above. 936 1109 */ 937 nc_printf(ncct, "Cannot set '%s', it would effect live checks\n"); 1110 if(noit_conf_get_uuid(node, "@uuid", checkid)) { 1111 noit_check_t *check; 1112 check = noit_poller_lookup(checkid); 1113 if(NOIT_CHECK_LIVE(check)) active++; 1114 } 1115 } 1116 if(active) { 1117 nc_printf(ncct, "Cannot set '%s', it would effect %d live check(s)\n", 1118 attrinfo->name, active); 938 1119 goto out; 939 1120 } … … 945 1126 if(pobj) xmlXPathFreeObject(pobj); 946 1127 return rv; 947 }948 static void949 refresh_subchecks(noit_console_closure_t ncct,950 noit_conf_t_userdata_t *info) {951 char *path;952 char xpath[1024];953 954 path = info->path;955 if(!strcmp(path, "/")) path = "";956 957 /* The first one is just a process_checks, the second is the reload.958 * Reload does a lot of work and there is no need to do it twice.959 */960 snprintf(xpath, sizeof(xpath), "/noit/%s[@uuid]", path);961 noit_poller_process_checks(xpath);962 snprintf(xpath, sizeof(xpath), "/noit/%s//check[@uuid]", path);963 noit_poller_reload(xpath);964 1128 } 965 1129 int … … 1039 1203 cmd_info_t *showcmd; 1040 1204 noit_console_state_t *tl, *_conf_state, *_conf_t_state, 1205 *_conf_t_check_state, 1041 1206 *_write_state, *_attr_state, 1042 1207 *_unset_state, *_uattr_state; … … 1063 1228 ADD_CMD(_unset_state, "check", noit_console_config_nocheck, NULL, NULL); 1064 1229 1230 NEW_STATE(_conf_t_check_state); 1231 _conf_t_check_state->console_prompt_function = conf_t_check_prompt; 1232 DELEGATE_CMD(_conf_t_check_state, "attribute", _attr_state); 1233 DELEGATE_CMD(_conf_t_check_state, "no", _unset_state); 1234 ADD_CMD(_conf_t_check_state, "status", noit_console_show_check, NULL, NULL); 1235 ADD_CMD(_conf_t_check_state, "exit", noit_console_config_cd, NULL, ".."); 1236 1065 1237 NEW_STATE(_conf_t_state); 1066 1238 _conf_t_state->console_prompt_function = conf_t_prompt; … … 1068 1240 ADD_CMD(_conf_t_state, "ls", noit_console_config_show, NULL, NULL); 1069 1241 ADD_CMD(_conf_t_state, "cd", noit_console_config_cd, NULL, NULL); 1070 ADD_CMD(_conf_t_state, "check", noit_console_check, NULL, NULL);1071 1242 ADD_CMD(_conf_t_state, "section", noit_console_config_section, NULL, (void *)0); 1243 ADD_CMD(_conf_t_state, "check", noit_console_check, _conf_t_check_state, NULL); 1072 1244 1073 1245 showcmd = noit_console_state_get_cmd(tl, "show"); 1074 ADD_CMD(showcmd->dstate, "check", noit_console_ check, NULL, NULL);1246 ADD_CMD(showcmd->dstate, "check", noit_console_show_check, NULL, NULL); 1075 1247 1076 1248 DELEGATE_CMD(_conf_t_state, "write", _write_state); src/noit_conf.h
r7a1324a re781d1e 17 17 typedef struct { 18 18 char *path; 19 char prompt[40]; 19 uuid_t current_check; 20 char prompt[50]; 20 21 } noit_conf_t_userdata_t; 21 22 src/sample.conf
re01b3ad re781d1e 39 39 </listeners> 40 40 <checks> 41 <check uuid="1b4e28ba-2fa1-11d2-883f-b9b761bde3fb" />41 <check uuid="1b4e28ba-2fa1-11d2-883f-b9b761bde3fb" module="ping_icmp" target="10.80.116.4" period="15000" timeout="14000"/> 42 42 <dc1 timeout="30000" period="60000"> 43 43 <icmp module="ping_icmp" timeout="12000">