int stats_config_line( AVP *av ) { char *d, *pm, *lbl, *fmt, thrbuf[64]; int i, t, l, mid, top; ST_THOLD *th; STAT_CTL *s; ST_CFG *sc; WORDS wd; s = ctl->stats; if( !( d = strchr( av->att, '.' ) ) ) { if( attIs( "thresholds" ) ) { if( strwords( &wd, av->val, av->vlen, ',' ) <= 0 ) { warn( "Invalid thresholds string: %s", av->val ); return -1; } if( wd.wc > 20 ) { warn( "A maximum of 20 thresholds is allowed." ); return -1; } for( i = 0; i < wd.wc; i++ ) { t = atoi( wd.wd[i] ); // sort out percent from per-mille if( ( pm = memchr( wd.wd[i], 'm', wd.len[i] ) ) ) { mid = 500; top = 1000; lbl = "per-mille"; fmt = "%s_%03d"; } else { mid = 50; top = 100; lbl = "percent"; fmt = "%s_%02d"; } // sanity check before we go any further if( t <= 0 || t == mid || t >= top ) { warn( "A %s threshold value of %s makes no sense: t != %d, 0 < t < %d.", lbl, wd.wd[i], mid, top ); return -1; } l = snprintf( thrbuf, 64, fmt, ( ( t < mid ) ? "lower" : "upper" ), t ); // OK, make a struct th = (ST_THOLD *) allocz( sizeof( ST_THOLD ) ); th->val = t; th->max = top; th->label = str_dup( thrbuf, l ); th->next = ctl->stats->thresholds; ctl->stats->thresholds = th; } debug( "Acquired %d thresholds.", wd.wc ); } else return -1; return 0; } d++; if( !strncasecmp( av->att, "stats.", 6 ) ) sc = s->stats; else if( !strncasecmp( av->att, "adder.", 6 ) ) sc = s->adder; // because I'm nice that way (plus, I keep mis-typing it...) else if( !strncasecmp( av->att, "gauge.", 6 ) || !strncasecmp( av->att, "guage.", 6 ) ) sc = s->gauge; else if( !strncasecmp( av->att, "self.", 5 ) ) sc = s->self; else return -1; if( !strcasecmp( d, "threads" ) ) { t = atoi( av->val ); if( t > 0 ) sc->threads = t; else warn( "Stats threads must be > 0, value %d given.", t ); } else if( !strcasecmp( d, "enable" ) ) { if( valIs( "y" ) || valIs( "yes" ) || atoi( av->val ) ) sc->enable = 1; else { debug( "Stats type %s disabled.", sc->name ); sc->enable = 0; } } else if( !strcasecmp( d, "prefix" ) ) { free( sc->prefix ); sc->prefix = stats_prefix( av->val ); debug( "%s prefix set to '%s'", sc->name, sc->prefix ); } else if( !strcasecmp( d, "period" ) ) { t = atoi( av->val ); if( t > 0 ) sc->period = t; else warn( "Stats period must be > 0, value %d given.", t ); } else if( !strcasecmp( d, "offset" ) || !strcasecmp( d, "delay" ) ) { t = atoi( av->val ); if( t > 0 ) sc->offset = t; else warn( "Stats offset must be > 0, value %d given.", t ); } else if( !strcasecmp( d, "size" ) || !strcasecmp( d, "hashsize" ) ) { if( valIs( "tiny" ) ) sc->hsize = MEM_HSZ_TINY; else if( valIs( "small" ) ) sc->hsize = MEM_HSZ_SMALL; else if( valIs( "medium" ) ) sc->hsize = MEM_HSZ_MEDIUM; else if( valIs( "large" ) ) sc->hsize = MEM_HSZ_LARGE; else if( valIs( "xlarge" ) ) sc->hsize = MEM_HSZ_XLARGE; else if( valIs( "x2large" ) ) sc->hsize = MEM_HSZ_X2LARGE; else { if( !isdigit( av->val[0] ) ) { warn( "Unrecognised hash table size '%s'", av->val ); return -1; } t = atoi( av->val ); if( t == 0 ) { warn( "Cannot set zero size hash table." ); return -1; } // < 0 means default sc->hsize = t; } } else return -1; return 0; }
int mem_config_line( AVP *av ) { MTYPE *mt; char *d; int t; if( !( d = strchr( av->att, '.' ) ) ) { // just the singles if( attIs( "maxMb" ) || attIs( "maxSize" ) ) ctl->mem->max_kb = 1024 * atoi( av->val ); else if( attIs( "maxKb") ) ctl->mem->max_kb = atoi( av->val ); else if( attIs( "interval" ) || attIs( "msec" ) ) ctl->mem->interval = atoi( av->val ); else if( attIs( "hashSize" ) ) ctl->mem->hashsize = atoi( av->val ); else if( attIs( "stackSize" ) ) { // gets converted to KB ctl->mem->stacksize = atoi( av->val ); debug( "Stack size set to %d KB.", ctl->mem->stacksize ); } else if( attIs( "gc" ) ) ctl->mem->gc_enabled = config_bool( av ); else if( attIs( "gcThresh" ) ) { t = atoi( av->val ); if( !t ) t = DEFAULT_GC_THRESH; debug( "Garbage collection threshold set to %d stats intervals.", t ); ctl->mem->gc_thresh = t; } else if( attIs( "gcGaugeThresh" ) ) { t = atoi( av->val ); if( !t ) t = DEFAULT_GC_GG_THRESH; debug( "Gauge garbage collection threshold set to %d stats intervals.", t ); ctl->mem->gc_gg_thresh = t; } else return -1; return 0; } *d++ = '\0'; // after this, it's per-type control if( !strncasecmp( av->att, "hosts.", 6 ) ) mt = ctl->mem->hosts; else if( !strncasecmp( av->att, "iobufs.", 7 ) ) mt = ctl->mem->iobufs; else if( !strncasecmp( av->att, "points.", 7 ) ) mt = ctl->mem->points; else if( !strncasecmp( av->att, "dhash.", 6 ) ) mt = ctl->mem->dhash; else if( !strncasecmp( av->att, "iolist.", 7 ) ) mt = ctl->mem->iolist; else if( !strncasecmp( av->att, "token.", 6 ) ) mt = ctl->mem->token; else return -1; if( !strcasecmp( d, "block" ) ) { mt->alloc_ct = (uint32_t) strtoul( av->val, NULL, 10 ); debug( "Allocation block for %s set to %u", av->att, mt->alloc_ct ); } else return -1; // done this way because GC might become a thing return 0; }