X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbootchart%2Flog.c;h=ccec03f12cb18c6b85c49dcdc888df50d5d5ba07;hb=78da2cd926937935741ce86bd53c8b546cca6f7a;hp=c7973a528502f552b72e6c5e492a70d628ebf22a;hpb=8d6167101696a28b7ac61b48fd2c1920564c4e90;p=elogind.git diff --git a/src/bootchart/log.c b/src/bootchart/log.c index c7973a528..ccec03f12 100644 --- a/src/bootchart/log.c +++ b/src/bootchart/log.c @@ -43,7 +43,7 @@ */ static char smaps_buf[4096]; DIR *proc; - +int procfd=-1; double gettime_ns(void) { @@ -57,18 +57,17 @@ double gettime_ns(void) void log_uptime(void) { - FILE *f; + FILE _cleanup_fclose_ *f = NULL; char str[32]; double uptime; f = fopen("/proc/uptime", "r"); + 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(); @@ -94,12 +93,31 @@ 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) { static int vmstat; static int schedstat; - FILE *st; char buf[4095]; char key[256]; char val[256]; @@ -113,10 +131,22 @@ void log_sample(int sample) ssize_t s; ssize_t n; struct dirent *ent; + int fd; + + /* all the per-process stuff goes here */ + if (!proc) { + /* find all processes */ + proc = opendir("/proc"); + if (!proc) + return; + procfd = dirfd(proc); + } else { + rewinddir(proc); + } if (!vmstat) { /* block stuff */ - vmstat = open("/proc/vmstat", O_RDONLY); + vmstat = openat(procfd, "vmstat", O_RDONLY); if (vmstat == -1) { perror("open /proc/vmstat"); exit (EXIT_FAILURE); @@ -148,7 +178,7 @@ vmstat_next: if (!schedstat) { /* overall CPU utilization */ - schedstat = open("/proc/schedstat", O_RDONLY); + schedstat = openat(procfd, "schedstat", O_RDONLY); if (schedstat == -1) { perror("open /proc/schedstat"); exit (EXIT_FAILURE); @@ -186,7 +216,7 @@ schedstat_next: if (entropy) { if (!e_fd) { - e_fd = open("/proc/sys/kernel/random/entropy_avail", O_RDONLY); + e_fd = openat(procfd, "sys/kernel/random/entropy_avail", O_RDONLY); } if (e_fd) { @@ -198,16 +228,6 @@ schedstat_next: } } - /* all the per-process stuff goes here */ - if (!proc) { - /* find all processes */ - proc = opendir("/proc"); - if (!proc) - return; - } else { - rewinddir(proc); - } - while ((ent = readdir(proc)) != NULL) { char filename[PATH_MAX]; int pid; @@ -230,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; @@ -241,7 +262,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); @@ -254,8 +275,8 @@ schedstat_next: /* get name, start time */ if (!ps->sched) { - sprintf(filename, "/proc/%d/sched", pid); - ps->sched = open(filename, O_RDONLY); + sprintf(filename, "%d/sched", pid); + ps->sched = openat(procfd, filename, O_RDONLY); if (ps->sched == -1) continue; } @@ -270,7 +291,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) @@ -286,15 +312,14 @@ schedstat_next: ps->starttime = strtod(t, NULL) / 1000.0; /* ppid */ - sprintf(filename, "/proc/%d/stat", pid); - st = fopen(filename, "r"); + sprintf(filename, "%d/stat", pid); + fd = openat(procfd, filename, O_RDONLY); + st = fdopen(fd, "r"); if (!st) continue; if (!fscanf(st, "%*s %*s %*s %i", &p)) { - fclose(st); continue; } - fclose(st); ps->ppid = p; /* @@ -342,8 +367,8 @@ schedstat_next: /* rt, wt */ if (!ps->schedstat) { - sprintf(filename, "/proc/%d/schedstat", pid); - ps->schedstat = open(filename, O_RDONLY); + sprintf(filename, "%d/schedstat", pid); + ps->schedstat = openat(procfd, filename, O_RDONLY); if (ps->schedstat == -1) continue; } @@ -374,8 +399,9 @@ schedstat_next: goto catch_rename; /* Pss */ if (!ps->smaps) { - sprintf(filename, "/proc/%d/smaps", pid); - ps->smaps = fopen(filename, "r"); + sprintf(filename, "%d/smaps", pid); + fd = openat(procfd, filename, O_RDONLY); + ps->smaps = fdopen(fd, "r"); if (!ps->smaps) continue; setvbuf(ps->smaps, smaps_buf, _IOFBF, sizeof(smaps_buf)); @@ -408,8 +434,8 @@ catch_rename: /* re-fetch name */ /* get name, start time */ if (!ps->sched) { - sprintf(filename, "/proc/%d/sched", pid); - ps->sched = open(filename, O_RDONLY); + sprintf(filename, "%d/sched", pid); + ps->sched = openat(procfd, filename, O_RDONLY); if (ps->sched == -1) continue; } @@ -428,7 +454,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); } } }