[CRIU] [PATCH 1/3] dump: save /proc/pid/cmdline
Pavel Emelyanov
xemul at parallels.com
Wed Apr 22 02:49:09 PDT 2015
On 04/19/2015 09:50 PM, Ruslan Kuprieiev wrote:
> We need it to produce core dump notes and don't use it on restore.
Can you check what's the difference between /proc/pid/cmdline and
the comm in /proc/pid/stat from the kernel point of view? Can we
drive them from one another?
Otherwise the patch looks OK.
-- Pavel
> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
> ---
> cr-dump.c | 13 +++++++++++--
> include/image.h | 1 +
> include/proc_parse.h | 1 +
> proc_parse.c | 35 +++++++++++++++++++++++++++++++++++
> protobuf/core.proto | 2 ++
> pstree.c | 4 +++-
> 6 files changed, 53 insertions(+), 3 deletions(-)
>
> diff --git a/cr-dump.c b/cr-dump.c
> index ac41865..0ec3444 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -653,7 +653,8 @@ int dump_thread_core(int pid, CoreEntry *core, const struct parasite_dump_thread
> static int dump_task_core_all(struct pstree_item *item,
> const struct proc_pid_stat *stat,
> const struct parasite_dump_misc *misc,
> - const struct cr_imgset *cr_imgset)
> + const struct cr_imgset *cr_imgset,
> + char cmdline[])
> {
> struct cr_img *img;
> CoreEntry *core = item->core[0];
> @@ -669,6 +670,7 @@ static int dump_task_core_all(struct pstree_item *item,
> goto err;
>
> strncpy((char *)core->tc->comm, stat->comm, TASK_COMM_LEN);
> + strncpy((char *)core->tc->cmdline, cmdline, TASK_CMDLINE_LEN);
> core->tc->flags = stat->flags;
> core->tc->task_state = item->state;
> core->tc->exit_code = 0;
> @@ -1459,6 +1461,7 @@ static int dump_one_task(struct pstree_item *item)
> struct cr_imgset *cr_imgset = NULL;
> struct parasite_drain_fd *dfds = NULL;
> struct proc_posix_timers_stat proc_args;
> + char cmdline[TASK_CMDLINE_LEN];
>
> INIT_LIST_HEAD(&vmas.h);
> vmas.nr = 0;
> @@ -1478,6 +1481,12 @@ static int dump_one_task(struct pstree_item *item)
> if (ret < 0)
> goto err;
>
> + ret = parse_pid_cmdline(pid, cmdline);
> + if (ret) {
> + pr_err("Parse cmdline (pid: %d) failed with %d\n", pid, ret);
> + goto err;
> + }
> +
> ret = collect_mappings(pid, &vmas);
> if (ret) {
> pr_err("Collect mappings (pid: %d) failed with %d\n", pid, ret);
> @@ -1604,7 +1613,7 @@ static int dump_one_task(struct pstree_item *item)
> goto err_cure;
> }
>
> - ret = dump_task_core_all(item, &pps_buf, &misc, cr_imgset);
> + ret = dump_task_core_all(item, &pps_buf, &misc, cr_imgset, cmdline);
> if (ret) {
> pr_err("Dump core (pid: %d) failed with %d\n", pid, ret);
> goto err_cure;
> diff --git a/include/image.h b/include/image.h
> index 55e63dd..3e6d584 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -106,6 +106,7 @@
> #define CR_CAP_SIZE 2
>
> #define TASK_COMM_LEN 16
> +#define TASK_CMDLINE_LEN 80
>
> #define TASK_ALIVE 0x1
> #define TASK_DEAD 0x2
> diff --git a/include/proc_parse.h b/include/proc_parse.h
> index e5d59d2..3ca93ef 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -157,6 +157,7 @@ struct vm_area_list;
> extern bool add_skip_mount(const char *mountpoint);
> extern struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump);
> extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
> +extern int parse_pid_cmdline(pid_t pid, char cmdline[]);
> extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list);
> extern int parse_self_maps_lite(struct vm_area_list *vms);
> extern int parse_pid_status(pid_t pid, struct proc_status_creds *);
> diff --git a/proc_parse.c b/proc_parse.c
> index 5d50979..a283c9a 100644
> --- a/proc_parse.c
> +++ b/proc_parse.c
> @@ -615,6 +615,41 @@ err_n:
>
> }
>
> +int parse_pid_cmdline(pid_t pid, char cmdline[])
> +{
> + int fd;
> + ssize_t n;
> + char *p;
> +
> + fd = open_proc(pid, "cmdline");
> + if (fd < 0)
> + return -1;
> +
> + n = read(fd, buf, BUF_SIZE);
> + /* 0 is okay, as it may be zombie */
> + if (n < 0) {
> + pr_perror("Can't read cmdline for %d\n", pid);
> + close(fd);
> + return -1;
> + }
> +
> + close(fd);
> +
> + /*
> + * cmdline contains null-separated strings,
> + * so we need to replace '\0's with spaces.
> + */
> + for (p = buf; p < buf + n; p++)
> + if (*p == '\0')
> + *p = ' ';
> +
> + *p = '\0';
> +
> + strncpy(cmdline, buf, TASK_CMDLINE_LEN);
> +
> + return 0;
> +}
> +
> int parse_pid_stat(pid_t pid, struct proc_pid_stat *s)
> {
> char *tok, *p;
> diff --git a/protobuf/core.proto b/protobuf/core.proto
> index 1f44a47..d6cce24 100644
> --- a/protobuf/core.proto
> +++ b/protobuf/core.proto
> @@ -25,6 +25,8 @@ message task_core_entry {
> optional uint32 cg_set = 9;
>
> optional signal_queue_entry signals_s = 10;
> +
> + optional string cmdline = 11;
> }
>
> message task_kobj_ids_entry {
> diff --git a/pstree.c b/pstree.c
> index 2dbcb04..f97423c 100644
> --- a/pstree.c
> +++ b/pstree.c
> @@ -37,7 +37,7 @@ CoreEntry *core_entry_alloc(int th, int tsk)
>
> sz = sizeof(CoreEntry);
> if (tsk) {
> - sz += sizeof(TaskCoreEntry) + TASK_COMM_LEN;
> + sz += sizeof(TaskCoreEntry) + TASK_COMM_LEN + TASK_CMDLINE_LEN;
> if (th) {
> sz += sizeof(TaskRlimitsEntry);
> sz += RLIM_NLIMITS * sizeof(RlimitEntry *);
> @@ -60,6 +60,8 @@ CoreEntry *core_entry_alloc(int th, int tsk)
> task_core_entry__init(core->tc);
> core->tc->comm = xptr_pull_s(&m, TASK_COMM_LEN);
> memzero(core->tc->comm, TASK_COMM_LEN);
> + core->tc->cmdline = xptr_pull_s(&m, TASK_CMDLINE_LEN);
> + memzero(core->tc->cmdline, TASK_CMDLINE_LEN);
>
> if (th) {
> TaskRlimitsEntry *rls;
>
More information about the CRIU
mailing list