[CRIU] [PATCH 1/3] dump: save /proc/pid/cmdline

Ruslan Kuprieiev kupruser at gmail.com
Thu Apr 23 10:36:55 PDT 2015


Please, drop this set for now.

Thanks.

On 19.04.15 21:50, Ruslan Kuprieiev wrote:
> We need it to produce core dump notes and don't use it on restore.
>
> 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