[systemd-commits] 3 commits - src/bootchart
Lennart Poettering
lennart at kemper.freedesktop.org
Thu Mar 7 07:10:06 PST 2013
src/bootchart/bootchart.c | 39 +++++++++++++++++++++-----------------
src/bootchart/bootchart.h | 5 ++--
src/bootchart/log.c | 47 +++++++++++++++++++++++++++++++++++-----------
src/bootchart/svg.c | 43 ++++++++++++++++++++++++++++++++++--------
4 files changed, 96 insertions(+), 38 deletions(-)
New commits:
commit 57dbefdf3878cf3408f62beb69f4b87b5dc65df2
Author: Harald Hoyer <harald at redhat.com>
Date: Thu Mar 7 08:52:56 2013 +0100
bootchart: use _cleanup_fclose_
diff --git a/src/bootchart/log.c b/src/bootchart/log.c
index 43999f2..ccec03f 100644
--- a/src/bootchart/log.c
+++ b/src/bootchart/log.c
@@ -57,7 +57,7 @@ double gettime_ns(void)
void log_uptime(void)
{
- FILE *f;
+ FILE _cleanup_fclose_ *f = NULL;
char str[32];
double uptime;
@@ -65,11 +65,9 @@ void log_uptime(void)
if (!f)
return;
- if (!fscanf(f, "%s %*s", str)) {
- fclose(f);
+ if (!fscanf(f, "%s %*s", str))
return;
- }
- fclose(f);
+
uptime = strtod(str, NULL);
log_start = gettime_ns();
@@ -120,7 +118,6 @@ void log_sample(int sample)
{
static int vmstat;
static int schedstat;
- FILE *st;
char buf[4095];
char key[256];
char val[256];
@@ -253,6 +250,7 @@ schedstat_next:
/* end of our LL? then append a new record */
if (ps->pid != pid) {
+ FILE _cleanup_fclose_ *st = NULL;
char t[32];
struct ps_struct *parent;
@@ -320,10 +318,8 @@ schedstat_next:
if (!st)
continue;
if (!fscanf(st, "%*s %*s %*s %i", &p)) {
- fclose(st);
continue;
}
- fclose(st);
ps->ppid = p;
/*
commit b9a496c166c35f670b1f0fce8745bc5df5ea74ad
Author: Harald Hoyer <harald at redhat.com>
Date: Thu Mar 7 08:52:55 2013 +0100
bootchart: rename global len to samples_len
diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c
index 543037d..e7c0b49 100644
--- a/src/bootchart/bootchart.c
+++ b/src/bootchart/bootchart.c
@@ -79,7 +79,7 @@ bool filter = true;
bool show_cmdline = false;
bool pss = false;
int samples;
-int len = 500; /* we record len+1 (1 start sample) */
+int samples_len = 500; /* we record len+1 (1 start sample) */
double hz = 25.0; /* 20 seconds log time */
double scale_x = 100.0; /* 100px = 1sec */
double scale_y = 20.0; /* 16px = 1 process bar */
@@ -112,16 +112,16 @@ int main(int argc, char *argv[])
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 },
+ { "Bootchart", "Samples", config_parse_int, 0, &samples_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 }
};
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
show_cmdline = true;
break;
case 'n':
- r = safe_atoi(optarg, &len);
+ r = safe_atoi(optarg, &samples_len);
if (r < 0)
log_warning("failed to parse --samples/-n argument '%s': %s",
optarg, strerror(-r));
@@ -216,7 +216,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Usage: %s [OPTIONS]\n", argv[0]);
fprintf(stderr, " --rel, -r Record time relative to recording\n");
fprintf(stderr, " --freq, -f f Sample frequency [%f]\n", hz);
- fprintf(stderr, " --samples, -n N Stop sampling at [%d] samples\n", len);
+ fprintf(stderr, " --samples, -n N Stop sampling at [%d] samples\n", samples_len);
fprintf(stderr, " --scale-x, -x N Scale the graph horizontally [%f] \n", scale_x);
fprintf(stderr, " --scale-y, -y N Scale the graph vertically [%f] \n", scale_y);
fprintf(stderr, " --pss, -p Enable PSS graph (CPU intensive)\n");
@@ -234,7 +234,7 @@ int main(int argc, char *argv[])
}
}
- if (len > MAXSAMPLES) {
+ if (samples_len > MAXSAMPLES) {
fprintf(stderr, "Error: samples exceeds maximum\n");
exit(EXIT_FAILURE);
}
@@ -339,12 +339,12 @@ int main(int argc, char *argv[])
} else {
overrun++;
/* calculate how many samples we lost and scrap them */
- len = len + ((int)(newint_ns / interval));
+ samples_len = samples_len + ((int)(newint_ns / interval));
}
samples++;
- if (samples > len)
+ if (samples > samples_len)
break;
}
diff --git a/src/bootchart/bootchart.h b/src/bootchart/bootchart.h
index c42f971..0fe4d2f 100644
--- a/src/bootchart/bootchart.h
+++ b/src/bootchart/bootchart.h
@@ -107,7 +107,7 @@ extern bool entropy;
extern bool initcall;
extern int samples;
extern int cpus;
-extern int len;
+extern int samples_len;
extern double hz;
extern double scale_x;
extern double scale_y;
diff --git a/src/bootchart/log.c b/src/bootchart/log.c
index 1e3f4a9..43999f2 100644
--- a/src/bootchart/log.c
+++ b/src/bootchart/log.c
@@ -264,7 +264,7 @@ schedstat_next:
ps = ps->next_ps;
ps->pid = pid;
- ps->sample = calloc(len + 1, sizeof(struct ps_sched_struct));
+ ps->sample = calloc(samples_len + 1, sizeof(struct ps_sched_struct));
if (!ps->sample) {
perror("calloc(ps_struct)");
exit (EXIT_FAILURE);
diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c
index 4c78abd..9fee810 100644
--- a/src/bootchart/svg.c
+++ b/src/bootchart/svg.c
@@ -103,7 +103,7 @@ static void svg_header(void)
svg("<!-- your browser to file:///run/log/ and click. This bootchart was -->\n\n");
svg("<!-- generated by bootchart version %s, running with options: -->\n", VERSION);
- svg("<!-- hz=\"%f\" n=\"%d\" -->\n", hz, len);
+ svg("<!-- hz=\"%f\" n=\"%d\" -->\n", hz, samples_len);
svg("<!-- x=\"%f\" y=\"%f\" -->\n", scale_x, scale_y);
svg("<!-- rel=\"%d\" f=\"%d\" -->\n", relative, filter);
svg("<!-- p=\"%d\" e=\"%d\" -->\n", pss, entropy);
@@ -222,7 +222,7 @@ static void svg_title(const char *build)
svg("Not detected");
svg("</text>\n");
svg("<text class=\"sec\" x=\"20\" y=\"155\">Graph data: %.03f samples/sec, recorded %i total, dropped %i samples, %i processes, %i filtered</text>\n",
- hz, len, overrun, pscount, pfiltered);
+ hz, samples_len, overrun, pscount, pfiltered);
}
commit e90f9fa4d1cab6f73fc502fe9ef705c1bb2912a0
Author: Harald Hoyer <harald at redhat.com>
Date: Thu Mar 7 08:52:54 2013 +0100
bootchart: add parameter "-C" to expand process names to the full cmdline
diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c
index af573da..543037d 100644
--- a/src/bootchart/bootchart.c
+++ b/src/bootchart/bootchart.c
@@ -76,6 +76,7 @@ bool entropy = false;
bool initcall = true;
bool relative = false;
bool filter = true;
+bool show_cmdline = false;
bool pss = false;
int samples;
int len = 500; /* we record len+1 (1 start sample) */
@@ -150,6 +151,7 @@ int main(int argc, char *argv[])
{"output", required_argument, NULL, 'o'},
{"init", required_argument, NULL, 'i'},
{"no-filter", no_argument, NULL, 'F'},
+ {"cmdline", no_argument, NULL, 'C'},
{"help", no_argument, NULL, 'h'},
{"scale-x", required_argument, NULL, 'x'},
{"scale-y", required_argument, NULL, 'y'},
@@ -159,7 +161,7 @@ int main(int argc, char *argv[])
gind = 0;
- i = getopt_long(argc, argv, "erpf:n:o:i:Fhx:y:", opts, &gind);
+ i = getopt_long(argc, argv, "erpf:n:o:i:FChx:y:", opts, &gind);
if (i == -1)
break;
switch (i) {
@@ -175,6 +177,9 @@ int main(int argc, char *argv[])
case 'F':
filter = false;
break;
+ case 'C':
+ show_cmdline = true;
+ break;
case 'n':
r = safe_atoi(optarg, &len);
if (r < 0)
diff --git a/src/bootchart/bootchart.h b/src/bootchart/bootchart.h
index ea26c93..c42f971 100644
--- a/src/bootchart/bootchart.h
+++ b/src/bootchart/bootchart.h
@@ -61,7 +61,7 @@ struct ps_struct {
struct ps_struct *next; /* siblings */
/* must match - otherwise it's a new process with same PID */
- char name[16];
+ char name[256];
int pid;
int ppid;
@@ -101,6 +101,7 @@ extern struct cpu_stat_struct cpustat[];
extern int pscount;
extern bool relative;
extern bool filter;
+extern bool show_cmdline;
extern bool pss;
extern bool entropy;
extern bool initcall;
diff --git a/src/bootchart/log.c b/src/bootchart/log.c
index cf6c3a7..1e3f4a9 100644
--- a/src/bootchart/log.c
+++ b/src/bootchart/log.c
@@ -95,6 +95,26 @@ static char *bufgetline(char *buf)
return c;
}
+static int pid_cmdline_strncpy(char *buffer, int pid, size_t buf_len) {
+ char filename[PATH_MAX];
+ int _cleanup_close_ fd=-1;
+ ssize_t n;
+
+ sprintf(filename, "%d/cmdline", pid);
+ fd = openat(procfd, filename, O_RDONLY);
+ if (fd < 0)
+ return -errno;
+
+ n = read(fd, buffer, buf_len-1);
+ if (n > 0) {
+ int i;
+ for (i = 0; i < n; i++)
+ if (buffer[i] == '\0')
+ buffer[i] = ' ';
+ buffer[n] = '\0';
+ }
+ return 0;
+}
void log_sample(int sample)
{
@@ -273,7 +293,12 @@ schedstat_next:
if (!sscanf(buf, "%s %*s %*s", key))
continue;
- strncpy(ps->name, key, 16);
+ strncpy(ps->name, key, 256);
+
+ /* cmdline */
+ if (show_cmdline)
+ pid_cmdline_strncpy(ps->name, pid, 256);
+
/* discard line 2 */
m = bufgetline(buf);
if (!m)
@@ -433,7 +458,11 @@ catch_rename:
if (!sscanf(buf, "%s %*s %*s", key))
continue;
- strncpy(ps->name, key, 16);
+ strncpy(ps->name, key, 256);
+
+ /* cmdline */
+ if (show_cmdline)
+ pid_cmdline_strncpy(ps->name, pid, 256);
}
}
}
diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c
index f8a3776..4c78abd 100644
--- a/src/bootchart/svg.c
+++ b/src/bootchart/svg.c
@@ -267,6 +267,20 @@ static void svg_graph_box(int height)
}
}
+/* xml comments must not contain "--" */
+static char* xml_comment_encode(const char* name) {
+ char *enc_name, *p;
+
+ enc_name = strdup(name);
+ if (!enc_name)
+ return NULL;
+
+ for (p = enc_name; *p; p++)
+ if (p[0] == '-' && p[1] == '-')
+ p[1] = '_';
+
+ return enc_name;
+}
static void svg_pss_graph(void)
{
@@ -369,7 +383,7 @@ static void svg_pss_graph(void)
top = bottom + ps->sample[i].pss;
/* draw a label with the process / PID */
if ((i == 1) || (ps->sample[i - 1].pss <= (100 * scale_y)))
- svg(" <text x=\"%.03f\" y=\"%.03f\">%s [%i]</text>\n",
+ svg(" <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]</text>\n",
time_to_graph(sampletime[i] - graph_start),
kb_to_graph(1000000.0 - bottom - ((top - bottom) / 2)),
ps->name,
@@ -383,10 +397,17 @@ static void svg_pss_graph(void)
svg("\n\n<!-- PSS map - csv format -->\n");
ps = ps_first;
while (ps->next_ps) {
+ char _cleanup_free_*enc_name;
ps = ps->next_ps;
if (!ps)
continue;
- svg("<!-- %s [%d] pss=", ps->name, ps->pid);
+
+ enc_name = xml_comment_encode(ps->name);
+ if(!enc_name)
+ continue;
+
+ svg("<!-- %s [%d] pss=", enc_name, ps->pid);
+
for (i = 0; i < samples ; i++) {
svg("%d," , ps->sample[i].pss);
}
@@ -816,14 +837,20 @@ static void svg_ps_bars(void)
/* pass 2 - ps boxes */
ps = ps_first;
while ((ps = get_next_ps(ps))) {
+ char _cleanup_free_*enc_name;
+
double starttime;
int t;
if (!ps)
continue;
+ enc_name = xml_comment_encode(ps->name);
+ if(!enc_name)
+ continue;
+
/* leave some trace of what we actually filtered etc. */
- svg("<!-- %s [%i] ppid=%i runtime=%.03fs -->\n", ps->name, ps->pid,
+ svg("<!-- %s [%i] ppid=%i runtime=%.03fs -->\n", enc_name, ps->pid,
ps->ppid, ps->total);
/* it would be nice if we could use exec_start from /proc/pid/sched,
@@ -898,7 +925,7 @@ static void svg_ps_bars(void)
w = ps->first;
/* text label of process name */
- svg(" <text x=\"%.03f\" y=\"%.03f\">%s [%i] <tspan class=\"run\">%.03fs</tspan></text>\n",
+ svg(" <text x=\"%.03f\" y=\"%.03f\"><![CDATA[%s]]> [%i]<tspan class=\"run\">%.03fs</tspan></text>\n",
time_to_graph(sampletime[w] - graph_start) + 5.0,
ps_to_graph(j) + 14.0,
ps->name,
@@ -1002,7 +1029,7 @@ static void svg_top_ten_cpu(void)
svg("<text class=\"t2\" x=\"20\" y=\"0\">Top CPU consumers:</text>\n");
for (n = 0; n < 10; n++)
- svg("<text class=\"t3\" x=\"20\" y=\"%d\">%3.03fs - %s[%d]</text>\n",
+ svg("<text class=\"t3\" x=\"20\" y=\"%d\">%3.03fs - <![CDATA[%s]]> [%d]</text>\n",
20 + (n * 13),
top[n]->total,
top[n]->name,
@@ -1037,7 +1064,7 @@ static void svg_top_ten_pss(void)
svg("<text class=\"t2\" x=\"20\" y=\"0\">Top PSS consumers:</text>\n");
for (n = 0; n < 10; n++)
- svg("<text class=\"t3\" x=\"20\" y=\"%d\">%dK - %s[%d]</text>\n",
+ svg("<text class=\"t3\" x=\"20\" y=\"%d\">%dK - <![CDATA[%s]]> [%d]</text>\n",
20 + (n * 13),
top[n]->pss_max,
top[n]->name,
More information about the systemd-commits
mailing list