compel: simplify compel_stop_on_syscall

compel_stop_on_syscall is only ever called for a single task. Simplify
its implementation by removing the 'tasks' parameter and the associated
logic for handling multiple tasks. It now takes a 'pid' directly and
waits for that specific task to exit the required syscall.

Signed-off-by: Andrei Vagin <avagin@google.com>
This commit is contained in:
Andrei Vagin 2026-03-09 00:19:22 +00:00 committed by Andrei Vagin
parent 7daebbe469
commit e718fac152
2 changed files with 15 additions and 16 deletions

View file

@ -92,7 +92,7 @@ enum trace_flags {
TRACE_EXIT,
};
extern int __must_check compel_stop_on_syscall(int tasks, int sys_nr, int sys_nr_compat);
extern int __must_check compel_stop_on_syscall(pid_t pid, int sys_nr, int sys_nr_compat);
extern int compel_stop_tasks_on_syscall(int tasks, pid_t *pids, const int sys_nr, const int sys_nr_compat);
extern int __must_check compel_unmap(struct parasite_ctl *ctl, unsigned long addr);

View file

@ -1439,7 +1439,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
return -1;
}
if (compel_stop_on_syscall(1, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1)))
if (compel_stop_on_syscall(pid, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1)))
return -1;
/*
@ -1576,7 +1576,7 @@ int compel_unmap(struct parasite_ctl *ctl, unsigned long addr)
if (ret)
goto err;
ret = compel_stop_on_syscall(1, __NR(munmap, 0), __NR(munmap, 1));
ret = compel_stop_on_syscall(pid, __NR(munmap, 0), __NR(munmap, 1));
/*
* Don't touch extended registers here: they were restored
@ -1618,22 +1618,20 @@ static inline int is_required_syscall(user_regs_struct_t *regs, pid_t pid, const
}
/*
* Trap tasks on the exit from the specified syscall
* Trap a task on the exit from the specified syscall
*
* tasks - number of processes, which should be trapped
* pid - the process, which should be trapped
* sys_nr - the required syscall number
* sys_nr_compat - the required compatible syscall number
*/
int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
int compel_stop_on_syscall(pid_t pid, const int sys_nr, const int sys_nr_compat)
{
enum trace_flags trace = tasks > 1 ? TRACE_ALL : TRACE_ENTER;
enum trace_flags trace = TRACE_ENTER;
user_regs_struct_t regs;
int status, ret;
pid_t pid;
while (tasks) {
pid = wait4(-1, &status, __WALL, NULL);
if (pid == -1) {
while (1) {
if (wait4(pid, &status, __WALL, NULL) == -1) {
pr_perror("wait4 failed");
return -1;
}
@ -1647,6 +1645,7 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
pr_err("Task %d is in unexpected state: %x\n", pid, status);
return -1;
}
if (trace == TRACE_EXIT) {
trace = TRACE_ENTER;
pr_debug("`- Expecting exit\n");
@ -1657,6 +1656,7 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
}
continue;
}
if (trace == TRACE_ENTER)
trace = TRACE_EXIT;
@ -1677,8 +1677,7 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
return -1;
}
pid = wait4(pid, &status, __WALL, NULL);
if (pid == -1) {
if (wait4(pid, &status, __WALL, NULL) == -1) {
pr_perror("wait4 failed");
return -1;
}
@ -1692,11 +1691,10 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
}
pr_debug("%d was stopped\n", pid);
tasks--;
continue;
break;
}
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
if (ret) {
pr_perror("ptrace");
return -1;
@ -1744,6 +1742,7 @@ int compel_stop_tasks_on_syscall(int nr_tasks, pid_t *pids, const int sys_nr, co
continue;
cont = 1;
pid = pids[i];
pid = wait4(pid, &status, __WALL, NULL);
if (pid == -1) {
pr_perror("wait4 failed");