/***
This file is part of systemd.
Copyright (C) 2009-2013 Intel Corporation
Authors:
Auke Kok <auke-jan.h.kok@intel.com>
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 <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "alloc-util.h"
#include "bootchart.h"
#include "cgroup-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "parse-util.h"
#include "store.h"
#include "string-util.h"
#include "strxcpyx.h"
#include "time-util.h"
#include "util.h"
/*
* Alloc a static 4k buffer for stdio - primarily used to increase
* PSS buffering from the default 1k stdin buffer to reduce
* read() overhead.
*/
static int skip = 0;
double gettime_ns(void) {
struct timespec n;
clock_gettime(CLOCK_MONOTONIC, &n);
}
char *c;
if (!buf)
return NULL;
if (c)
c++;
return c;
}
ssize_t n;
if (fd < 0)
return -errno;
if (n > 0) {
int i;
for (i = 0; i < n; i++)
if (buffer[i] == '\0')
buffer[i] = ' ';
buffer[n] = '\0';
}
return 0;
}
int sample,
struct list_sample_data **ptr,
int *pscount,
int *cpus) {
char *m;
int r;
int c;
int p;
int mod;
ssize_t s;
ssize_t n;
int fd;
int procfd;
sampledata = *ptr;
if (procfd < 0)
return -errno;
if (vmstat < 0) {
/* block stuff */
if (vmstat < 0)
}
if (n <= 0) {
if (n < 0)
return -errno;
return -ENODATA;
}
buf[n] = '\0';
m = buf;
while (m) {
goto vmstat_next;
break;
}
m = bufgetline(m);
if (!m)
break;
}
if (r < 0)
return log_error_errno(r, "Unable to read schedstat: %m");
m = buf_schedstat;
while (m) {
goto schedstat_next;
if (r < 0 || c > MAXCPUS -1)
/* Oops, we only have room for MAXCPUS data */
break;
if (c == *cpus)
*cpus = c + 1;
}
m = bufgetline(m);
if (!m)
break;
}
if (arg_entropy) {
if (e_fd < 0) {
if (e_fd < 0)
}
if (n <= 0) {
} else {
buf[n] = '\0';
}
}
int pid;
continue;
continue;
break;
}
/* end of our LL? then append a new record */
char t[32];
return log_oom();
return log_oom();
(*pscount)++;
/* mark our first sample */
/* get name, start time */
continue;
}
if (s <= 0) {
continue;
}
buf[s] = '\0';
continue;
/* cmdline */
if (arg_show_cmdline)
/* discard line 2 */
m = bufgetline(buf);
if (!m)
continue;
m = bufgetline(m);
if (!m)
continue;
if (!sscanf(m, "%*s %*s %s", t))
continue;
if (r < 0)
continue;
if (arg_show_cgroup)
/* if this fails, that's OK */
/* ppid */
if (fd < 0)
continue;
if (!st) {
continue;
}
continue;
/*
* setup child pointers
*
* these are used to paint the tree coherently later
* each parent has a LL of children, and a LL of siblings
*/
if (pid == 1)
continue; /* nothing to do for init atm */
/* kthreadd has ppid=0, which breaks our tree ordering */
/* orphan */
}
/* it's the first child */
} else {
/* walk all children and append */
}
}
/* else -> found pid, append data in ps */
/* below here is all continuous logging parts - we get here on every
* iteration */
/* rt, wt */
continue;
}
if (s <= 0) {
/* clean up our file descriptors - assume that the process exited */
continue;
}
buf[s] = '\0';
continue;
return log_oom();
if (ps_prev)
/ 1000000000.0;
* by parsing "/proc/[pid]/task/[tid]/schedstat" for all [tid] != [pid]
*/
/* Browse directory "/proc/[pid]/task" to know the thread ids of process [pid] */
if (taskfd >= 0) {
if (!taskdir) {
return -errno;
}
long long delta_rt;
long long delta_wt;
continue;
/* Skip main thread as it was already accounted */
continue;
/* Parse "/proc/[pid]/task/[tid]/schedstat" */
if (tid_schedstat == -1)
continue;
if (s <= 0)
continue;
buf[s] = '\0';
continue;
if (r < 0)
continue;
if (r < 0)
continue;
}
}
if (!arg_pss)
goto catch_rename;
/* Pss */
if (fd < 0)
continue;
continue;
}
} else {
}
/* test to see if we need to skip another field */
if (skip == 0) {
continue;
}
continue;
}
skip = 2;
}
else {
skip = 1;
}
}
while (1) {
int pss_kb;
/* skip one line, this contains the object mapped. */
break;
}
/* then there's a 28 char 14 line block */
break;
}
/* skip one more line if this is a newer kernel */
if (skip == 2) {
break;
}
}
/* catch process rename, try to randomize time */
/* re-fetch name */
/* get name, start time */
continue;
}
if (s <= 0) {
/* clean up file descriptors */
continue;
}
buf[s] = '\0';
continue;
/* cmdline */
if (arg_show_cmdline)
}
}
return 0;
}