-
Notifications
You must be signed in to change notification settings - Fork 596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
compel: when pre-dump, handle ERESTART_RESTARTBLOCK as ERESTARTNOINTR #2512
Conversation
Test casesI tested two cases for this patch:
Test command and result
Without this patch, pre-dump of criu will break the sleep or poll syscall |
860e527
to
ae411f3
Compare
When pre-dump, if thread is in syscall like sleep or poll, it will return -ERESTART_RESTARTBLOCK. In that case, if we set ax register to -EINTR, it will break the original syscall. Instead, we can restore original syscall. Signed-off-by: Longjun Luo <[email protected]>
ae411f3
to
cdab649
Compare
@@ -60,7 +60,7 @@ int sigreturn_prep_fpu_frame_plain(struct rt_sigframe *sigframe, struct rt_sigfr | |||
} | |||
|
|||
int compel_get_task_regs(pid_t pid, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd, save_regs_t save, | |||
void *arg, __maybe_unused unsigned long flags) | |||
void *arg, __maybe_unused unsigned long flags, __maybe_unused bool pre_dump) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this argument is now used with both criu pre-dump
and criu dump --leave-running
, it might be better to use more generic name than pre_dump
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good to me.
@Snorch This change seems related to the discussion in #1589 (comment). Would you be able to review this pull request?
This does not sound correct. We specifically set aside the -ERESTART_RESTARTBLOCK case, e.g. see commit message of dd71cca, it says:
So we explicitly want this behavior of not restarting syscall in this case. One of the reasons why we might want not to simply restart sleep syscall is that this approach does not consider the passed time before restart and may lead to wrong sleep times (possibly even endless sleep due to repeated dump).
In other words: Application which uses sleep (nanosleep) is in charge of restarting sleep with proper time adjustment, as sleep can be interrupted by signal even without CRIU involved. |
@Snorch Yes, I agree with you. As you said, interrupted time will not be considered as elcasped time. So it is good to make ERESTART_RESTARTBLOCK case return -EINTR explicitly.
Anyway, I think two strategies are all acceptable, just one advice. |
@anatasluo syscalls like poll and sleep have restart blocks in the kernel: so they can be proper restarted only if the kernel doesn't drop their restart blocks. Otherwise, it can be the case, that a process called sleep(1h) and has been sleeping for 59 minutes, then we restart the syscall and it starts sleeping for another hour. |
@avagin This patch is used for pre-dump or --leave-running. In this case, kernel should not drop anything. And also, check the kernel code, the remanning time is saved or updated in userspace:
restart->nanosleep.rmtp is coming from userspace:
|
@avagin Test cases have considered this situation. |
compel uses rt_sigreturn to resume a process, but in the kernel, it cleans up the restart_block in the kernel: I use your test with minor modifications and I see that the poll syscall is restarted without the restart_block from the previous call:
|
@avagin I found the problem here, restore_sigcontext would not affect this patch. Because this patch doesn't use restart_syscall. Instead, this patch restarts the original syscall. The problem here is that timeout for sleep syscall is read from memory while timeout for poll syscall is a value. So this patch works for sleep syscall, but not works for poll syscall.
|
Since this patch still has problems to fix, i will close it now. |
When pre-dump, if thread is in syscall like sleep or poll, it will return -ERESTART_RESTARTBLOCK. In that case, if we set ax register to -EINTR, it will break the original syscall. Instead, we can restore original syscall.