-/*
- * bootchart.c
- *
- * Copyright (C) 2009-2012 Intel Coproration
- *
- * Authors:
- * Auke Kok <auke-jan.h.kok@intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- */
+/***
+ bootchart.c - This file is part of systemd-bootchart
+ Copyright (C) 2009-2013 Intel Coproration
+
+ Authors:
+ Auke Kok <auke-jan.h.kok@intel.com>
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+ ***/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
+#include <sys/stat.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <getopt.h>
#include <limits.h>
#include <errno.h>
+#include <fcntl.h>
#include "bootchart.h"
#include "util.h"
+#include "fileio.h"
double graph_start;
double log_start;
int pscount;
int cpus;
double interval;
-FILE *of;
+FILE *of = NULL;
int overrun = 0;
static int exiting = 0;
+int sysfd=-1;
/* graph defaults */
int entropy = 0;
double scale_y = 20.0; /* 16px = 1 process bar */
char init_path[PATH_MAX] = "/sbin/init";
-char output_path[PATH_MAX] = "/var/log";
+char output_path[PATH_MAX] = "/run/log";
static struct rlimit rlim;
int main(int argc, char *argv[])
{
+ _cleanup_free_ char *build = NULL;
struct sigaction sig;
struct ps_struct *ps;
char output_file[PATH_MAX];
char datestr[200];
- time_t t;
+ time_t t = 0;
FILE *f;
int gind;
int i;
- memset(&t, 0, sizeof(time_t));
-
rlim.rlim_cur = 4096;
rlim.rlim_max = 4096;
(void) setrlimit(RLIMIT_NOFILE, &rlim);
execl(init_path, init_path, NULL);
}
}
+ argv[0][0] = '@';
/* start with empty ps LL */
- ps_first = malloc(sizeof(struct ps_struct));
+ ps_first = calloc(1, sizeof(struct ps_struct));
if (!ps_first) {
- perror("malloc(ps_struct)");
+ perror("calloc(ps_struct)");
exit(EXIT_FAILURE);
}
- memset(ps_first, 0, sizeof(struct ps_struct));
/* handle TERM/INT nicely */
memset(&sig, 0, sizeof(struct sigaction));
sampletime[samples] = gettime_ns();
+ if (!of && (access(output_path, R_OK|W_OK|X_OK) == 0)) {
+ t = time(NULL);
+ strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t));
+ snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", output_path, datestr);
+ of = fopen(output_file, "w");
+ }
+
+ if (sysfd < 0) {
+ sysfd = open("/sys", O_RDONLY);
+ }
+
+ if (!build) {
+ parse_env_file("/etc/os-release", NEWLINE,
+ "PRETTY_NAME", &build,
+ NULL);
+ }
+
/* wait for /proc to become available, discarding samples */
if (!(graph_start > 0.0))
log_uptime();
if (ps->smaps)
fclose(ps->smaps);
}
- closedir(proc);
- t = time(NULL);
- strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t));
- snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", output_path, datestr);
+ if (!of) {
+ t = time(NULL);
+ strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t));
+ snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", output_path, datestr);
+ of = fopen(output_file, "w");
+ }
- of = fopen(output_file, "w");
if (!of) {
perror("open output_file");
exit (EXIT_FAILURE);
}
- svg_do();
+ svg_do(build);
fprintf(stderr, "bootchartd: Wrote %s\n", output_file);
fclose(of);
+ closedir(proc);
+ close(sysfd);
+
/* nitpic cleanups */
ps = ps_first;
while (ps->next_ps) {