summaryrefslogtreecommitdiff
path: root/src/bootchart/svg.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2015-04-02 14:15:33 +0200
committerDaniel Mack <daniel@zonque.org>2015-04-03 15:29:18 +0200
commitf91781329c6d8a760e3c1b88b66b0e2137c2e5ab (patch)
tree94a417ee58753ea5a92116d0a74ec0a3a044e825 /src/bootchart/svg.c
parent34a4071e998f327945993ea6e6cbcaa0292b4093 (diff)
bootchart: clean up sysfd and proc handling
Retrieve the handle to procfs in main(), and pass it functions that need it. Kill the global variables. Also, refactor lots of code in svg_title(). There's no need to access any global variables from there either, and we really should return proper errors from there as well.
Diffstat (limited to 'src/bootchart/svg.c')
-rw-r--r--src/bootchart/svg.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c
index 8c8fab941d..b031090d2f 100644
--- a/src/bootchart/svg.c
+++ b/src/bootchart/svg.c
@@ -31,6 +31,7 @@
#include <fcntl.h>
#include "util.h"
+#include "fileio.h"
#include "macro.h"
#include "store.h"
#include "svg.h"
@@ -149,54 +150,47 @@ static void svg_header(void) {
svg(" ]]>\n </style>\n</defs>\n\n");
}
-static void svg_title(const char *build) {
- char cmdline[256] = "";
- char filename[PATH_MAX];
- char buf[256];
- char rootbdev[16] = "Unknown";
- char model[256] = "Unknown";
+static int svg_title(const char *build) {
+ _cleanup_free_ char *cmdline = NULL;
+ _cleanup_free_ char *model = NULL;
+ _cleanup_free_ char *buf = NULL;
char date[256] = "Unknown";
- char cpu[256] = "Unknown";
+ char *cpu;
char *c;
- FILE *f;
time_t t;
- int fd, r;
+ int r;
struct utsname uts;
- /* grab /proc/cmdline */
- fd = openat(procfd, "cmdline", O_RDONLY);
- f = fdopen(fd, "r");
- if (f) {
- if (!fgets(cmdline, 255, f))
- sprintf(cmdline, "Unknown");
- fclose(f);
- } else {
- if (fd >= 0)
- close(fd);
+ r = read_one_line_file("/proc/cmdline", &cmdline);
+ if (r < 0) {
+ log_error_errno(r, "Unable to read cmdline: %m\n");
+ return r;
}
/* extract root fs so we can find disk model name in sysfs */
/* FIXME: this works only in the simple case */
c = strstr(cmdline, "root=/dev/");
if (c) {
- strncpy(rootbdev, &c[10], 3);
+ char rootbdev[4];
+ char filename[32];
+
+ strncpy(rootbdev, &c[10], sizeof(rootbdev) - 1);
rootbdev[3] = '\0';
- sprintf(filename, "block/%s/device/model", rootbdev);
- fd = openat(sysfd, filename, O_RDONLY);
- f = fdopen(fd, "r");
- if (f) {
- if (!fgets(model, 255, f))
- log_error("Error reading disk model for %s: %m\n", rootbdev);
- fclose(f);
- } else {
- if (fd >= 0)
- close(fd);
+ snprintf(filename, sizeof(filename), "/sys/block/%s/device/model", rootbdev);
+
+ r = read_one_line_file(filename, &model);
+ if (r < 0) {
+ log_error("Error reading disk model for %s: %m\n", rootbdev);
+ return r;
}
}
/* various utsname parameters */
- if (uname(&uts))
+ r = uname(&uts);
+ if (r < 0) {
log_error("Error getting uname info\n");
+ return -errno;
+ }
/* date */
t = time(NULL);
@@ -204,21 +198,23 @@ static void svg_title(const char *build) {
assert_se(r > 0);
/* CPU type */
- fd = openat(procfd, "cpuinfo", O_RDONLY);
- f = fdopen(fd, "r");
- if (f) {
- while (fgets(buf, 255, f)) {
- if (strstr(buf, "model name")) {
- strncpy(cpu, &buf[13], 255);
- break;
- }
- }
- fclose(f);
- } else {
- if (fd >= 0)
- close(fd);
+ r = read_full_file("/proc/cpuinfo", &buf, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Unable to read cpuinfo: %m\n");
+ return r;
+ }
+
+ cpu = strstr(buf, "model name");
+ if (!cpu) {
+ log_error("Unable to read module name from cpuinfo.\n");
+ return -ENOENT;
}
+ cpu += 13;
+ c = strchr(cpu, '\n');
+ if (c)
+ *c = '\0';
+
svg("<text class=\"t1\" x=\"0\" y=\"30\">Bootchart for %s - %s</text>\n",
uts.nodename, date);
svg("<text class=\"t2\" x=\"20\" y=\"50\">System: %s %s %s %s</text>\n",
@@ -241,6 +237,8 @@ static void svg_title(const char *build) {
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",
arg_hz, arg_samples_len, overrun, pscount, pfiltered);
+
+ return 0;
}
static void svg_graph_box(int height) {
@@ -1273,10 +1271,10 @@ static void svg_top_ten_pss(void) {
top[n]->pid);
}
-void svg_do(const char *build) {
+int svg_do(const char *build) {
struct ps_struct *ps;
double offset = 7;
- int c;
+ int r, c;
memzero(&str, sizeof(str));
@@ -1334,9 +1332,12 @@ void svg_do(const char *build) {
svg("</g>\n\n");
svg("<g transform=\"translate(10, 0)\">\n");
- svg_title(build);
+ r = svg_title(build);
svg("</g>\n\n");
+ if (r < 0)
+ return r;
+
svg("<g transform=\"translate(10,200)\">\n");
svg_top_ten_cpu();
svg("</g>\n\n");
@@ -1359,4 +1360,6 @@ void svg_do(const char *build) {
/* svg footer */
svg("\n</svg>\n");
+
+ return 0;
}