[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