[CRIU] [PATCH] parasite: remove the hash table for tid_state-s
Andrey Vagin
avagin at openvz.org
Wed May 15 15:38:01 EDT 2013
Use the same indexes which used for item->threads
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-dump.c | 10 ++++---
include/parasite-syscall.h | 13 ++++-----
include/parasite.h | 4 +--
mem.c | 4 +--
parasite-syscall.c | 59 +++++++++++++++++++--------------------
pie/parasite.c | 69 ++++++++++------------------------------------
6 files changed, 60 insertions(+), 99 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 3e3bca3..91f9263 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1067,10 +1067,12 @@ static int collect_file_locks(const struct cr_options *opts)
}
static int dump_task_thread(struct parasite_ctl *parasite_ctl,
- struct pid *tid, CoreEntry *core)
+ const struct pstree_item *item, int id)
{
- int ret = -1, fd_core;
+ struct pid *tid = &item->threads[id];
pid_t pid = tid->real;
+ CoreEntry *core = item->core[id];
+ int ret = -1, fd_core;
pr_info("\n");
pr_info("Dumping core for thread (pid: %d)\n", pid);
@@ -1080,7 +1082,7 @@ static int dump_task_thread(struct parasite_ctl *parasite_ctl,
if (ret)
goto err;
- ret = parasite_dump_thread_seized(parasite_ctl, tid, core);
+ ret = parasite_dump_thread_seized(parasite_ctl, id, tid, core);
if (ret) {
pr_err("Can't dump thread for pid %d\n", pid);
goto err;
@@ -1198,7 +1200,7 @@ static int dump_task_threads(struct parasite_ctl *parasite_ctl,
item->threads[i].virt = item->pid.virt;
continue;
}
- if (dump_task_thread(parasite_ctl, &item->threads[i], item->core[i]))
+ if (dump_task_thread(parasite_ctl, item, i))
return -1;
}
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 12fa1de..be568f6 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -48,12 +48,11 @@ extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdse
void *parasite_args_s(struct parasite_ctl *ctl, int args_size);
int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl);
int parasite_send_fd(struct parasite_ctl *ctl, int fd);
-int __parasite_execute_daemon_by_pid(unsigned int cmd,
- struct parasite_ctl *ctl,
- pid_t pid, bool wait_ack);
+int __parasite_execute_daemon_by_id(unsigned int cmd,
+ struct parasite_ctl *ctl,
+ int id, bool wait_ack);
int __parasite_execute_daemon_wait_ack(unsigned int cmd,
- struct parasite_ctl *ctl,
- pid_t pid);
+ struct parasite_ctl *ctl, int id);
struct parasite_dump_misc;
struct vm_area_list;
@@ -66,8 +65,8 @@ extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
struct parasite_dump_thread;
struct pid;
struct _CoreEntry;
-extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, struct pid *tid,
- struct _CoreEntry *core);
+extern int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
+ struct pid *tid, struct _CoreEntry *core);
struct parasite_drain_fd;
struct fd_opts;
diff --git a/include/parasite.h b/include/parasite.h
index 1441eae..10924e8 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -69,7 +69,7 @@ struct parasite_init_args {
struct sockaddr_un p_addr;
int nr_threads;
- pid_t real;
+ int id;
struct rt_sigframe *sigframe;
};
@@ -133,7 +133,7 @@ struct parasite_dump_creds {
struct parasite_dump_thread {
unsigned int *tid_addr;
- pid_t real;
+ int id;
pid_t tid;
k_rtsigset_t blocked;
u32 tls;
diff --git a/mem.c b/mem.c
index 01740d4..dc1ec58 100644
--- a/mem.c
+++ b/mem.c
@@ -349,14 +349,14 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
pr_debug("PPB: %d pages %d segs %u pipe %d off\n",
args->nr_pages, args->nr, ppb->pipe_size, args->off);
- ret = __parasite_execute_daemon_by_pid(PARASITE_CMD_DUMPPAGES, ctl, ctl->pid.real, false);
+ ret = __parasite_execute_daemon_by_id(PARASITE_CMD_DUMPPAGES, ctl, 0, false);
if (ret < 0)
goto out_pp;
ret = parasite_send_fd(ctl, ppb->p[1]);
if (ret)
goto out_pp;
- ret = __parasite_execute_daemon_wait_ack(PARASITE_CMD_DUMPPAGES, ctl, ctl->pid.real);
+ ret = __parasite_execute_daemon_wait_ack(PARASITE_CMD_DUMPPAGES, ctl, 0);
if (ret < 0)
goto out_pp;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 36af935..3910652 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -182,18 +182,18 @@ static int __parasite_send_cmd(int sockfd, struct ctl_msg *m)
return 0;
}
-static int parasite_wait_ack(int sockfd, pid_t pid, unsigned int cmd, struct ctl_msg *m)
+static int parasite_wait_ack(int sockfd, pid_t id, unsigned int cmd, struct ctl_msg *m)
{
int ret;
- pr_debug("Wait for ack %d-%d on daemon socket\n", pid, cmd);
+ pr_debug("Wait for ack %d-%d on daemon socket\n", id, cmd);
while (1) {
memzero(m, sizeof(*m));
ret = recv(sockfd, m, sizeof(*m), MSG_WAITALL);
if (ret == -1) {
- pr_perror("Failed to read ack from %d", pid);
+ pr_perror("Failed to read ack from %d", id);
return -1;
} else if (ret != sizeof(*m)) {
pr_err("Message reply from daemon is trimmed (%d/%d)\n",
@@ -203,7 +203,7 @@ static int parasite_wait_ack(int sockfd, pid_t pid, unsigned int cmd, struct ctl
pr_debug("Fetched ack: %d %d %d %d\n",
m->id, m->cmd, m->ack, m->err);
- if (m->id != pid || m->cmd != cmd || m->ack != cmd) {
+ if (m->id != id || m->cmd != cmd || m->ack != cmd) {
pr_err("Communication error, this is not "
"the ack we expected\n");
return -1;
@@ -216,46 +216,46 @@ static int parasite_wait_ack(int sockfd, pid_t pid, unsigned int cmd, struct ctl
int __parasite_execute_daemon_wait_ack(unsigned int cmd,
struct parasite_ctl *ctl,
- pid_t pid)
+ int id)
{
struct ctl_msg m;
- if (parasite_wait_ack(ctl->tsock, pid, cmd, &m))
+ if (parasite_wait_ack(ctl->tsock, id, cmd, &m))
return -1;
if (m.err != 0) {
pr_err("Command %d for daemon %d failed with %d\n",
- cmd, pid, m.err);
+ cmd, id, m.err);
return -1;
}
return 0;
}
-int __parasite_execute_daemon_by_pid(unsigned int cmd,
- struct parasite_ctl *ctl,
- pid_t pid, bool wait_ack)
+int __parasite_execute_daemon_by_id(unsigned int cmd,
+ struct parasite_ctl *ctl, int id, bool wait_ack)
{
struct ctl_msg m;
- m = ctl_msg_cmd(pid, cmd);
+ m = ctl_msg_cmd(id, cmd);
if (__parasite_send_cmd(ctl->tsock, &m))
return -1;
if (wait_ack)
- return __parasite_execute_daemon_wait_ack(cmd, ctl, pid);
+ return __parasite_execute_daemon_wait_ack(cmd, ctl, id);
return 0;
}
-static int parasite_execute_daemon_by_pid(unsigned int cmd, struct parasite_ctl *ctl, pid_t pid)
+static int parasite_execute_daemon_by_id(unsigned int cmd,
+ struct parasite_ctl *ctl, int id)
{
- return __parasite_execute_daemon_by_pid(cmd, ctl, pid, true);
+ return __parasite_execute_daemon_by_id(cmd, ctl, id, true);
}
int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl)
{
- return parasite_execute_daemon_by_pid(cmd, ctl, ctl->pid.real);
+ return parasite_execute_daemon_by_id(cmd, ctl, 0);
}
static int munmap_seized(struct parasite_ctl *ctl, void *addr, size_t length)
@@ -319,7 +319,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid());
args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid);
args->nr_threads = nr_threads;
- args->real = pid;
+ args->id = 0;
args->sigframe = ctl->threads[0].rsigframe;
if (sock == -1) {
@@ -404,7 +404,7 @@ static int parasite_daemonize(struct parasite_ctl *ctl, int id)
pr_info("Wait for parasite being daemonized...\n");
- if (parasite_wait_ack(ctl->tsock, pid, PARASITE_CMD_DAEMONIZE, &m)) {
+ if (parasite_wait_ack(ctl->tsock, id, PARASITE_CMD_DAEMONIZE, &m)) {
pr_err("Can't switch parasite %d to daemon mode %d\n",
pid, m.err);
goto err;
@@ -418,16 +418,16 @@ err:
return -1;
}
-int parasite_dump_thread_seized(struct parasite_ctl *ctl, struct pid *tid,
- CoreEntry *core)
+int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
+ struct pid *tid, CoreEntry *core)
{
struct parasite_dump_thread *args;
int ret;
args = parasite_args(ctl, struct parasite_dump_thread);
- args->real = tid->real;
+ args->id = id;
- ret = parasite_execute_daemon_by_pid(PARASITE_CMD_DUMP_THREAD, ctl, tid->real);
+ ret = parasite_execute_daemon_by_id(PARASITE_CMD_DUMP_THREAD, ctl, id);
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr);
tid->virt = args->tid;
@@ -565,8 +565,8 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
args = parasite_args_s(ctl, size);
memcpy(args, dfds, size);
- ret = __parasite_execute_daemon_by_pid(PARASITE_CMD_DRAIN_FDS, ctl,
- ctl->pid.real, false);
+ ret = __parasite_execute_daemon_by_id(PARASITE_CMD_DRAIN_FDS, ctl,
+ 0, false);
if (ret) {
pr_err("Parasite failed to drain descriptors\n");
goto err;
@@ -576,8 +576,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
if (ret)
pr_err("Can't retrieve FDs from socket\n");
- ret |= __parasite_execute_daemon_wait_ack(PARASITE_CMD_DRAIN_FDS, ctl,
- ctl->pid.real);
+ ret |= __parasite_execute_daemon_wait_ack(PARASITE_CMD_DRAIN_FDS, ctl, 0);
err:
return ret;
}
@@ -586,8 +585,8 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
{
int ret = -1, fd;
- ret = __parasite_execute_daemon_by_pid(PARASITE_CMD_GET_PROC_FD, ctl,
- ctl->pid.real, false);
+ ret = __parasite_execute_daemon_by_id(PARASITE_CMD_GET_PROC_FD, ctl,
+ 0, false);
if (ret) {
pr_err("Parasite failed to get proc fd\n");
return ret;
@@ -596,7 +595,7 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
fd = recv_fd(ctl->tsock);
if (fd < 0)
pr_err("Can't retrieve FD from socket\n");
- if (__parasite_execute_daemon_wait_ack(PARASITE_CMD_GET_PROC_FD, ctl, ctl->pid.real)) {
+ if (__parasite_execute_daemon_wait_ack(PARASITE_CMD_GET_PROC_FD, ctl, 0)) {
close(fd);
return -1;
}
@@ -617,7 +616,7 @@ int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *i
ctl->threads[i].tid = tid;
ctl->nr_threads++;
- args->real = tid;
+ args->id = i;
args->sigframe = ctl->threads[i].rsigframe;
ret = ptrace(PTRACE_GETREGS, item->threads[i].real, NULL, &ctl->threads[i].regs_orig);
if (ret) {
@@ -730,7 +729,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
nr_dmnz++;
}
- ret = __parasite_execute_daemon_by_pid(PARASITE_CMD_FINI, ctl, ctl->pid.real, false);
+ ret = __parasite_execute_daemon_by_id(PARASITE_CMD_FINI, ctl, 0, false);
if (ret)
return -1;
diff --git a/pie/parasite.c b/pie/parasite.c
index 97661f3..488a491 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -20,7 +20,7 @@
static int tsock = -1;
static struct tid_state_s {
- pid_t real;
+ pid_t id;
pid_t tid;
futex_t cmd;
@@ -28,7 +28,6 @@ static struct tid_state_s {
struct rt_sigframe *sigframe;
- void *next;
unsigned char stack[PARASITE_STACK_SIZE] __aligned(8);
} *tid_state;
@@ -44,8 +43,6 @@ static unsigned int next_tid_state;
#define SPLICE_F_GIFT 0x08
#endif
-static struct tid_state_s *tid_table[512];
-
static int mprotect_vmas(struct parasite_mprotect_args *args)
{
struct parasite_vma_entry *vma;
@@ -179,38 +176,11 @@ static int drain_fds(struct parasite_drain_fd *args)
return ret;
}
-static void hash_thread_state(struct tid_state_s *s)
-{
- unsigned int pos = s->real % ARRAY_SIZE(tid_table);
- struct tid_state_s *next = tid_table[pos];
-
- tid_table[pos] = s;
- s->next = next;
-}
-
-static struct tid_state_s *find_thread_state(pid_t real)
-{
- unsigned int pos = real % ARRAY_SIZE(tid_table);
- struct tid_state_s *s;
-
- for (s = tid_table[pos]; s; s = s->next) {
- if (s->real == real)
- return s;
- }
-
- return NULL;
-}
-
static int dump_thread(struct parasite_dump_thread *args)
{
pid_t tid = sys_gettid();
- struct tid_state_s *s;
int ret;
- s = find_thread_state(args->real);
- if (!s)
- return -ENOENT;
-
ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
if (ret)
return ret;
@@ -227,13 +197,11 @@ static int init_thread(struct parasite_init_args *args)
return -ENOMEM;
tid_state[next_tid_state].tid = sys_gettid();
- tid_state[next_tid_state].real = args->real;
tid_state[next_tid_state].sigframe = args->sigframe;
+ tid_state[next_tid_state].id = next_tid_state;
futex_set(&tid_state[next_tid_state].cmd, PARASITE_CMD_IDLE);
- hash_thread_state(&tid_state[next_tid_state]);
-
next_tid_state++;
return 0;
@@ -478,10 +446,10 @@ static void __parasite_daemon_thread_ack(struct tid_state_s *s, int ret)
static unsigned long noinline __used
__parasite_daemon_thread(void *args, struct tid_state_s *s, unsigned long oldstack)
{
- pr_debug("Running daemon thread %d\n", s->real);
+ pr_debug("Running daemon thread %d (tid = %d)\n", s->id, s->tid);
/* Reply we're alive */
- if (__parasite_daemon_reply_ack(s->real, PARASITE_CMD_DAEMONIZE, 0))
+ if (__parasite_daemon_reply_ack(s->id, PARASITE_CMD_DAEMONIZE, 0))
return oldstack;
while (1) {
@@ -489,7 +457,7 @@ __parasite_daemon_thread(void *args, struct tid_state_s *s, unsigned long oldsta
cmd = __parasite_daemon_thread_wait_cmd(s);
- pr_debug("Command %d in daemon thread %d\n", cmd, s->real);
+ pr_debug("Command %d in daemon thread %d (tid %d)\n", cmd, s->id, s->tid);
switch (cmd) {
case PARASITE_CMD_DUMP_THREAD:
@@ -512,14 +480,12 @@ __parasite_daemon_thread(void *args, struct tid_state_s *s, unsigned long oldsta
static int __parasite_execute_thread(struct ctl_msg *m)
{
- struct tid_state_s *s = find_thread_state(m->id);
- if (!s)
- return -ENOENT;
+ struct tid_state_s *s = &tid_state[m->id];
- pr_debug("Wake thread %d daemon with command %d\n", s->real, m->cmd);
+ pr_debug("Wake thread %d daemon with command %d\n", s->id, m->cmd);
futex_set_and_wake(&s->cmd, m->cmd);
- pr_debug("Wait thread %d for PARASITE_CMD_IDLE\n", s->real);
+ pr_debug("Wait thread %d for PARASITE_CMD_IDLE\n", s->id);
futex_wait_until(&s->cmd, PARASITE_CMD_IDLE);
return s->ret;
@@ -531,7 +497,7 @@ static int fini(struct tid_state_s *s, bool block)
int i;
for (i = 1; i < next_tid_state; i++) {
- struct ctl_msg m = {.cmd = PARASITE_CMD_FINI_THREAD, .id = tid_state[i].real};
+ struct ctl_msg m = {.cmd = PARASITE_CMD_FINI_THREAD, .id = i};
__parasite_execute_thread(&m);
}
@@ -562,10 +528,10 @@ __parasite_daemon_thread_leader(void *args, struct tid_state_s *s, unsigned long
struct ctl_msg m = { };
int ret = -1;
- pr_debug("Running daemon thread leader %d\n", s->real);
+ pr_debug("Running daemon thread leader\n");
/* Reply we're alive */
- if (__parasite_daemon_reply_ack(s->real, PARASITE_CMD_DAEMONIZE, 0))
+ if (__parasite_daemon_reply_ack(0, PARASITE_CMD_DAEMONIZE, 0))
goto out;
while (1) {
@@ -633,16 +599,11 @@ static int noinline parasite_daemon(struct parasite_init_args *args)
{
struct tid_state_s *s;
unsigned long new_sp = 0;
- bool is_leader = false;
-
- s = find_thread_state(args->real);
- if (!s)
- return -ENOENT;
+ bool is_leader = (args->id == 0);
- if (s->real == thread_leader->real)
- is_leader = true;
+ s = &tid_state[args->id];
- pr_info("Parasite entering daemon mode for %d\n", s->real);
+ pr_info("Parasite entering daemon mode for %d (tid %d)\n", s->id, s->tid);
new_sp = (unsigned long)(void *)&s->stack[PARASITE_STACK_SIZE - 8];
if (is_leader)
@@ -650,7 +611,7 @@ static int noinline parasite_daemon(struct parasite_init_args *args)
else
call_daemon_thread(new_sp, args, s, __parasite_daemon_thread);
- pr_info("Parasite leaving daemon mode for %d\n", s->real);
+ pr_info("Parasite leaving daemon mode for %d\n", s->id);
if (is_leader)
sys_munmap(tid_state, TID_STATE_SIZE(nr_tid_state));
--
1.8.2
More information about the CRIU
mailing list