bootchart: use conf-parser & CamelCase names in .conf

This commit is contained in:
Thomas Hindoe Paaboel Andersen 2013-02-14 21:32:49 +01:00
parent 47a81ba2e1
commit f7900e258d
7 changed files with 104 additions and 71 deletions

View File

@ -34,11 +34,15 @@
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include "bootchart.h"
#include "util.h"
#include "fileio.h"
#include "macro.h"
#include "conf-parser.h"
#include "strxcpyx.h"
double graph_start;
double log_start;
@ -56,11 +60,11 @@ static int exiting = 0;
int sysfd=-1;
/* graph defaults */
int entropy = 0;
int initcall = 1;
int relative;
int filter = 1;
int pss = 0;
bool entropy = false;
bool initcall = true;
bool relative = false;
bool filter = true;
bool pss = false;
int samples;
int len = 500; /* we record len+1 (1 start sample) */
double hz = 25.0; /* 20 seconds log time */
@ -88,60 +92,41 @@ int main(int argc, char *argv[])
char output_file[PATH_MAX];
char datestr[200];
time_t t = 0;
FILE *f;
const char *fn;
_cleanup_fclose_ FILE *f;
int gind;
int i;
int i, r;
char *init = NULL, *output = NULL;
const ConfigTableItem items[] = {
{ "Bootchart", "Samples", config_parse_int, 0, &len },
{ "Bootchart", "Frequency", config_parse_double, 0, &hz },
{ "Bootchart", "Relative", config_parse_bool, 0, &relative },
{ "Bootchart", "Filter", config_parse_bool, 0, &filter },
{ "Bootchart", "Output", config_parse_path, 0, &output },
{ "Bootchart", "Init", config_parse_path, 0, &init },
{ "Bootchart", "PlotMemoryUsage", config_parse_bool, 0, &pss },
{ "Bootchart", "PlotEntropyGraph", config_parse_bool, 0, &entropy },
{ "Bootchart", "ScaleX", config_parse_double, 0, &scale_x },
{ "Bootchart", "ScaleY", config_parse_double, 0, &scale_y },
{ NULL, NULL, NULL, 0, NULL }
};
rlim.rlim_cur = 4096;
rlim.rlim_max = 4096;
(void) setrlimit(RLIMIT_NOFILE, &rlim);
f = fopen("/etc/systemd/bootchart.conf", "r");
fn = "/etc/systemd/bootchart.conf";
f = fopen(fn, "re");
if (f) {
char buf[256];
char *key;
char *val;
r = config_parse(fn, f, NULL, config_item_table_lookup, (void*) items, true, NULL);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
while (fgets(buf, 80, f) != NULL) {
char *c;
c = strchr(buf, '\n');
if (c) *c = 0; /* remove trailing \n */
if (buf[0] == '#')
continue; /* comment line */
key = strtok(buf, "=");
if (!key)
continue;
val = strtok(NULL, "=");
if (!val)
continue;
// todo: filter leading/trailing whitespace
if (streq(key, "samples"))
len = atoi(val);
if (streq(key, "freq"))
hz = atof(val);
if (streq(key, "rel"))
relative = atoi(val);
if (streq(key, "filter"))
filter = atoi(val);
if (streq(key, "pss"))
pss = atoi(val);
if (streq(key, "output"))
strncpy(output_path, val, PATH_MAX - 1);
if (streq(key, "init"))
strncpy(init_path, val, PATH_MAX - 1);
if (streq(key, "scale_x"))
scale_x = atof(val);
if (streq(key, "scale_y"))
scale_y = atof(val);
if (streq(key, "entropy"))
entropy = atoi(val);
}
fclose(f);
if (init != NULL)
strscpy(init_path, sizeof(init_path), init);
if (output != NULL)
strscpy(output_path, sizeof(output_path), output);
}
while (1) {
@ -167,13 +152,13 @@ int main(int argc, char *argv[])
break;
switch (i) {
case 'r':
relative = 1;
relative = true;
break;
case 'f':
hz = atof(optarg);
break;
case 'F':
filter = 0;
filter = false;
break;
case 'n':
len = atoi(optarg);
@ -185,7 +170,7 @@ int main(int argc, char *argv[])
strncpy(init_path, optarg, PATH_MAX - 1);
break;
case 'p':
pss = 1;
pss = true;
break;
case 'x':
scale_x = atof(optarg);
@ -194,7 +179,7 @@ int main(int argc, char *argv[])
scale_y = atof(optarg);
break;
case 'e':
entropy = 1;
entropy = true;
break;
case 'h':
fprintf(stderr, "Usage: %s [OPTIONS]\n", argv[0]);

View File

@ -1,4 +1,3 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
@ -8,13 +7,14 @@
#
# See bootchart.conf(5) for details
#samples=500
#freq=25
#rel=0
#filter=1
#output=<folder name, defaults to /run/log>
#init=/path/to/init-binary
#pss=0
#entropy=0
#scale_x=100
#scale_y=20
[Bootchart]
#Samples=500
#Frequency=25
#Relative=no
#Filter=yes
#Output=<folder name, defaults to /run/log>
#Init=/path/to/init-binary
#PlotMemoryUsage=no
#PlotEntropyGraph=no
#ScaleX=100
#ScaleY=20

View File

@ -21,6 +21,7 @@
***/
#include <dirent.h>
#include <stdbool.h>
#define MAXCPUS 16
#define MAXPIDS 65535
@ -98,11 +99,11 @@ extern struct ps_struct *ps_first;
extern struct block_stat_struct blockstat[];
extern struct cpu_stat_struct cpustat[];
extern int pscount;
extern int relative;
extern int filter;
extern int pss;
extern int entropy;
extern int initcall;
extern bool relative;
extern bool filter;
extern bool pss;
extern bool entropy;
extern bool initcall;
extern int samples;
extern int cpus;
extern int len;

View File

@ -467,6 +467,33 @@ int config_parse_unsigned(
return 0;
}
int config_parse_double(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
double *d = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = safe_atod(rvalue, d);
if (r < 0) {
log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
return r;
}
return 0;
}
int config_parse_bytes_size(
const char *filename,
unsigned line,

View File

@ -92,6 +92,7 @@ int config_parse_int(const char *filename, unsigned line, const char *section, c
int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_double(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);

View File

@ -353,6 +353,23 @@ int safe_atolli(const char *s, long long int *ret_lli) {
return 0;
}
int safe_atod(const char *s, double *ret_d) {
char *x = NULL;
double d;
assert(s);
assert(ret_d);
errno = 0;
d = strtod(s, &x);
if (!x || x == s || *x || errno)
return errno ? -errno : -EINVAL;
*ret_d = (double) d;
return 0;
}
/* Split a string into words. */
char *split(const char *c, size_t *l, const char *separator, char **state) {
char *current;

View File

@ -122,6 +122,8 @@ int safe_atoi(const char *s, int *ret_i);
int safe_atollu(const char *s, unsigned long long *ret_u);
int safe_atolli(const char *s, long long int *ret_i);
int safe_atod(const char *s, double *ret_d);
#if __WORDSIZE == 32
static inline int safe_atolu(const char *s, unsigned long *ret_u) {
assert_cc(sizeof(unsigned long) == sizeof(unsigned));