analysis: shared networks to be linked list

This way memory is allocated only for items that are in use, and walking
through shared network items is also more straightforward.

As an unfortunate side effect in --perfdata output shared networks are no
longer printed in reverse order.  This should be a cosmetic issue.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2017-11-12 16:50:19 +00:00
parent a237c11d5a
commit ef5421ed05
No known key found for this signature in database
GPG key ID: A9553245FDE9B739
8 changed files with 84 additions and 100 deletions

View file

@ -93,11 +93,11 @@ void do_counting(struct conf_t *state)
range_p->shared_net->touched += range_p->touched;
range_p->shared_net->backups += range_p->backups;
/* When shared network is not 'all networks' add it as well. */
if (range_p->shared_net != state->shared_networks) {
state->shared_networks->available += block_size;
state->shared_networks->used += range_p->count;
state->shared_networks->touched += range_p->touched;
state->shared_networks->backups += range_p->backups;
if (range_p->shared_net != state->shared_net_root) {
state->shared_net_root->available += block_size;
state->shared_net_root->used += range_p->count;
state->shared_net_root->touched += range_p->touched;
state->shared_net_root->backups += range_p->backups;
}
/* Next range. */
range_p++;

View file

@ -78,12 +78,11 @@ static int return_limit(const char c)
* initializations, etc are here. */
static void prepare_memory(struct conf_t *state)
{
/* The SHARED_NETWORKS is a static value from defaults.h */
state->shared_networks = xcalloc(sizeof(struct shared_network_t), SHARED_NETWORKS);
state->ranges = xmalloc(sizeof(struct range_t) * state->ranges_size);
/* First shared network entry is all networks */
state->shared_networks->name = xstrdup("All networks");
state->shared_net_root = xcalloc(sizeof(struct shared_network_t), 1);
state->shared_net_root->name = xstrdup("All networks");
state->shared_net_head = state->shared_net_root;
}
/*! \brief Start of execution. Parse options, and call other other
@ -306,7 +305,7 @@ int main(int argc, char **argv)
}
/* Do the job */
parse_config(&state, 1, state.dhcpdconf_file, state.shared_networks);
parse_config(&state, 1, state.dhcpdconf_file, state.shared_net_root);
if (output_format == 'X' || output_format == 'J')
parse_leases(&state, 1);
else

View file

@ -77,12 +77,10 @@ union ipaddr_t {
/*! \enum dhcpd_magic_numbers
* \brief MAXLEN is maximum expected line length in dhcpd.conf and
* dhcpd.leases, and SHARED_NETWORKS is maximum number of different shared
* networks in dhcpd.conf file.
* dhcpd.leases.
*/
enum dhcpd_magic_numbers {
MAXLEN = 1024,
SHARED_NETWORKS = 8192
MAXLEN = 1024
};
/*! \enum dhcp_version
@ -120,6 +118,7 @@ struct shared_network_t {
double touched;
double backups;
int netmask;
struct shared_network_t *next;
};
/*! \struct range_t
@ -237,8 +236,8 @@ struct output_sort {
* \brief Runtime configuration state.
*/
struct conf_t {
struct shared_network_t *shared_networks;
unsigned int num_shared_networks;
struct shared_network_t *shared_net_root;
struct shared_network_t *shared_net_head;
struct range_t *ranges;
unsigned int num_ranges;
size_t ranges_size;

View file

@ -192,7 +192,7 @@ void parse_config(struct conf_t *state, const int is_include, const char *restri
word = xmalloc(sizeof(char) * MAXLEN);
if (is_include)
/* Default place holder for ranges "All networks". */
shared_p->name = state->shared_networks->name;
shared_p->name = state->shared_net_root->name;
/* Open configuration file */
dhcpd_config = fopen(config_file, "r");
if (dhcpd_config == NULL)
@ -282,7 +282,7 @@ void parse_config(struct conf_t *state, const int is_include, const char *restri
/* FIXME: Using 1000 is lame, but
* works. */
braces_shared = 1000;
shared_p = state->shared_networks;
shared_p = state->shared_net_root;
}
/* Not literally 1, but works for this
* program */
@ -374,19 +374,15 @@ void parse_config(struct conf_t *state, const int is_include, const char *restri
case ITS_A_SHAREDNET:
case ITS_A_SUBNET:
/* ignore subnets inside a shared-network */
if (argument == ITS_A_SUBNET && shared_p != state->shared_networks) {
if (argument == ITS_A_SUBNET && shared_p != state->shared_net_root) {
argument = ITS_NOTHING_INTERESTING;
break;
}
/* printf ("shared-network named: %s\n", word); */
state->num_shared_networks++;
shared_p = state->shared_networks + state->num_shared_networks;
state->shared_net_head->next = xcalloc(sizeof(struct shared_network_t), 1);
state->shared_net_head = state->shared_net_head->next;
shared_p = state->shared_net_head;
shared_p->name = xstrdup(word);
shared_p->netmask = (argument == ITS_A_SUBNET ? -1 : 0); /* do not fill in netmask */
if (SHARED_NETWORKS < state->num_shared_networks + 2)
/* FIXME: make this to go away by reallocating more space. */
error(EXIT_FAILURE, 0,
"parse_config: increase SHARED_NETWORKS in dhcpd-pools.h and recompile");
/* record network's mask too */
if (argument == ITS_A_SUBNET)
newclause = 1;

View file

@ -220,14 +220,19 @@ static int must_next_shnet(void *closure)
{
struct expl *e = closure;
do {
e->shnet_p++;
e->current--;
if (e->current <= 0)
return 0;
if (e->current == 1 || e->shnet_p == NULL)
return 0;
while (1) {
e->shnet_p = e->shnet_p->next;
if (e->shnet_p == NULL)
break;
shnet_output_helper(e->state, &e->oh, e->shnet_p);
} while (e->state->skip_ok && e->oh.status == STATUS_OK);
return 1;
if (e->state->skip_ok && e->oh.status == STATUS_OK)
continue;
else
return 1;
}
return 0;
}
static int must_enter(void *closure, const char *name)
@ -246,16 +251,16 @@ static int must_enter(void *closure, const char *name)
if (!strcmp(name, "shared-networks")) {
itf.put = must_put_shnet;
itf.next = must_next_shnet;
e->shnet_p = e->state->shared_networks;
e->current = e->state->num_shared_networks + 1;
e->shnet_p = e->state->shared_net_root;
e->current = 0;
return must_next_shnet(closure);
}
if (!strcmp(name, "summary")) {
itf.put = must_put_shnet;
itf.next = must_next_shnet;
e->shnet_p = e->state->shared_networks;
shnet_output_helper(e->state, &e->oh, e->shnet_p);
e->shnet_p = e->state->shared_net_root;
e->current = 1;
shnet_output_helper(e->state, &e->oh, e->shnet_p);
return 1;
}
return 0;
@ -265,7 +270,7 @@ static int must_leave(void *closure __attribute__ ((unused)))
{
struct expl *e = closure;
e->shnet_p = e->state->shared_networks;
e->shnet_p = e->state->shared_net_root;
e->range_p = e->state->ranges;
return 0;
}

View file

@ -510,24 +510,22 @@ void flip_ranges(struct conf_t *state)
void clean_up(struct conf_t *state)
{
struct output_sort *cur, *next;
struct shared_network_t *c, *n;
/* Just in case there something in buffers */
if (fflush(NULL))
error(EXIT_FAILURE, errno, "clean_up: fflush");
free(state->ranges);
delete_all_leases(state);
if (state->shared_networks) {
unsigned int i;
state->num_shared_networks++;
for (i = 0; i < state->num_shared_networks; i++)
free((state->shared_networks + i)->name);
free(state->shared_networks);
}
for (cur = state->sorts; cur; cur = next) {
next = cur->next;
free(cur);
}
for (c = state->shared_net_root; c; c = n) {
n = c->next;
free(c->name);
free(c);
}
}
/*! \brief A version printing. */

View file

@ -80,7 +80,7 @@ void range_output_helper(struct conf_t *state, struct output_helper_t *oh, struc
if (oh->status != STATUS_OK) {
if (oh->range_size <= state->minsize)
oh->status = STATUS_IGNORED;
else if (state->snet_alarms && range_p->shared_net != state->shared_networks)
else if (state->snet_alarms && range_p->shared_net != state->shared_net_root)
oh->status = STATUS_SUPPRESSED;
}
}
@ -186,7 +186,6 @@ static int output_txt(struct conf_t *state)
outfile = open_outfile(state);
range_p = state->ranges;
shared_p = state->shared_networks;
if (state->header_limit & R_BIT) {
fprintf(outfile, "Ranges:\n");
@ -256,10 +255,9 @@ static int output_txt(struct conf_t *state)
fprintf(outfile, "\n");
}
if (state->number_limit & S_BIT) {
for (i = 0; i < state->num_shared_networks; i++) {
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
int color_set = 0;
shared_p++;
shnet_output_helper(state, &oh, shared_p);
if (state->skip_ok && oh.status == STATUS_OK)
continue;
@ -298,20 +296,20 @@ static int output_txt(struct conf_t *state)
if (state->number_limit & A_BIT) {
int color_set = 0;
shnet_output_helper(state, &oh, state->shared_networks);
shnet_output_helper(state, &oh, state->shared_net_root);
if (state->color_mode == color_on)
color_set = start_color(&oh, outfile);
fprintf(outfile, "%-20s %5g %5g %10.3f %7g %6g %9.3f",
state->shared_networks->name,
state->shared_networks->available,
state->shared_networks->used,
state->shared_net_root->name,
state->shared_net_root->available,
state->shared_net_root->used,
oh.percent,
state->shared_networks->touched,
state->shared_net_root->touched,
oh.tc,
oh.tcp);
if (state->backups_found == 1) {
fprintf(outfile, "%7g %8.3f", state->shared_networks->backups, oh.bup);
fprintf(outfile, "%7g %8.3f", state->shared_net_root->backups, oh.bup);
}
if (color_set)
fputs(COLOR_RESET, outfile);
@ -332,7 +330,6 @@ static int output_xml(struct conf_t *state, const int print_mac_addreses)
outfile = open_outfile(state);
range_p = state->ranges;
shared_p = state->shared_networks;
fprintf(outfile, "<dhcpstatus>\n");
@ -378,8 +375,7 @@ static int output_xml(struct conf_t *state, const int print_mac_addreses)
}
if (state->number_limit & S_BIT) {
for (i = 0; i < state->num_shared_networks; i++) {
shared_p++;
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
shnet_output_helper(state, &oh, shared_p);
if (state->skip_ok && oh.status == STATUS_OK)
continue;
@ -396,12 +392,12 @@ static int output_xml(struct conf_t *state, const int print_mac_addreses)
if (state->header_limit & A_BIT) {
fprintf(outfile, "<summary>\n");
fprintf(outfile, "\t<location>%s</location>\n", state->shared_networks->name);
fprintf(outfile, "\t<defined>%g</defined>\n", state->shared_networks->available);
fprintf(outfile, "\t<used>%g</used>\n", state->shared_networks->used);
fprintf(outfile, "\t<touched>%g</touched>\n", state->shared_networks->touched);
fprintf(outfile, "\t<location>%s</location>\n", state->shared_net_root->name);
fprintf(outfile, "\t<defined>%g</defined>\n", state->shared_net_root->available);
fprintf(outfile, "\t<used>%g</used>\n", state->shared_net_root->used);
fprintf(outfile, "\t<touched>%g</touched>\n", state->shared_net_root->touched);
fprintf(outfile, "\t<free>%g</free>\n",
state->shared_networks->available - state->shared_networks->used);
state->shared_net_root->available - state->shared_net_root->used);
fprintf(outfile, "</summary>\n");
}
@ -422,7 +418,6 @@ static int output_json(struct conf_t *state, const int print_mac_addreses)
outfile = open_outfile(state);
range_p = state->ranges;
shared_p = state->shared_networks;
sep = 0;
fprintf(outfile, "{\n");
@ -503,8 +498,7 @@ static int output_json(struct conf_t *state, const int print_mac_addreses)
fprintf(outfile, ",\n");
}
fprintf(outfile, " \"shared-networks\": [\n");
for (i = 0; i < state->num_shared_networks; i++) {
shared_p++;
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
shnet_output_helper(state, &oh, shared_p);
if (state->skip_ok && oh.status == STATUS_OK)
continue;
@ -532,7 +526,7 @@ static int output_json(struct conf_t *state, const int print_mac_addreses)
fprintf(outfile, "\"backup_percent\":%g, ", oh.bup);
}
fprintf(outfile, "\"status\":%d ", oh.status);
if (i + 1 < state->num_shared_networks)
if (shared_p->next)
fprintf(outfile, "},\n");
else
fprintf(outfile, "}\n");
@ -542,23 +536,23 @@ static int output_json(struct conf_t *state, const int print_mac_addreses)
}
if (state->header_limit & A_BIT) {
shnet_output_helper(state, &oh, state->shared_networks);
shnet_output_helper(state, &oh, state->shared_net_root);
if (sep) {
fprintf(outfile, ",\n");
}
fprintf(outfile, " \"summary\": {\n");
fprintf(outfile, " \"location\":\"%s\",\n", state->shared_networks->name);
fprintf(outfile, " \"defined\":%g,\n", state->shared_networks->available);
fprintf(outfile, " \"used\":%g,\n", state->shared_networks->used);
fprintf(outfile, " \"touched\":%g,\n", state->shared_networks->touched);
fprintf(outfile, " \"location\":\"%s\",\n", state->shared_net_root->name);
fprintf(outfile, " \"defined\":%g,\n", state->shared_net_root->available);
fprintf(outfile, " \"used\":%g,\n", state->shared_net_root->used);
fprintf(outfile, " \"touched\":%g,\n", state->shared_net_root->touched);
fprintf(outfile, " \"free\":%g,\n",
state->shared_networks->available - state->shared_networks->used);
state->shared_net_root->available - state->shared_net_root->used);
fprintf(outfile, " \"percent\":%g,\n", oh.percent);
fprintf(outfile, " \"touch_count\":%g,\n", oh.tc);
fprintf(outfile, " \"touch_percent\":%g,\n", oh.tcp);
if (state->backups_found == 1) {
fprintf(outfile, " \"backup_count\":%g,\n",
state->shared_networks->backups);
state->shared_net_root->backups);
fprintf(outfile, " \"backup_percent\":%g,\n", oh.bup);
}
fprintf(outfile, " \"status\":%d\n", oh.status);
@ -722,7 +716,6 @@ static int output_html(struct conf_t *state)
outfile = open_outfile(state);
range_p = state->ranges;
shared_p = state->shared_networks;
html_header(state, outfile);
newsection(outfile, "Sum of all");
table_start(outfile, "a", "all");
@ -746,16 +739,16 @@ static int output_html(struct conf_t *state)
if (state->number_limit & A_BIT) {
start_tag(outfile, "tbody");
start_tag(outfile, "tr");
shnet_output_helper(state, &oh, state->shared_networks);
output_line(outfile, "td", state->shared_networks->name);
output_double(outfile, "td", state->shared_networks->available);
output_double(outfile, "td", state->shared_networks->used);
shnet_output_helper(state, &oh, state->shared_net_root);
output_line(outfile, "td", state->shared_net_root->name);
output_double(outfile, "td", state->shared_net_root->available);
output_double(outfile, "td", state->shared_net_root->used);
output_float(outfile, "td", oh.percent);
output_double(outfile, "td", state->shared_networks->touched);
output_double(outfile, "td", state->shared_net_root->touched);
output_double(outfile, "td", oh.tc);
output_float(outfile, "td", oh.tcp);
if (state->backups_found == 1) {
output_double(outfile, "td", state->shared_networks->backups);
output_double(outfile, "td", state->shared_net_root->backups);
output_float(outfile, "td", oh.tcp);
}
end_tag(outfile, "tr");
@ -783,9 +776,8 @@ static int output_html(struct conf_t *state)
}
if (state->number_limit & S_BIT) {
start_tag(outfile, "tbody");
for (i = 0; i < state->num_shared_networks; i++) {
shared_p++;
shnet_output_helper(state, &oh, state->shared_networks);
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
shnet_output_helper(state, &oh, shared_p);
if (state->skip_ok && oh.status == STATUS_OK)
continue;
start_tag(outfile, "tr");
@ -874,7 +866,6 @@ static int output_csv(struct conf_t *state)
outfile = open_outfile(state);
range_p = state->ranges;
shared_p = state->shared_networks;
if (state->header_limit & R_BIT) {
fprintf(outfile, "\"Ranges:\"\n");
fprintf
@ -927,8 +918,7 @@ static int output_csv(struct conf_t *state)
}
if (state->number_limit & S_BIT) {
for (i = 0; i < state->num_shared_networks; i++) {
shared_p++;
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
shnet_output_helper(state, &oh, shared_p);
if (state->skip_ok && oh.status == STATUS_OK)
continue;
@ -959,18 +949,18 @@ static int output_csv(struct conf_t *state)
fprintf(outfile, "\n");
}
if (state->number_limit & A_BIT) {
shnet_output_helper(state, &oh, state->shared_networks);
shnet_output_helper(state, &oh, state->shared_net_root);
fprintf(outfile,
"\"%s\",\"%g\",\"%g\",\"%.3f\",\"%g\",\"%g\",\"%.3f\"",
state->shared_networks->name,
state->shared_networks->available,
state->shared_networks->used,
state->shared_net_root->name,
state->shared_net_root->available,
state->shared_net_root->used,
oh.percent,
state->shared_networks->touched,
state->shared_net_root->touched,
oh.tc,
oh.tcp);
if (state->backups_found == 1) {
fprintf(outfile, "%7g %8.3f", state->shared_networks->backups, oh.bup);
fprintf(outfile, "%7g %8.3f", state->shared_net_root->backups, oh.bup);
}
fprintf(outfile, "\n");
}
@ -993,7 +983,6 @@ static int output_alarming(struct conf_t *state)
outfile = open_outfile(state);
range_p = state->ranges;
range_size = get_range_size(range_p);
shared_p = state->shared_networks;
if (state->number_limit & R_BIT) {
for (i = 0; i < state->num_ranges; i++) {
@ -1020,8 +1009,7 @@ static int output_alarming(struct conf_t *state)
}
}
if (state->number_limit & S_BIT) {
for (i = 0; i < state->num_shared_networks; i++) {
shared_p++;
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
shnet_output_helper(state, &oh, shared_p);
switch (oh.status) {
case STATUS_IGNORED:
@ -1108,7 +1096,7 @@ static int output_alarming(struct conf_t *state)
fprintf(outfile, " snet_ignored=%d", si);
}
if (state->perfdata == 1 && state->header_limit & R_BIT) {
for (i = 0; i < state->num_shared_networks; i++) {
for (shared_p = state->shared_net_root->next; shared_p; shared_p = shared_p->next) {
if (state->minsize < shared_p->available) {
fprintf(outfile, " '%s_s'=%g;%g;%g;0;%g",
shared_p->name,
@ -1123,7 +1111,6 @@ static int output_alarming(struct conf_t *state)
shared_p->name, shared_p->backups);
}
}
shared_p--;
}
fprintf(outfile, "\n");
}

View file

@ -1,3 +1,3 @@
OK: Ranges - crit: 0 warn: 0 ok: 5; | range_crit=0 range_warn=0 range_ok=5 10.4.0.1_r=5;16;18;0;20 10.4.0.1_rt=0 10.3.0.1_r=9;16;18;0;20 10.3.0.1_rt=0 10.2.0.1_r=8;16;18;0;20 10.2.0.1_rt=0 10.1.0.1_r=10;16;18;0;20 10.1.0.1_rt=0 10.0.0.1_r=11;16;18;0;20 10.0.0.1_rt=0
Shared nets - crit: 0 warn: 0 ok: 2; | snet_crit=0 snet_warn=0 snet_ok=2 'example2_s'=17;32;36;0;40 'example2_st'=0 'example1_s'=21;32;36;0;40 'example1_st'=0
Shared nets - crit: 0 warn: 0 ok: 2; | snet_crit=0 snet_warn=0 snet_ok=2 'example1_s'=21;32;36;0;40 'example1_st'=0 'example2_s'=17;32;36;0;40 'example2_st'=0