mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-02 07:15:31 +00:00
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: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
0ff0943eb4
commit
5d03b52fd3
113
proc_parse.c
113
proc_parse.c
@@ -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);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
if (n < 6) {
|
memset(s, 0, sizeof(*s));
|
||||||
|
|
||||||
|
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", &s->state, &s->ppid, &s->pgid, &s->sid);
|
||||||
|
if (n < 4)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
|
pr_err("Parsing %d's stat failed (#fields do not match)\n", pid);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->comm[PROC_TASK_COMM_LEN-1] = '\0';
|
|
||||||
tok = strchr(s->comm, ')');
|
|
||||||
if (tok)
|
|
||||||
*tok = '\0';
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return -1;
|
||||||
|
|
||||||
|
n = read(fd, buf, sizeof(buf));
|
||||||
|
if (n < 1) {
|
||||||
|
pr_err("stat for %d is corrupted\n", pid);
|
||||||
|
close(fd);
|
||||||
|
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)
|
|||||||
&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)
|
||||||
|
Reference in New Issue
Block a user