Commit 5d03b52f authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

proc_parse: Fix task name parsing

The task name may include spaces so %s
scanning format will fail (in particular
dumping rsyslogd fails since thread has
name "rs:main Q:Reg"). Fix it.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 0ff0943e
...@@ -186,50 +186,96 @@ err_bogus_mapping: ...@@ -186,50 +186,96 @@ err_bogus_mapping:
int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s) int parse_pid_stat_small(pid_t pid, struct proc_pid_stat_small *s)
{ {
FILE *f; char buf[128];
char *tok; char *tok, *p;
int fd;
int n; int n;
f = fopen_proc(pid, "stat"); fd = open_proc(pid, "stat");
if (f == NULL) if (fd < 0)
return -1; return -1;
memset(s, 0, sizeof(*s)); n = read(fd, buf, sizeof(buf));
n = fscanf(f, "%d " PROC_TASK_COMM_LEN_FMT " %c %d %d %d", if (n < 1) {
&s->pid, s->comm, &s->state, &s->ppid, &s->pgid, &s->sid); pr_err("stat for %d is corrupted\n", pid);
close(fd);
if (n < 6) {
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
return -1; return -1;
} }
close(fd);
s->comm[PROC_TASK_COMM_LEN-1] = '\0'; memset(s, 0, sizeof(*s));
tok = strchr(s->comm, ')');
if (tok) tok = strchr(buf, ' ');
*tok = '\0'; if (!tok)
fclose(f); goto err;
*tok++ = '\0';
if (*tok != '(')
goto err;
s->pid = atoi(buf);
p = strrchr(tok + 1, ')');
if (!p)
goto err;
*tok = '\0';
*p = '\0';
strncpy(s->comm, tok + 1, sizeof(s->comm));
n = sscanf(p + 1, " %c %d %d %d", &s->state, &s->ppid, &s->pgid, &s->sid);
if (n < 4)
goto err;
return 0; return 0;
err:
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
return -1;
} }
int parse_pid_stat(pid_t pid, struct proc_pid_stat *s) int parse_pid_stat(pid_t pid, struct proc_pid_stat *s)
{ {
FILE *f; char buf[1024];
char *tok; char *tok, *p;
int fd;
int n; int n;
f = fopen_proc(pid, "stat"); fd = open_proc(pid, "stat");
if (f == NULL) if (fd < 0)
return -1;
n = read(fd, buf, sizeof(buf));
if (n < 1) {
pr_err("stat for %d is corrupted\n", pid);
close(fd);
return -1; return -1;
}
close(fd);
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
n = fscanf(f,
"%d " PROC_TASK_COMM_LEN_FMT " %c %d %d %d %d %d %u %lu %lu %lu %lu " tok = strchr(buf, ' ');
if (!tok)
goto err;
*tok++ = '\0';
if (*tok != '(')
goto err;
s->pid = atoi(buf);
p = strrchr(tok + 1, ')');
if (!p)
goto err;
*tok = '\0';
*p = '\0';
strncpy(s->comm, tok + 1, sizeof(s->comm));
n = sscanf(p + 1,
" %c %d %d %d %d %d %u %lu %lu %lu %lu "
"%lu %lu %ld %ld %ld %ld %d %d %llu %lu %ld %lu %lu %lu %lu " "%lu %lu %ld %ld %ld %ld %d %d %llu %lu %ld %lu %lu %lu %lu "
"%lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld " "%lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld "
"%lu %lu %lu %lu %lu %lu %lu %d", "%lu %lu %lu %lu %lu %lu %lu %d",
&s->pid,
s->comm,
&s->state, &s->state,
&s->ppid, &s->ppid,
&s->pgid, &s->pgid,
...@@ -280,19 +326,14 @@ int parse_pid_stat(pid_t pid, struct proc_pid_stat *s) ...@@ -280,19 +326,14 @@ int parse_pid_stat(pid_t pid, struct proc_pid_stat *s)
&s->env_start, &s->env_start,
&s->env_end, &s->env_end,
&s->exit_code); &s->exit_code);
if (n < 50)
if (n < 52) { goto err;
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
return -1;
}
s->comm[PROC_TASK_COMM_LEN-1] = '\0';
tok = strchr(s->comm, ')');
if (tok)
*tok = '\0';
fclose(f);
return 0; return 0;
err:
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
return -1;
} }
static int ids_parse(char *str, unsigned int *arr) static int ids_parse(char *str, unsigned int *arr)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment