From 188c182be4796babe77b10ac50ed729d75e385cf Mon Sep 17 00:00:00 2001 From: Mehmet YILMAZ Date: Mon, 27 Oct 2025 21:00:32 +0300 Subject: [PATCH] PG18 - Enable NUMA syscalls in CI containers to fix PG18 numa.out regression test failures (#8258) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #8246 PostgreSQL 18 introduced stricter NUMA page-inquiry permissions for the `pg_shmem_allocations_numa` view. Without the required kernel capabilities, the test fails with: ``` ERROR: failed NUMA pages inquiry status: Operation not permitted ``` This PR updates our test containers to include the necessary privileges: * Adds `--cap-add=SYS_NICE` and `--security-opt seccomp=unconfined` When PostgreSQL’s new NUMA views (`pg_shmem_allocations_numa`, `pg_buffercache_numa`) run, they call `move_pages()` to ask the kernel which NUMA node holds each shared memory page. https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=8cc139bec That syscall (`move_pages()`) requires `CAP_SYS_NICE` when inspecting another process. So: `--cap-add=SYS_NICE` grants the container permission to perform that NUMA page query. https://man7.org/linux/man-pages/man2/move_pages.2.html#:~:text=must%20be%20privileged%0A%20%20%20%20%20%20%20%20%20%20(-,CAP_SYS_NICE,-)%20or%20the%20real `--security-opt seccomp=unconfined` Docker containers still run under a seccomp filter which a kernel-level sandbox that blocks many system calls entirely for safety. The default Docker seccomp profile blocks `move_pages()` outright, because it can expose kernel memory layout information. https://docs.docker.com/engine/security/seccomp/#:~:text=You%20can%20pass-,unconfined,-to%20run%20a **In combination** Both flags are required for NUMA introspection inside a container: - `SYS_NICE` → permission - `seccomp=unconfined` → ability --- .devcontainer/devcontainer.json | 2 ++ .github/workflows/build_and_test.yml | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index cddfcebf4..2114cf7f9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,6 +2,8 @@ "image": "ghcr.io/citusdata/citus-devcontainer:main", "runArgs": [ "--cap-add=SYS_PTRACE", + "--cap-add=SYS_NICE", // allow NUMA page inquiry + "--security-opt=seccomp=unconfined", // unblocks move_pages() in the container "--ulimit=core=-1", ], "forwardPorts": [ diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 5a99abef1..98e012179 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -225,10 +225,16 @@ jobs: runs-on: ubuntu-latest container: image: "${{ matrix.image_name }}:${{ fromJson(matrix.pg_version).full }}${{ needs.params.outputs.image_suffix }}" - options: --user root --dns=8.8.8.8 + options: >- + --user root + --dns=8.8.8.8 + --cap-add=SYS_NICE + --security-opt seccomp=unconfined # Due to Github creates a default network for each job, we need to use # --dns= to have similar DNS settings as our other CI systems or local # machines. Otherwise, we may see different results. + # and grant caps so PG18's NUMA introspection (pg_shmem_allocations_numa -> move_pages) + # doesn't fail with EPERM in CI. needs: - params - build