io-uring 0.7.12

The low-level `io_uring` userspace interface for Rust
Documentation
name: Kernel Version Test

on:
  workflow_call:
    inputs:
      kernel_version:
        description: 'Version of the Linux kernel to build'
        required: true
        type: string

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      KERNEL_VERSION: ${{ inputs.kernel_version }}
    steps:
      - uses: actions/checkout@v4

      - name: Install system dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            bison flex libelf-dev \
            qemu-system-x86 busybox-static cpio xz-utils wget e2fsprogs

      - name: Create ext4 test disk
        run: |
          dd if=/dev/zero of=disk.img bs=1M count=64
          mkfs.ext4 -F disk.img

      - name: Cache Linux source
        id: cache-kernel
        uses: actions/cache@v4
        with:
          path: linux-${{ env.KERNEL_VERSION }}
          key: kernel-${{ env.KERNEL_VERSION }}

      - name: Download & build Linux kernel
        if: steps.cache-kernel.outputs.cache-hit != 'true'
        run: |
          MAJOR=${KERNEL_VERSION%%.*}
          wget https://cdn.kernel.org/pub/linux/kernel/v${MAJOR}.x/linux-${KERNEL_VERSION}.tar.xz
          tar xf linux-${KERNEL_VERSION}.tar.xz
          cd linux-${KERNEL_VERSION}

          # Generate the default config
          make defconfig

          # Enable essentials as built-ins
          scripts/config --enable CONFIG_DEVTMPFS
          scripts/config --enable CONFIG_DEVTMPFS_MOUNT

          # Enable virtio drivers, which is used by QEMU
          scripts/config --enable CONFIG_VIRTIO
          scripts/config --enable CONFIG_VIRTIO_PCI
          scripts/config --enable CONFIG_VIRTIO_BLK

          # Enable ext4 filesystem, as some tests require O_DIRECT operations
          scripts/config --enable CONFIG_EXT4_FS

          # Generate the updated config
          make olddefconfig

          make -j$(nproc)

      - name: Generate the test binary
        run: |
          rustup target add x86_64-unknown-linux-musl
          cargo build --package io-uring-test --features io-uring-test/ci --release --target x86_64-unknown-linux-musl

      - name: Prepare initramfs + tests binaries
        run: |
          rm -rf initramfs && mkdir -p initramfs/{bin,sbin,proc,sys,tmp}

          # Copy the test binary
          cp target/x86_64-unknown-linux-musl/release/io-uring-test initramfs/bin/

          # Add necessary binaries from busybox
          cp /usr/bin/busybox initramfs/bin/
          for cmd in sh mount ip ifconfig cat; do ln -sf busybox initramfs/bin/$cmd; done
          ln -sf ../bin/busybox initramfs/sbin/poweroff

          # Generate init script
          cat > initramfs/init << 'EOF'
          #!/bin/sh
          set -e

          # Activating the loopback interface (it's required for some network tests)
          ip link set lo up

          mkdir -p /dev

          # Enable necessary devices
          # https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
          mknod /dev/port c 1 4
          mknod /dev/null c 1 3
          mknod /dev/zero c 1 5
          mknod /dev/tty c 5 0

          mkdir -p /tmp && mount -t tmpfs -o mode=1777 tmpfs /tmp

          # Bring up ext4 test volume at /mnt
          mount -t devtmpfs devtmpfs /dev
          mkdir -p /mnt
          mount -t ext4 /dev/vda /mnt

          # Run tests from a filesystem that supports O_DIRECT
          cd /mnt

          exit_code=0

          # Run the test binary
          RUST_BACKTRACE=1 /bin/io-uring-test || exit_code=1

          # If the test binary exited with a non-zero code, write it to /dev/port.
          # This lets QEMU exit with non-zero exit-code, triggering a CI error.
          [ $exit_code -eq 0 ] || printf '\x01' \
            | dd of=/dev/port bs=1 seek=244 count=1 2>/dev/null

          /sbin/poweroff -f

          EOF

          chmod +x initramfs/init

          # Pack into a CPIO archive
          (cd initramfs && find . -print0 \
            | cpio --null -ov --format=newc | gzip -9 > ../initramfs.cpio.gz)

      - name: Run tests in QEMU
        run: |
          qemu-system-x86_64 \
            -device isa-debug-exit,iobase=0xf4,iosize=0x04 \
            -kernel linux-${{ env.KERNEL_VERSION }}/arch/x86/boot/bzImage \
            -initrd initramfs.cpio.gz \
            -drive if=virtio,format=raw,file=disk.img \
            -netdev user,id=net0 \
            -device e1000,netdev=net0 \
            -append "console=ttyS0 rootfstype=ramfs panic=1" \
            -nographic -no-reboot -m 1024 -action panic=exit-failure

          if [ $? -ne 0 ]; then
            echo "tests failed (QEMU exited abnormally)"
            exit 1
          else
            echo "all tests passed"
          fi