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

Ruslan Kuprieiev kupruser at gmail.com
Sun Apr 26 12:45:12 PDT 2015


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 14ef589..455b8d9 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;
-- 
1.9.1



More information about the CRIU mailing list