[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