The service socket now defaults to 0600 (owner-only). Since the
test runs the setuid criu binary as a non-root user (uid 1000),
the socket ends up owned by root. Chown the socket to the test
user after service startup so it can connect, mirroring what an
administrator would do in production.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Generated with Claude Code (https://claude.ai/code)
Signed-off-by: Adrian Reber <areber@redhat.com>
Change the service socket permissions from 0666 (world-accessible)
to 0600 (owner-only) to prevent unauthorized local users from
connecting to the CRIU service socket.
Print a message informing the administrator that the socket is
restricted and that chmod should be used to widen access if needed.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Generated with Claude Code (https://claude.ai/code)
Signed-off-by: Adrian Reber <areber@redhat.com>
Third-party GitHub Actions referenced by tags can change without a CRIU
patch if the upstream action repository moves or compromises a tag. That
is especially sensitive for actions that receive CI credentials such as
CODECOV_TOKEN or GITHUB_TOKEN.
Pin the remaining non-GitHub actions used by regular workflows to the
full commit IDs currently behind their version tags. Keep the version
tag in a comment next to each SHA so reviewers can see the intended
release and future updates remain explicit.
Leave GitHub-owned actions on version tags to match the existing
linux-next workflow policy, which already pins non-GitHub actions while
using tags for actions/* refs. This keeps the hardening focused on
third-party supply chain risk without forcing the repository-wide SHA
policy that would also require pinning GitHub-authored actions.
Fixes: #3068
Assisted-by: Codex:gpt-5
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
Replace 'from .images import *' with an explicit import list to
prevent namespace pollution, as the images module does not define
'__all__'.
Assisted-by: Claude Code (claude-opus-4-6@default)
Signed-off-by: Adrian Reber <areber@redhat.com>
ctrl_dir_and_opt() builds comma-separated controller directory and
mount option strings by repeatedly appending via snprintf() into
stack-allocated buffers. The offsets (doff, ooff) are advanced by
the snprintf() return value, but snprintf() returns the number of
bytes that *would* have been written on truncation, not the number
actually written. When a controller name is long enough to cause
truncation, the offset advances past the buffer end. On the next
iteration, the remaining-length calculation (e.g. ds - doff) goes
negative and is implicitly cast to a large size_t, disabling the
truncation guard entirely. Subsequent snprintf() calls and the
trailing-comma removal then write out of bounds on the stack
(CWE-121: Stack-based Buffer Overflow).
A crafted cgroup.img with oversized cnames entries triggers this
during restore in any code path that calls ctrl_dir_and_opt():
prepare_cgns(), move_in_cgroup(), prepare_cgroup_properties(),
prepare_cgroup_sfd(), and cgroupd().
Fix this by checking every snprintf() call for truncation before
advancing the offset. Each append now verifies that remaining
space is positive and that snprintf() did not return a value
greater than or equal to the remaining space. On any overflow
the function returns -1 and all five callers now propagate this
error. Also change the type of `off` in prepare_cgroup_properties()
from unsigned int to int so the -1 return is not silently converted
to a large positive value.
This vulnerability was identified and analyzed by an AI security
analysis tool.
Assisted-by: claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>
A not-accountable VMA cannot hold restored pages. If such a VMA is
matched into the COW chain, a child can inherit a parent's PROT_NONE
reservation as the target for its restored memory.
Reject not-accountable VMAs when preparing COW relationships. This makes
the child restore its pages through a separate writable premap, while the
parent's PROT_NONE reservation can still be mapped without write access.
Signed-off-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Bhavik Sachdev <b.sachdev1904@gmail.com>
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
The asyncd worker threads added in this series call pr_*() concurrently
on restore, but vprint_on_level() formatted every line into a shared
static buffer, so their output could interleave and garble log lines.
Build each line on the stack instead. Only the small read-only pid
prefix ("%6d: ") stays in process state -- written once per task in
log_init_by_pid() before any asyncd worker starts. Emitted bytes are
unchanged.
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Dan Feigin <dfeigin@nvidia.com>
When restoring an anonymous shared memory VMA, CRIU uses a memfd if the
kernel supports it and otherwise falls back to an anonymous shared mapping
opened via map_files. Route both through the async fill daemon so the
content is filled in parallel with the rest of restore.
The map_files fallback fd of an anonymous shared mapping must not be
ftruncate()d, while a memfd must. Introduce restore_shmem_fd_content(),
which takes a truncate flag, and keep restore_memfd_shmem_content() as a
truncate=true wrapper. open_shmem() offloads the fill to the daemon and
passes truncate only for the memfd case.
As with memfd inodes, the content is filled inline when restoring from a
stream, where the daemon's out-of-band reads are not possible.
Co-developed-by: Dan Feigin <dfeigin@nvidia.com>
Signed-off-by: Dan Feigin <dfeigin@nvidia.com>
Signed-off-by: Andrei Vagin <avagin@google.com>
memfds are restored as regular files, so their content can be filled in
parallel at the file level. Filling memfd data is the slowest part of
restore, and since the other restore steps do not depend on it, it can be
done asynchronously by a helper daemon.
Each restoring task creates its memfd and hands the descriptor to an
asynchronous daemon (asyncd) that fills the content (mmap + pread) from a
pool of worker threads. The daemon mirrors the usernsd design: tasks ship
work over a SEQPACKET socket via SCM_RIGHTS, and the content fill runs
out-of-band while the tasks keep restoring.
The daemon's worker threads must not hold a TID that the restorer later
needs. The restorer recreates each application thread at its original TID
via clone3(set_tid); if a daemon worker still occupies that TID the clone
fails with EEXIST ("Unable to create a thread: -17"). To guarantee the
daemon is gone before any application thread is cloned, a new restore
stage CR_STATE_PRE_RESTORER is introduced between CR_STATE_FORKING and
CR_STATE_RESTORE. The root task starts the daemon and switches all tasks
to PRE_RESTORER, during which the tasks ship their fills. The root task
then drains and reaps the daemon (stop_asyncd) before switching to
CR_STATE_RESTORE, where threads are cloned. Because the daemon is reaped
first, its worker TIDs are free by the time clone3(set_tid) runs.
Keeping the daemon inside the restored task tree (rather than forking it
from the coordinator) keeps the content fill charged to the restored
container's memory cgroup instead of to criu.
The fill-thread pool is sized to min(online_cpus, 16). stop_asyncd() fails
the restore if the daemon exits abnormally, so a failed content fill is
never silently lost, and it is idempotent so the restore paths can call it
unconditionally.
criu-image-streamer serves the image in a single sequential pass, which is
incompatible with the daemon's out-of-band reads, so the daemon is not
started when restoring from a stream and the content is filled inline
instead.
Co-developed-by: Dan Feigin <dfeigin@nvidia.com>
Signed-off-by: Dan Feigin <dfeigin@nvidia.com>
Signed-off-by: Andrei Vagin <avagin@google.com>
Parallel memfd restore opens page images from multiple pthread workers
later in this series. Those paths can use bfd helpers, whose global
buffer pool was previously single-threaded.
Protect the shared buffer list around allocation, return, and buffer
extension paths. Add pthread linkage for the new restore-time pthread
users.
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Codex:gpt-5
Signed-off-by: Dan Feigin <dfeigin@nvidia.com>
Add a memfd mmap test that keeps many independent memfds alive across
checkpoint and restore, with shared and private mappings for each one.
Verify restored fd flags and offsets, mapping devices, shared mapping
contents, private COW contents, and post-restore shared/private write
semantics.
Assisted-by: Codex:gpt-5
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Dan Feigin <dfeigin@nvidia.com>
Correct the documentation regarding `vmsplice` and `SPLICE_F_GIFT`
behavior. `SPLICE_F_GIFT` does not enforce Copy-on-Write (COW) when the
user-space process modifies the gifted memory. Instead, it is a
zero-copy mechanism where post-resume modifications can lead to
inconsistent intermediate dumps.
Explain how CRIU handles this inconsistency via its iterative design,
relying on the soft-dirty tracker to catch post-resume modifications and
re-dump them in subsequent iterations, ensuring final consistency.
Also emphasize that the `splice` scheme relies heavily on `vmsplice`
performance to minimize freeze time, making the migration almost
invisible to the process.
Signed-off-by: Andrei Vagin <avagin@google.com>
Commit 2d2168fc9 hardcodes ELFDATA2LSB in place of a previously used
endian-aware macro BORD, causing issues on big endian architectures,
e.g., on s390x:
$ ./criu/criu check -v4
(00.000000) CRIU run id = 6b0cc8b9-0cbe-44e7-aeb4-7387862d9670
(00.000016) Version: 4.2 (gitid v4.2-211-g4d76d1acd)
[...]
(00.061309) vdso: Parsing at 3ffc75ae000 3ffc75b0000
(00.061319) Error (criu/pie-util-vdso.c:126): vdso: Unsupported ELF data encoding: 2
(00.061320) Error (criu/vdso.c:633): vdso: Failed to fill self vdso symtable
(00.061321) Error (criu/kerndat.c:2043): kerndat_vdso_fill_symtable failed when initializing kerndat.
(00.061367) Adjust mmap_min_addr 0x1000 -> 0x10000
(00.061368) Found mmap_min_addr 0x10000
(00.061374) files stat: fs/nr_open 1073741816
(00.061375) Error (criu/crtools.c:280): Could not initialize kernel features detection.
Fixes: 2d2168fc9 ("vdso: relax EI_OSABI check to support linux in ELF header")
Signed-off-by: Čestmír Kalina <ckalina@redhat.com>
There is no need to use the fd libdrm duplicated from the original fd.
Just use the original one.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Simplify a bunch of error handling blocks by freeing the vm_info_entries
array as soon as we are done accessing it.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Instead of initializing and de-initializing libdrm for every buffer object
we dump (each of which consists of a few system calls), we can simply
initialize it once and by doing so simplify a bunch of the error handling
blocks.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
When saving buffer object content the current code constantly allocates
and frees aligned memory where the GPU will copy each buffer one by one.
We can optimise this path by keeping the buffer around and only grow it if
is too small for the current object.
While doing this we also fix a theoretically incorrect freeing of memory
allocated via posix_memalign with xfree.
An alternative solution could be to probe for the maximum size before hand
by adding a pre-scan loop.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
amdgpu_plugin_drm_dump_file() already defines a large temporary stack
buffer for the purpose of generating the file level protobuf image name.
Instead of the buffer object dumping loop defining a separate temporary
stack buffer for the buffer content protobuf images we can simply use the
top level one.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
We can save a few lines of code and end up with a potentially more
readable function if we replace the open-coded try-retry of getting the
list of buffer objects with a loop.
While refactoring we also remove the needless copy of the entry as the
dump loop iterates the handles, and also stop returning a false success
with a made up zero buffer objects saved in cases when the kernel does not
support the DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES ioctl.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
The DRM minor local variable is shadowed between two blocks inside
amdgpu_plugin_drm_dump_file(). If at the top level we access the minor via
the copy stored in the protobuf image, we can simply drop this copy and
so avoid the buffer object dump loop shadowing it.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
If the protobuf image allocation fails we can simply return immediately
since there aren't any other things to clean up at this point.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Pass show_test_info directly to map() instead of wrapping it
in a redundant lambda.
Assisted-by: Claude Code (claude-opus-4-6)
Signed-off-by: Adrian Reber <areber@redhat.com>
tempfile.mktemp is deprecated because it only generates a filename
without creating the file, introducing a TOCTOU race condition where
another process could create a file with the same name between the
mktemp call and the subsequent file operation.
Replace it with tempfile.mkstemp, which atomically creates the file
and returns a file descriptor, eliminating the race window.
Assisted-by: Claude Code (claude-opus-4-6)
Signed-off-by: Adrian Reber <areber@redhat.com>
When restoring inside a user namespace on a host where userfaultfd
is restricted to privileged callers, 'criu restore --lazy-pages'
fails to open a userfaultfd descriptor with EPERM. This patch improves
the error message to suggests how to fix this.
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
Add a ZDTM test that verifies inotify watches on files inside an
overlayfs mount survive checkpoint/restore.
The test uses the external mount pattern (like mnt_ext_auto): in
the ZDTM_NEWNS=1 phase it creates an overlay mount before
unshare(CLONE_NEWNS), so CRIU treats it as an external mount and
does not attempt to reconstruct the overlay on restore. After
restore the test opens the watched file and reads back the inotify
event to confirm the watch is intact.
This is needed because the test/others/overlayfs test only checks
that the process survives C/R. This ZDTM test validates that the
inotify watch itself is properly dumped and restored by exercising
the overlay directory walk fallback added in fsnotify.c.
The test is restricted to the 'ns' flavor because the overlay
setup requires the ZDTM_NEWNS=1 lifecycle and root privileges
for mounting overlayfs.
Assisted-by: Claude Code (claude-opus-4-6):default
Signed-off-by: Adrian Reber <areber@redhat.com>
Add a test that exercises checkpoint/restore of a process with an
inotify watch on a file inside an overlayfs mount.
The test compiles inotify_test.c (a simple program that sets up an
inotify watch and blocks reading events), starts it watching a file
on an overlay mount, dumps and restores via criu, then verifies the
restored process is still alive.
Run with: make -C test/others/overlayfs run-inotify
Assisted-by: Claude Code (claude-opus-4-6):default
Signed-off-by: Adrian Reber <areber@redhat.com>
When a process has inotify (or fanotify) watches on files inside an
overlayfs mount, criu dump fails because open_by_handle_at() does not
work for overlay file handles (type OVL_FILEID_V1 = 0xf8). The dump
log shows:
fsnotify: wd 0x000001 s_dev 0x00002d i_ino 0x101ad2 mask 0x00033a
fsnotify: [fhandle] bytes 0x000020 type 0x0000f8 ...
fsnotify: Handle 0x2d:0x101ad2 cannot be opened
Error (criu/fsnotify.c:284): fsnotify: Can't dump that handle
To reproduce manually:
mkdir -p /tmp/{lower,upper,work,merged}
touch /tmp/lower/testfile
mount -t overlay overlay \
-o lowerdir=/tmp/lower,upperdir=/tmp/upper,workdir=/tmp/work \
/tmp/merged
inotifywait -m /tmp/merged/testfile &
PID=$!
criu dump -t $PID -D /tmp/imgs --shell-job --ext-unix-sk
alloc_openable() iterates mounts matching s_dev and tries
open_by_handle_at() for each one. Overlay file handles use the
private OVL_FILEID_V1 type which open_by_handle_at() does not
support, so the call always fails and the dump aborts.
Add a fallback for overlay mounts: when open_by_handle_at() fails
and the mount is identified as FSTYPE__OVERLAYFS, walk the overlay
mount's directory tree with opendir/readdir/fstatat to find the
file matching the (s_dev, i_ino) pair from the handle. Store the
discovered absolute path in f_handle->path so that get_mark_path()
uses the path-based openat() strategy on restore, which works on
overlay mounts.
The fallback only triggers when open_by_handle_at() fails AND the
mount type is FSTYPE__OVERLAYFS, so there is no impact on other
filesystems.
Assisted-by: Claude Code (claude-opus-4-6):default
Signed-off-by: Adrian Reber <areber@redhat.com>
Commit 2e30db5c3d added --network-lock handling and a CLI restore
warning that checks argv[optind] after option parsing.
However, CRIU can also call parse_options() from the RPC config parsing
path with argc == 0 and argv == NULL. This path was added by 99d52ec7dd
for req->config_file handling.
If an RPC configuration file contains "network-lock iptables",
has_network_lock_opt is set and the restore warning dereferences
argv[optind], crashing criu swrk.
Guard the restore warning with argv && optind < argc before accessing
argv[optind].
Fixes: 2e30db5c3d ("criu: add --network-lock option to allow nftables alternative")
Signed-off-by: Zhang Xuedong <2190206983@qq.com>
Add a test for the SIGSEGV fixed by "mem: keep COW root VMAs writable
when premapping".
The parent reserves an address range with PROT_NONE and never touches
it, so the kernel does not account it (no "ac" flag in smaps). After
fork(), the child turns the same range into a writable mapping and fills
it with data. CRIU matches COW VMAs by start/end and flags but ignores
their protection bits, so the parent's PROT_NONE, not-accountable VMA
becomes the COW root of the child's data VMA.
On restore the child inherits the root's mapping. Without the fix that
mapping is PROT_NONE, so restoring the child's pages into it faults and
the test fails at restore; with the fix it passes.
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
Commit 7daaa11aa ("mem: don't PROT_WRITE on reservation mmaps") started
to premap PROT_NONE and not-accountable VMAs with PROT_NONE, on the
assumption that such an area is only used to reserve address space and
will never get any data written into it.
That assumption does not hold for a COW root. check_cow_vmas() pairs two
VMAs that coincide by start/end and flags regardless of their protection
bits, so a parent's PROT_NONE, not-accountable reservation can become the
COW root of a child VMA that does have pages. premap_private_vma() maps
the root with PROT_NONE, the inherited child re-positions that mapping
with mremap(), and restore_priv_vma_content() then restores the child's
pages into it. Writing to (or memcmp()-ing against) a PROT_NONE mapping
faults, so the restored task dies:
(00.012587) 109: pr109-2 Read 409000 1 pages'
(00.012588) 109: \tpr109-2 Read page from self 409000/2000'
(00.012744) 109: pr109-2 Read 7f7bf9b2e000 1 pages'
(00.012745) 109: \tpr109-2 Read page from self 7f7bf9b2e000/3000'
(00.051495) 108: Error (criu/cr-restore.c:1268): 109 killed by signal 11: Segmentation fault'
This is easy to hit with an incremental dump of a process tree that keeps
re-mapping memory (e.g. zdtm/transition/maps007 with --pre and a forked
child), where a now-PROT_NONE region still has content in a child.
To fix this, restrict the PROT_NONE optimization to standalone VMAs
(vma->pvma == NULL). A COW root (vma->pvma == VMA_COW_ROOT) must stay
writable because its premapped area is shared via mremap() with
inherited children that may carry data.
Fixes: 7daaa11aa0 ("mem: don't PROT_WRITE on reservation mmaps")
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
Fix four "unused local/global variable" alerts reported by CodeQL:
- zdtm.py: drop unused assignment to print_next in the tail-printing
loop at the end of grep_errors(). The return value of print_error()
is not needed here since no further iterations follow.
- crit-recode.py: remove duplicate pycriu.images.dumps(pb) call
inside the except handler. The same call just raised the exception,
so re-executing it would raise again and prevent the error message
from being printed.
- exhaustive/unix.py: drop unused msg variable. The recv() call is
used for its blocking side effect to synchronize with the parent,
the received data is not needed.
- others/mounts/mounts.py: rename unused loop variable i to _ in
the range(10) iteration.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <areber@redhat.com>
The tst.available() and criu.available() calls were running
unconditionally for every zdtm.py subcommand (clean, list,
group, run). The zdtm_test.available() method builds umount2,
zdtm_ct, the zdtm test library, and potentially other targets.
This caused "make -C test clean" to first build all these
binaries via "./zdtm.py clean nsroot" before deleting them.
Skip the available() calls only for the clean subcommand, as
list and group still need the test binaries to be built.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <areber@redhat.com>
The clean target referenced libcriu, rpc, and crit directories
directly, but these are located under others/. This caused
"make -C test clean" to fail with "No such file or directory"
when reaching the sub-make calls.
Fix the paths to others/libcriu, others/rpc, and others/crit.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <areber@redhat.com>
test_iters.c:29:1: error: non-void function does not return a value [-Werror,-Wreturn-type]
29 | }
| ^
1 error generated.
make: *** [Makefile:48: test_iters.o] Error 1
Signed-off-by: Adrian Reber <areber@redhat.com>
The custom core dump handler tries to call gdb which makes it much
easier to understand why something crashed especially in CI. For dnf
based distribution this currently does not work because gdb is missing.
This installs gdb on dnf based CI runs.
Signed-off-by: Adrian Reber <areber@redhat.com>
By default GitHub Actions cancels all in-progress and queued matrix
legs as soon as one leg fails (fail-fast: true). Re-running only the
failed job afterwards does not bring back the cancelled siblings, so
recovering from a single failure requires re-running the whole job.
Cancelling the siblings also hides information: whether the other
shards or environments would have passed or failed is exactly
what we want to know from a CI run, not something to discard
on the first failure. Set fail-fast: false on the matrix jobs
that were still inheriting the default, so every leg runs
to completion independently.
Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
Move the two remaining Cirrus CI Vagrant-based tests (no-VDSO and
non-root) into the existing vm-fedora-rawhide-test GitHub Actions
matrix job using Lima VMs.
Add fedora-no-vdso-{setup,test} and fedora-non-root-{setup,test}
functions to scripts/ci/lima.sh, expand the matrix in ci.yml with
the two new variants, make the reboot step conditional on
matrix.reboot, and remove .cirrus.yml and scripts/ci/vagrant.sh
along with their Makefile targets.
Assisted-by: Claude Code (claude-opus-4-6):claude-opus-4-6@default
Signed-off-by: Adrian Reber <areber@redhat.com>
The tests are no longer vagrant based. Remove it. Instead of naming it
lima based tests, just name it VM based tests.
Signed-off-by: Adrian Reber <areber@redhat.com>
Move the CentOS Stream 9 based test from Cirrus CI to GitHub
Actions using Lima VMs. Expand coverage to a matrix of CentOS
Stream 9 and 10 on x86_64.
Extract the common Lima VM setup steps (Lima install, image
caching, KVM enablement, VM start, source copy) into a reusable
composite action at .github/actions/lima-vm-setup.
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>
The thread-bomb test frequently fails during setup with
pthread_create() returning EAGAIN (errno 11). The test creates
1024 threads in a tight loop from main(), and each of those
threads immediately spawns another thread that joins its
predecessor, resulting in a burst of ~2048 simultaneous thread
creations with 64KB stacks.
This burst causes transient EAGAIN errors from clone() due to
kernel resource pressure (VMA allocator contention, temporary
memory fragmentation, etc.). The failure is not related to hard
resource limits — ulimit, threads-max, max_map_count and cgroup
pids limits are all well above the required values. The failure
occurs both inside and outside containers and is worse on hosts
with fewer resources.
Measured failure rates on a 16GB / 9-CPU host:
Before fix: 65% failure rate (13/20 outside container)
After fix: ~2.5% failure rate (1/40), and that failure was
a C/R issue, not a pthread_create EAGAIN
Fix this by adding a pthread_create_retry() wrapper that retries
pthread_create() up to 50 times with a 10ms delay when it returns
EAGAIN. This gives the kernel time to reclaim resources between
attempts while keeping the total worst-case retry time under one
second per thread creation.
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>
CRIU dumps and restores the SO_SNDTIMEO and SO_RCVTIMEO socket
send/receive timeout options in dump_socket_opts()/restore_socket_opts()
(criu/sockets.c), but the ZDTM suite has no dedicated coverage for them:
SO_SNDTIMEO is not exercised by any test, and SO_RCVTIMEO is only used
incidentally as a receive timeout in socket_icmp, never asserted across
checkpoint/restore.
Add socket-timeo, which sets distinct send and receive timeouts on a
socket, performs checkpoint/restore, and verifies both values survive.
Whole-second timeouts are used because the kernel stores these options
with jiffy granularity: setsockopt() may round a sub-second value to the
nearest tick depending on HZ, so a literal sub-second expectation could
fail to match the stored value regardless of checkpoint/restore. The
send and receive values differ so a mix-up between the two options is
caught.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Rocker Zhang <zhang.rocker.liyuan@gmail.com>
The amdgpu plugin's local amdgpu_drm.h defines struct
drm_color_ctm_3x4 guarded by #ifndef HAVE_DRM_COLOR_CTM_3X4,
but HAVE_DRM_COLOR_CTM_3X4 was never defined by the build
system. On systems where libdrm headers already provide this
struct (e.g. Alpine with libdrm 2.4.131), clang rejects the
redefinition as a hard error, while gcc silently accepts
identical struct redefinitions as an extension.
Add a feature test that checks whether struct drm_color_ctm_3x4
is available in the system drm_mode.h and pass
-DHAVE_DRM_COLOR_CTM_3X4 when it is, so the local fallback
definition is skipped.
Assisted-by: Claude Code (claude-opus-4-6):2025-09-03
Signed-off-by: Adrian Reber <areber@redhat.com>
The CLANG=1 parameter was only used during the Docker image build
but never propagated to the container at runtime. The hardcoded
CC=gcc in docker.env always took precedence, causing the test
container to rebuild and test with gcc instead of clang.
Override CC and HOSTCC via docker run -e flags when CLANG is set.
Signed-off-by: Adrian Reber <areber@redhat.com>
Apply the same ZDTM test sharding strategy used by the Alpine CI
job to the Arch Linux CI job (GCC only). The ZDTM tests are split
across 4 shards (indices 0-3) with a 5th shard for non-shardable
tests (lazy pages, fault injection, plugins, etc.).
This reduces the Arch Linux CI time from ~30 minutes to ~10 minutes.
Assisted-by: Claude Code (https://claude.ai/code):claude-opus-4-6
Signed-off-by: Adrian Reber <areber@redhat.com>