criu icon indicating copy to clipboard operation
criu copied to clipboard

Restore with different PID

Open markasoftware-tc opened this issue 1 month ago • 3 comments

There are lots of pain points when restoring with the original PID -- you have to choose between risking a PID collision, or the extra complexity of a PID namespace. In our application, we are always checkpointing and restoring a single process (no children), so it would be ideal to restore with an arbitrary new PID, chosen by the kernel (/proc/sys/kernel/ns_last_pid + 1).

I'm potentially willing to contribute a new option myself, but before I dig further, are there any other issues I should expect restoring into a different PID (other than parent/child relations)?

EDIT: Found this suggesting GLIBC will not respond well to a PID change https://lists.openvz.org/pipermail/criu/2014-December/018498.html does that sound right?

markasoftware-tc avatar Nov 05 '25 01:11 markasoftware-tc

@markasoftware-tc This problem has been explored by many people in the past. The ns_last_pid kernel interface was introduced specifically to enable support for checkpoint/restore. There is even a set_ns_last_pid tool that demonstrates we can set the desired value of ns_last_pid by spawning as many processes as necessary. This tool was used as a motivation for introducing support for unprivileged checkpoint/restore with the CAP_CHECKPOINT_RESTORE capability.

Restoring in a new PID namespace is a the best solution we have so far and the criu-ns tool aims to simplify this.

rst0git avatar Nov 05 '25 08:11 rst0git

would be ideal to restore with an arbitrary new PID

There is another project called DMTCP that implements similar functionality with something they call "pid virtualization". They use LD_PRELOAD to inject a library that intercepts and modifies the behaviour of fork so that it returns a "virtual pid". The following paper provides more information: https://doi.org/10.1109/IPDPS.2009.5161063

rst0git avatar Nov 05 '25 08:11 rst0git

I'd be very surprised if there were any glibc bugs these days from changing the pid on restore, at least for single-threaded processes with no children. glibc 2.25 removed the pid cache in 2017, partially so that programs wouldn't break if they used the raw clone(2) syscall to fork the process without going through libc. So from glibc's perspective, it should just look like the restored process just clone(2)-forked itself behind its back to get a new pid. Of course, if the program itself depends on its pid (typically if it has children), then it will likely run into big issues.

LegionMammal978 avatar Dec 06 '25 00:12 LegionMammal978