diff --git a/boards/odroid-xu4/board.conf b/boards/odroid-xu4/board.conf index d225f265..289be4d8 100644 --- a/boards/odroid-xu4/board.conf +++ b/boards/odroid-xu4/board.conf @@ -22,6 +22,8 @@ KERNEL_ARCH="arm" KERNEL_REPO="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" KERNEL_TAG="v7.2" KERNEL_DEFCONFIG="exynos_defconfig" +# Kernel config for Docker support and the USB WiFi dongle. +KERNEL_CONFIG_FRAGMENTS=("docker" "wifi-rtl8188fu") # Mainline U-Boot. There is no odroid-xu4 defconfig: odroid-xu3_defconfig # covers XU3/XU3-Lite/XU4/HC1/HC2 and identifies itself as such. @@ -31,9 +33,10 @@ U_BOOT_DEFCONFIG="odroid-xu3_defconfig" # The USB3 gigabit NIC is an RTL8153; r8152 asks for its PHY patch by name and # logs a load failure without it. The NIC works either way. +# rtlwifi has the WiFi dongle's firmware. FIRMWARE_REPO="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git" FIRMWARE_TAG="20260810" -FIRMWARE_DIRS=("rtl_nic") +FIRMWARE_DIRS=("rtl_nic" "rtlwifi") # Samsung-signed boot chain: iROM -> BL1 -> BL2 -> TrustZone SW -> U-Boot. # BL1, BL2 and the TrustZone monitor have no public source and are verified by diff --git a/boards/odroid-xu4/kernel-config/wifi-rtl8188fu b/boards/odroid-xu4/kernel-config/wifi-rtl8188fu new file mode 100644 index 00000000..531f6fbd --- /dev/null +++ b/boards/odroid-xu4/kernel-config/wifi-rtl8188fu @@ -0,0 +1,3 @@ +# USB WiFi dongle: Realtek RTL8188FU (0bda:f179). Handled by mainline's +# rtl8xxxu driver, deps already come from exynos_defconfig. +CONFIG_RTL8XXXU=m diff --git a/boards/odroid-xu4/make.conf b/boards/odroid-xu4/make.conf new file mode 100644 index 00000000..be5da00a --- /dev/null +++ b/boards/odroid-xu4/make.conf @@ -0,0 +1,3 @@ +# 32-bit ARM Go defaults to PIE, which needs cgo. Packages that hardcode +# CGO_ENABLED=0 still need a patch -- see post-assemble.sh. +CGO_ENABLED=1 diff --git a/boards/odroid-xu4/patches/mesa-arm-llvm22-stringmap.patch b/boards/odroid-xu4/patches/mesa-arm-llvm22-stringmap.patch deleted file mode 100644 index fd230902..00000000 --- a/boards/odroid-xu4/patches/mesa-arm-llvm22-stringmap.patch +++ /dev/null @@ -1,16 +0,0 @@ -Backport of the upstream fix, which is in mesa main but not in 26.1.x. - -LLVM 22 dropped llvm::StringMapIterator, and gallivm still names it in the -DETECT_ARCH_ARM branch, so mesa fails to compile for 32-bit ARM only. - ---- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp -+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp -@@ -331,7 +331,7 @@ - llvm::sys::getHostCPUFeatures(features); - #endif - -- for (llvm::StringMapIterator f = features.begin(); -+ for (auto f = features.begin(); - f != features.end(); - ++f) { - MAttrs.push_back(((*f).second ? "+" : "-") + (*f).first().str()); diff --git a/boards/odroid-xu4/post-assemble.sh b/boards/odroid-xu4/post-assemble.sh index ae5ec388..6ecd5a6e 100644 --- a/boards/odroid-xu4/post-assemble.sh +++ b/boards/odroid-xu4/post-assemble.sh @@ -7,6 +7,10 @@ for dir in "${FIRMWARE_DIRS[@]}"; do cp -a "/build/firmware/${dir}/." "/build/gen/root/lib/firmware/${dir}/" done +# MFC v8 video codec firmware: a top-level file, so FIRMWARE_DIRS doesn't cover it. +mkdir -p /build/gen/root/lib/firmware +cp -a /build/firmware/s5p-mfc-v8.fw /build/gen/root/lib/firmware/ + # Mainline U-Boot's odroid-xu3 target keeps CONFIG_DISTRO_DEFAULTS, whose # BOOT_TARGET_DEVICES walks mmc2 (the SD slot), mmc1 and mmc0 looking for # extlinux/extlinux.conf. Hardkernel's boot.ini is a fork-only feature and is @@ -38,3 +42,33 @@ cat >> /build/gen/root/etc/fstab <> /build/gen/root/etc/portage/bashrc <<'EOF' +post_src_prepare() { + case "${CATEGORY}/${PN}" in + dev-go/go-md2man|app-containers/containerd) + sed -i 's/CGO_ENABLED=0/CGO_ENABLED=1/' Makefile + ;; + esac +} +EOF + +# containerd needs network for `go mod download`, blocked by network-sandbox. +# SHIM_CGO_ENABLED is a `?=` var, so an env var works directly (no sed). +mkdir -p /build/gen/root/etc/portage/env +cat > /build/gen/root/etc/portage/env/allow-net <<'EOF' +FEATURES="${FEATURES} -network-sandbox" +SHIM_CGO_ENABLED=1 +EOF +echo 'app-containers/containerd allow-net' >> /build/gen/root/etc/portage/package.env + +# docker-cli's own ebuild hardcodes CGO_ENABLED=0 for its manpages target +# since 29.7.2 (no sed/env fix works against that); docker-29.8.1+ blocks +# older docker-cli, so both are capped at the last good pair. +mkdir -p /build/gen/root/etc/portage/package.mask +cat > /build/gen/root/etc/portage/package.mask/docker-cli <<'EOF' +>app-containers/docker-cli-29.5.2 +>app-containers/docker-29.5.2 +EOF diff --git a/boards/odroid-xu4/pre-deps.sh b/boards/odroid-xu4/pre-deps.sh index 60461a1f..50916a53 100644 --- a/boards/odroid-xu4/pre-deps.sh +++ b/boards/odroid-xu4/pre-deps.sh @@ -19,11 +19,3 @@ echo 'media-libs/libglvnd X' > "${cross}/package.use/mesa" # mesa_clc builds for CBUILD, so the card selection is repeated on the host. mkdir -p /etc/portage/package.use echo 'dev-util/mesa_clc video_cards_panfrost' > /etc/portage/package.use/mesa - -# eapply_user reads patches from PORTAGE_CONFIGROOT, so they go in the prefix -# too. gallivm names llvm::StringMapIterator, which LLVM 22 removed, inside a -# DETECT_ARCH_ARM block: mesa 26.1.x fails to build for 32-bit ARM and only for -# 32-bit ARM. Fixed in mesa main, not backported. -mkdir -p "${cross}/patches/media-libs/mesa" -cp /scripts/boards/odroid-xu4/patches/mesa-arm-llvm22-stringmap.patch \ - "${cross}/patches/media-libs/mesa/" diff --git a/boards/odroid-xu4/sandbox-packages.txt b/boards/odroid-xu4/sandbox-packages.txt new file mode 100644 index 00000000..459dd187 --- /dev/null +++ b/boards/odroid-xu4/sandbox-packages.txt @@ -0,0 +1,3 @@ +# mkeficapsule needs gnutls built with pkcs11 (see sandbox-packages.use). +# Named here too so --changed-use actually rebuilds it. +net-libs/gnutls diff --git a/boards/odroid-xu4/sandbox-packages.use b/boards/odroid-xu4/sandbox-packages.use new file mode 100644 index 00000000..2b79c2af --- /dev/null +++ b/boards/odroid-xu4/sandbox-packages.use @@ -0,0 +1,2 @@ +# U-Boot's mkeficapsule fails to link without gnutls pkcs11 support. +net-libs/gnutls pkcs11 diff --git a/boards/odroid-xu4/target-packages.txt b/boards/odroid-xu4/target-packages.txt index 66dd32ca..e0f8877e 100644 --- a/boards/odroid-xu4/target-packages.txt +++ b/boards/odroid-xu4/target-packages.txt @@ -16,3 +16,8 @@ app-portage/gentoolkit # Mesa for the Mali-T620. Midgard v4 caps at GLES 2.0 and there is no Vulkan, # so this is panfrost only; VIDEO_CARDS is written by pre-deps.sh. media-libs/mesa + +# USB WiFi dongle support. SSID/PSK are set up on-device, not committed here. +net-wireless/wpa_supplicant +net-wireless/iw +net-wireless/wireless-regdb diff --git a/crossdev-stages/src/board.rs b/crossdev-stages/src/board.rs index 1b77cf3b..a081c71d 100644 --- a/crossdev-stages/src/board.rs +++ b/crossdev-stages/src/board.rs @@ -405,9 +405,14 @@ fn parse(name: &str, path: &Utf8Path, content: &str) -> Result { .map(|v| v.split_whitespace().map(str::to_string).collect()) .unwrap_or_default(), kernel_defconfig: req!("KERNEL_DEFCONFIG"), - kernel_config_fragments: kv + // Array syntax lives in `arrays`, not `kv` -- this always returned nothing. + kernel_config_fragments: arrays .get("KERNEL_CONFIG_FRAGMENTS") - .map(|v| v.split_whitespace().map(str::to_string).collect()) + .cloned() + .or_else(|| { + kv.get("KERNEL_CONFIG_FRAGMENTS") + .map(|v| v.split_whitespace().map(str::to_string).collect()) + }) .unwrap_or_default(), kernel_dtb_glob: kv.get("BOARD_DTB_GLOB").cloned(), diff --git a/crossdev-stages/src/image.rs b/crossdev-stages/src/image.rs index 5d2f6548..a9f01188 100644 --- a/crossdev-stages/src/image.rs +++ b/crossdev-stages/src/image.rs @@ -1386,7 +1386,7 @@ fn default_kernel(runner: &SandboxRunner, board: &BoardConfig) -> Result<()> { cc = board.cross_compile, defconfig = board.kernel_defconfig, board_name = board.name, - fragments = kernel_config_fragments(board), + fragments = kernel_config_fragments(board, karch, &board.cross_compile), )) } @@ -1398,7 +1398,7 @@ fn default_kernel(runner: &SandboxRunner, board: &BoardConfig) -> Result<()> { /// silently, and a board that says `# CONFIG_X is not set` has no way to find /// out that X came back on. Checking the fragments themselves means the whole /// request is covered rather than whichever symbols someone remembered to list. -fn kernel_config_fragments(board: &BoardConfig) -> String { +fn kernel_config_fragments(board: &BoardConfig, karch: &str, cc: &str) -> String { if board.kernel_config_fragments.is_empty() { return String::new(); } @@ -1416,7 +1416,7 @@ fn kernel_config_fragments(board: &BoardConfig) -> String { format!( "frags=\n\ {out}\ - make -C /build/linux ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE olddefconfig\n\ + make -C /build/linux ARCH={karch} CROSS_COMPILE={cc} olddefconfig\n\ for f in $frags; do\n\ while read -r line; do\n\ case \"$line\" in\n\ @@ -2082,6 +2082,13 @@ pub fn build( let result = match *step { "deps" => run_step("deps", "deps", &bld, &runner, boards_root, board, |_r| { + // The overlay is a precondition of these providers alone + // (apk-tools, dnf5), so it is installed here and not in + // prepare(): every other command, a plain kernel build + // included, must build with the overlay repo unreachable. + if provider.needs_overlay() { + sandbox.install_overlay(defaults_root, provider)?; + } // A wrong atom is otherwise only found by emerge, which gets // there after the sandbox list has already been built -- ten // minutes of compiling thrown away over a package that was @@ -2363,12 +2370,12 @@ mod tests { #[test] fn no_fragments_generates_nothing() { - assert!(kernel_config_fragments(&board_with(&[])).is_empty()); + assert!(kernel_config_fragments(&board_with(&[]), "riscv64", "riscv64-unknown-linux-gnu-").is_empty()); } #[test] fn a_fragment_is_looked_up_board_first_then_defaults() { - let script = kernel_config_fragments(&board_with(&["riscv64-no-vector"])); + let script = kernel_config_fragments(&board_with(&["riscv64-no-vector"]), "riscv64", "riscv64-unknown-linux-gnu-"); assert!(script.contains("/scripts/boards/demo/kernel-config/riscv64-no-vector")); assert!(script.contains("/scripts/defaults/kernel-config/riscv64-no-vector")); // Both directions of the check have to be generated: a symbol that was diff --git a/crossdev-stages/src/portage.rs b/crossdev-stages/src/portage.rs index c635bd93..a44b2e95 100644 --- a/crossdev-stages/src/portage.rs +++ b/crossdev-stages/src/portage.rs @@ -68,6 +68,18 @@ pub fn write_version_pins(portage_root: &Utf8Path, gcc_version: Option<&str>) -> std::fs::write(mask_dir.join("pin-llvm"), mask)?; std::fs::write(unmask_dir.join("pin-llvm"), unmask)?; + // Also pin these to LLVM_SLOT, same as llvm-core/* above. + std::fs::write( + mask_dir.join("pin-llvm-extra"), + "llvm-runtimes/libclc\ndev-util/spirv-llvm-translator\n", + )?; + std::fs::write( + unmask_dir.join("pin-llvm-extra"), + format!( + "=llvm-runtimes/libclc-{llvm_slot}*\n=dev-util/spirv-llvm-translator-{llvm_slot}*\n" + ), + )?; + Ok(()) } @@ -342,9 +354,14 @@ impl<'a> Portage<'a> { /// Cross-emerge packages into the target stage (mounted at `/target`). /// Uses `{chost}-emerge` which crossdev installs. + /// + /// `--backtrack=100`: ROOT=/target's near-empty vdb makes this resolve + /// almost the whole graph from scratch; the default depth (20) isn't enough. pub fn cross_emerge(&self, chost: &str, packages: &[&str]) -> Result<()> { let pkgs = shell_quote_atoms(packages); - self.run_emerge(&format!("ROOT=/target {chost}-emerge -b -k {pkgs}")) + self.run_emerge(&format!( + "ROOT=/target {chost}-emerge -b -k --backtrack=100 {pkgs}" + )) } /// Cross-emerge with `USE=build` for bootstrapping (baselayout, portage). diff --git a/crossdev-stages/src/provider.rs b/crossdev-stages/src/provider.rs index 33b7f6ee..595dd0a1 100644 --- a/crossdev-stages/src/provider.rs +++ b/crossdev-stages/src/provider.rs @@ -145,6 +145,21 @@ impl RootfsProvider { } } + /// Whether the `deps` step emerges atoms the crossdev-stages overlay + /// carries (`app-arch/apk-tools`, `sys-apps/dnf5`). The only reason + /// any build needs the overlay repository to be reachable, so nothing + /// else may treat it as a precondition. + pub fn needs_overlay(&self) -> bool { + match self { + Self::Alpine | Self::Fedora => true, + Self::Gentoo + | Self::Debian + | Self::Ubuntu + | Self::Buildroot + | Self::None => false, + } + } + /// The debootstrap flavour behind this provider, if it is one. pub fn debootstrap(&self) -> Option { match self { @@ -442,6 +457,25 @@ impl FedoraImage { mod tests { use super::{Debootstrap, RootfsProvider, SecondStage}; + #[test] + fn only_alpine_and_fedora_need_the_overlay() { + assert!(RootfsProvider::Alpine.needs_overlay()); + assert!(RootfsProvider::Fedora.needs_overlay()); + for p in [ + RootfsProvider::Gentoo, + RootfsProvider::Debian, + RootfsProvider::Ubuntu, + RootfsProvider::Buildroot, + RootfsProvider::None, + ] { + assert!( + !p.needs_overlay(), + "{} must build without the overlay", + p.name() + ); + } + } + #[test] fn parse_known_values() { assert_eq!(RootfsProvider::parse("gentoo"), Some(RootfsProvider::Gentoo)); diff --git a/crossdev-stages/src/sandbox.rs b/crossdev-stages/src/sandbox.rs index 11a213cf..6c4260f6 100644 --- a/crossdev-stages/src/sandbox.rs +++ b/crossdev-stages/src/sandbox.rs @@ -10,6 +10,7 @@ use crate::container::{ }; use crate::error::{Error, Result}; use crate::portage::{install_host_deps, sync_portage_tree, MakeConf}; +use crate::provider::RootfsProvider; use crate::stage::gentoo_profile; use crate::workspace::{store_key, Workspace}; @@ -50,15 +51,9 @@ impl Sandbox { /// Idempotent: skips if `.prepared` marker exists (or `.prepared-bare` when `bare`). /// /// With `bare`, writes `make.conf` and syncs the portage tree but does not - /// emerge packages. When `/overlay.conf` names one, - /// installs the `crossdev-stages` portage overlay (apk-tools, dnf5, the - /// opt-in ESOS firmware ebuilds). + /// emerge packages. The `crossdev-stages` overlay is not installed here: + /// see [`Sandbox::install_overlay`]. pub fn prepare(&self, mirror: Option<&str>, defaults_root: &Utf8Path, bare: bool) -> Result<()> { - // The overlay refreshes on every prepare, even on an already-prepared - // sandbox: the pinned overlay repo is the source of truth and the - // checkout is cheap and idempotent. - install_overlay(self.runner(), &self.dir, defaults_root)?; - if self.dir.join(".prepared").exists() { tracing::info!("Sandbox already prepared, skipping."); return Ok(()); @@ -96,6 +91,36 @@ impl Sandbox { Ok(()) } + /// Install the `crossdev-stages` portage overlay at the revision pinned + /// in `/overlay.conf`. + /// + /// Only a provider whose `deps` step emerges from the overlay may call + /// this ([`RootfsProvider::needs_overlay`]), and there it is fatal: + /// making it a precondition of `prepare` instead let an unreachable + /// overlay repository kill kernel builds that use no ebuild of it. + /// `provider` only names the reason in the error. + pub fn install_overlay( + &self, + defaults_root: &Utf8Path, + provider: RootfsProvider, + ) -> Result<()> { + let conf = defaults_root.join("overlay.conf"); + let failed = |msg: String| Error::Config { + file: conf.to_string(), + msg: format!( + "ROOTFS_PROVIDER={} needs packages from the crossdev-stages \ + overlay, but {msg}", + provider.name() + ), + }; + let Some((repo, tag)) = read_overlay_conf(&conf)? else { + return Err(failed("OVERLAY_REPO is empty".into())); + }; + tracing::info!("Installing crossdev-stages overlay from {repo} ({tag})…"); + install_overlay(self.runner(), &self.dir, &repo, &tag) + .map_err(|e| failed(format!("installing it from {repo} failed: {e}"))) + } + /// Return installed GCC versions grouped by slot, using `.gcc_versions` cache if present. /// Versions within each slot are sorted newest-first. pub fn get_installed_gcc_versions(&self) -> Result>> { @@ -382,11 +407,23 @@ impl Sandbox { // The prefix gets a passwd/group from acct-user/portage alone, so it // knows "portage" but not "root". Any ebuild reaching fowners with a // root: pair then dies at install time. + // Except when something merges before acct-user/portage does and + // needs "portage" too -- seed that defensively as well. runner.run(&format!( "grep -q '^root:' /usr/{chost}/etc/passwd 2>/dev/null || \ echo 'root:x:0:0:root:/root:/bin/bash' >> /usr/{chost}/etc/passwd; \ grep -q '^root:' /usr/{chost}/etc/group 2>/dev/null || \ - echo 'root:x:0:' >> /usr/{chost}/etc/group" + echo 'root:x:0:' >> /usr/{chost}/etc/group; \ + grep -q '^portage:' /usr/{chost}/etc/group 2>/dev/null || \ + echo 'portage:x:250:' >> /usr/{chost}/etc/group" + ))?; + + // The clang-crossdev-wrappers version matching our LLVM_SLOT pin has + // no KEYWORDS yet, so portage falls back to an older, pin-masked slot. + runner.run(&format!( + "mkdir -p /etc/portage/package.accept_keywords && \ + echo 'cross-{chost}/clang-crossdev-wrappers **' \ + >> /etc/portage/package.accept_keywords/clang-crossdev-wrappers" ))?; tracing::info!("Running crossdev (this takes a while)…"); @@ -712,7 +749,17 @@ impl Sandbox { portage_dir.join("package.use/rust"), "dev-lang/rust rustfmt -system-llvm\n", )?; - std::fs::write(portage_dir.join("package.use/git"), "dev-vcs/git -iconv\n")?; + // -rust: needs rust-std for the target triple, which we don't cross-build. + std::fs::write( + portage_dir.join("package.use/git"), + "dev-vcs/git -iconv -rust\n", + )?; + // openmp wants a second gcc slot we don't have pinned; not worth it. + std::fs::write( + portage_dir.join("package.use/portage-utils"), + "app-portage/portage-utils -openmp\n\ + app-crypt/libb2 -openmp\n", + )?; if let Some(ref platforms) = board.grub_platforms { let flags: Vec = platforms @@ -798,48 +845,49 @@ const OVERLAY_SRC_IN_CONTAINER: &str = "/.overlay-src"; /// Overlay checkout inside the sandbox. const OVERLAY_DIR: &str = "/var/db/repos/crossdev-stages"; -/// Install the `crossdev-stages` portage overlay at the revision pinned in -/// `/overlay.conf` and write a repos.conf entry. -/// No-op when that file is absent or sets no `OVERLAY_REPO`. +/// Where a new checkout is staged before it replaces `OVERLAY_DIR`. +const OVERLAY_STAGE: &str = "/var/db/repos/.crossdev-stages.new"; + +/// Check out the overlay `repo` at `tag` inside the sandbox and write its +/// repos.conf entry. Not called directly: see [`Sandbox::install_overlay`]. /// /// The ebuilds live in their own repository, so this one carries no ebuilds -/// and no licenses but its own. `OVERLAY_REPO` may also name a local -/// clone, which is bind-mounted read-only and copied in; that is the route -/// for an overlay that is not published yet. -fn install_overlay( - runner: SandboxRunner, - sandbox: &Utf8Path, - defaults_root: &Utf8Path, -) -> Result<()> { - let conf = defaults_root.join("overlay.conf"); - let Some((repo, tag)) = read_overlay_conf(&conf)? else { - return Ok(()); - }; - tracing::info!("Installing crossdev-stages overlay from {repo} ({tag})…"); - +/// and no licenses but its own. `repo` may also name a local clone, which +/// is bind-mounted read-only and copied in; that is the route for an +/// overlay that is not published yet. +fn install_overlay(runner: SandboxRunner, sandbox: &Utf8Path, repo: &str, tag: &str) -> Result<()> { // /var/db/repos is created by portage inside the container, so it ends up // owned by a subordinate uid the host user cannot write to: every write // below goes through the container. + // + // The checkout is staged next to the overlay and swapped in only once it + // is complete, so a failure leaves the previous overlay and the + // repos.conf entry that points at it consistent with each other, never + // an empty directory portage is still told to read. runner.run(&format!( - "mkdir -p {OVERLAY_DIR} && find {OVERLAY_DIR} -mindepth 1 -delete" + "rm -rf {OVERLAY_STAGE} && mkdir -p {OVERLAY_STAGE}" ))?; - let local = Utf8Path::new(&repo); - if local.is_dir() { + let local = Utf8Path::new(repo); + let runner = if local.is_dir() { + let runner = runner.with_extra_ro(local, OVERLAY_SRC_IN_CONTAINER); + runner.run(&format!( + "cp -a {OVERLAY_SRC_IN_CONTAINER}/. {OVERLAY_STAGE}/" + ))?; runner - .with_extra_ro(local, OVERLAY_SRC_IN_CONTAINER) - .run(&format!( - "cp -a {OVERLAY_SRC_IN_CONTAINER}/. {OVERLAY_DIR}/" - ))?; } else { crate::source_cache::cached_clone( &runner, - &repo, - &tag, - OVERLAY_DIR, + repo, + tag, + OVERLAY_STAGE, "crossdev-stages-overlay", )?; - } + runner + }; + runner.run(&format!( + "rm -rf {OVERLAY_DIR} && mv {OVERLAY_STAGE} {OVERLAY_DIR}" + ))?; let repos_conf = sandbox.join("etc/portage/repos.conf"); fs::create_dir_all(&repos_conf)?; diff --git a/defaults/kernel-config/docker b/defaults/kernel-config/docker new file mode 100644 index 00000000..520585a1 --- /dev/null +++ b/defaults/kernel-config/docker @@ -0,0 +1,85 @@ +# Kernel config docker/containerd/runc need, from app-containers/docker's CONFIG_CHECK. + +# Namespaces. USER_NS is the only one not already on. +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_USER_NS=y + +# Cgroup controllers docker needs. +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_CPUSETS=y +CONFIG_MEMCG=y +CONFIG_BLK_CGROUP=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_NET_SCHED=y +CONFIG_NET_CLS_CGROUP=m +CONFIG_BPF_SYSCALL=y +CONFIG_CGROUP_BPF=y + +# Keyrings and /dev/mqueue for containers. +CONFIG_KEYS=y +CONFIG_POSIX_MQUEUE=y +# Seccomp profile support. +CONFIG_SECCOMP_FILTER=y + +# Bridge/veth/macvlan/vxlan for container networking. +CONFIG_VETH=m +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_VXLAN=m +CONFIG_MACVLAN=m +CONFIG_IPVLAN=m +CONFIG_DUMMY=m + +# Netfilter core, off by default. +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_NAT=m +CONFIG_BRIDGE_NETFILTER=m + +# Legacy iptables chain, required by the docker ebuild's CONFIG_CHECK. +CONFIG_NETFILTER_XTABLES_LEGACY=y +CONFIG_IP_NF_IPTABLES_LEGACY=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m + +# IPVS, for swarm-mode load balancing. +CONFIG_IP_VS=m +CONFIG_IP_VS_NFCT=y + +# IPsec for the encrypted overlay network driver. +CONFIG_XFRM_USER=m +CONFIG_INET_ESP=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=m + +# overlay2 storage driver. +CONFIG_OVERLAY_FS=m + +# ACL/security xattrs for ext4, which containers need. +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y diff --git a/defaults/target-packages.txt b/defaults/target-packages.txt index 06655c99..d35b6832 100644 --- a/defaults/target-packages.txt +++ b/defaults/target-packages.txt @@ -34,6 +34,5 @@ sys-block/parted dev-vcs/git net-analyzer/nmap -# Portage helpers (equery, genlop) +# Portage helpers. Not genlop: needs perl-5.44, conflicts with stage3's 5.42. app-portage/gentoolkit -app-portage/genlop