[CRIU] [crtools-bot for Andrey Vagin ] dump: use prctl to dump clear_tid_address

Cyrill Gorcunov gorcunov at openvz.org
Wed Feb 22 06:06:51 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit 62ba357e4d16311a093e6db01eb5434737622bb7
Author: Andrey Vagin <avagin at openvz.org>
Date:   Tue Feb 21 09:25:17 2012 +0300

    dump: use prctl to dump clear_tid_address
    
    Signed-off-by: Andrey Vagin <avagin at openvz.org>
    Acked-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c                  |   24 +++++++++++++++++-------
 include/parasite-syscall.h |    4 ++++
 include/parasite.h         |    7 +++++++
 include/ptrace.h           |    1 -
 include/types.h            |    2 +-
 parasite-syscall.c         |   13 +++++++++++++
 parasite.c                 |   13 +++++++++++++
 7 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 642755e..c7b450a 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1029,10 +1029,12 @@ err:
 	return -1;
 }
 
-static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
+static int dump_task_thread(struct parasite_ctl *parasite_ctl,
+				pid_t pid, struct cr_fdset *cr_fdset)
 {
 	struct core_entry *core		= xzalloc(sizeof(*core));
 	int ret				= -1;
+	unsigned int *taddr;
 
 	pr_info("\n");
 	pr_info("Dumping core for thread (pid: %d)\n", pid);
@@ -1045,10 +1047,16 @@ static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
 	ret = get_task_regs(pid, core, NULL);
 	if (ret)
 		goto err_free;
-	if (ptrace(PTRACE_GET_TID_ADDRESS, pid, NULL, &core->clear_tid_address)) {
-		pr_err("Can't get TID address for %d\n", pid);
-		goto err_free;
+
+	ret = parasite_dump_tid_addr_seized(parasite_ctl, pid, &taddr);
+	if (ret) {
+		pr_err("Can't dump tid address for pid %d", pid);
+		goto err;
 	}
+
+	pr_info("%d: tid_address=%p\n", pid, taddr);
+	core->clear_tid_address = (u64) taddr;
+
 	pr_info("OK\n");
 
 	core->tc.task_state = TASK_ALIVE;
@@ -1085,7 +1093,8 @@ static int dump_one_zombie(struct pstree_item *item, struct proc_pid_stat *pps,
 
 static struct proc_pid_stat pps_buf;
 
-static int dump_task_threads(struct pstree_item *item)
+static int dump_task_threads(struct parasite_ctl *parasite_ctl,
+					struct pstree_item *item)
 {
 	int i;
 	struct cr_fdset *cr_fdset_thread = NULL;
@@ -1102,7 +1111,8 @@ static int dump_task_threads(struct pstree_item *item)
 		if (!cr_fdset_thread)
 			goto err;
 
-		if (dump_task_thread(item->threads[i], cr_fdset_thread))
+		if (dump_task_thread(parasite_ctl,
+					item->threads[i], cr_fdset_thread))
 			goto err;
 
 		close_cr_fdset(&cr_fdset_thread);
@@ -1186,7 +1196,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
 		goto err;
 	}
 
-	ret = dump_task_threads(item);
+	ret = dump_task_threads(parasite_ctl, item);
 	if (ret) {
 		pr_err("Can't dump threads\n");
 		goto err;
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 83ec588..2ccd6ab 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -36,6 +36,10 @@ extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_d
 extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
 				      struct list_head *vma_area_list,
 				      struct cr_fdset *cr_fdset);
+struct parasite_dump_tid_addr;
+extern int parasite_dump_tid_addr_seized(struct parasite_ctl *ctl,
+					 pid_t pid, unsigned int **tid_add);
+
 extern int parasite_cure_seized(struct parasite_ctl *ctl);
 extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct list_head *vma_area_list);
diff --git a/include/parasite.h b/include/parasite.h
index 59eff7d..5277aa7 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -42,6 +42,7 @@ enum {
 	PARASITE_CMD_DUMP_SIGACTS,
 	PARASITE_CMD_DUMP_ITIMERS,
 	PARASITE_CMD_DUMP_MISC,
+	PARASITE_CMD_DUMP_TID_ADDR,
 
 	PARASITE_CMD_MAX,
 };
@@ -90,6 +91,12 @@ struct parasite_dump_misc {
 	k_rtsigset_t		blocked;
 };
 
+struct parasite_dump_tid_addr {
+	parasite_status_t	status;
+
+	unsigned int *tid_addr;
+};
+
 /*
  * Some useful offsets
  */
diff --git a/include/ptrace.h b/include/ptrace.h
index e08f862..2665e76 100644
--- a/include/ptrace.h
+++ b/include/ptrace.h
@@ -13,7 +13,6 @@
 #endif
 
 #define PTRACE_LISTEN		0x4208
-#define PTRACE_GET_TID_ADDRESS	0x4209
 
 #define PTRACE_SEIZE_DEVEL	0x80000000
 
diff --git a/include/types.h b/include/types.h
index dea51e1..63799cf 100644
--- a/include/types.h
+++ b/include/types.h
@@ -41,7 +41,7 @@
 # define PR_SET_MM_AUXV			12
 # define PR_SET_MM_EXE_FILE		13
 
-#define PR_SETUP_VDSO_AT	36
+#define PR_GET_TID_ADDR		36
 
 /* fcntl */
 #ifndef F_LINUX_SPECIFIC_BASE
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 0a27b18..e397a5f 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -423,6 +423,19 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
 	return 0;
 }
 
+int parasite_dump_tid_addr_seized(struct parasite_ctl *ctl, pid_t pid, unsigned int **tid_addr)
+{
+	struct parasite_dump_tid_addr args = { };
+	int ret;
+
+	ret = parasite_execute_by_pid(PARASITE_CMD_DUMP_TID_ADDR, ctl, pid,
+			(parasite_status_t *)&args, sizeof(args));
+
+	*tid_addr = args.tid_addr;
+
+	return ret;
+}
+
 int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
 {
 	return parasite_file_cmd("sigactions", PARASITE_CMD_DUMP_SIGACTS,
diff --git a/parasite.c b/parasite.c
index 00ecff5..e160850 100644
--- a/parasite.c
+++ b/parasite.c
@@ -374,6 +374,17 @@ static int dump_misc(struct parasite_dump_misc *args)
 	return 0;
 }
 
+static int dump_tid_addr(struct parasite_dump_tid_addr *args)
+{
+	parasite_status_t *st = &args->status;
+	int ret;
+
+	ret = sys_prctl(PR_GET_TID_ADDR, (unsigned long) &args->tid_addr, 0, 0, 0);
+
+	SET_PARASITE_STATUS(st, 0, ret);
+	return 0;
+}
+
 static int init(struct parasite_init_args *args)
 {
 	int ret;
@@ -444,6 +455,8 @@ static int __used parasite_service(unsigned long cmd, void *args, void *brk)
 		return dump_itimers((parasite_status_t *)args);
 	case PARASITE_CMD_DUMP_MISC:
 		return dump_misc((struct parasite_dump_misc *)args);
+	case PARASITE_CMD_DUMP_TID_ADDR:
+		return dump_tid_addr((struct parasite_dump_tid_addr *)args);
 	default:
 		sys_write_msg("Unknown command to parasite\n");
 		break;


More information about the CRIU mailing list