criu: Add time namespace to container config after checkpoint/restore

Since v3.14, CRIU always restores processes into a time namespace to
prevent backward jumps of monotonic and boottime clocks. This change
updates the container configuration to ensure that `runc exec` launches
new processes within the container's time namespace.

Fixes #2610

Signed-off-by: Andrei Vagin <avagin@gmail.com>
(cherry picked from commit b68cbdff34)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Andrei Vagin
2025-03-25 18:55:39 +00:00
committed by Kir Kolyshkin
parent 1c50804572
commit c248c8ecdf
2 changed files with 42 additions and 0 deletions
+7
View File
@@ -1146,6 +1146,13 @@ func (c *Container) criuNotifications(resp *criurpc.CriuResp, process *Process,
}
// create a timestamp indicating when the restored checkpoint was started
c.created = time.Now().UTC()
if !c.config.Namespaces.Contains(configs.NEWTIME) &&
configs.IsNamespaceSupported(configs.NEWTIME) &&
c.checkCriuVersion(31400) == nil {
// CRIU restores processes into a time namespace.
c.config.Namespaces = append(c.config.Namespaces,
configs.Namespace{Type: configs.NEWTIME})
}
if _, err := c.updateState(r); err != nil {
return err
}
+35
View File
@@ -441,3 +441,38 @@ function simple_cr() {
pid=$(cat "pid")
grep -q "${REL_CGROUPS_PATH}$" "/proc/$pid/cgroup"
}
@test "checkpoint/restore and exec" {
runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox running
local execed_pid=""
for _ in $(seq 2); do
# checkpoint the running container
runc checkpoint --work-path ./work-dir test_busybox
[ "$status" -eq 0 ]
# after checkpoint busybox is no longer running
testcontainer test_busybox checkpointed
# restore from checkpoint
runc restore -d --work-path ./work-dir --console-socket "$CONSOLE_SOCKET" test_busybox
[ "$status" -eq 0 ]
# busybox should be back up and running
testcontainer test_busybox running
# verify that previously exec'd process is restored.
if [ -n "$execed_pid" ]; then
runc exec test_busybox ls -ld "/proc/$execed_pid"
[ "$status" -eq 0 ]
fi
# exec a new background process.
runc exec test_busybox sh -c 'sleep 1000 < /dev/null &> /dev/null & echo $!'
[ "$status" -eq 0 ]
execed_pid=$output
done
}