Newsletter
TechAnV Blog
Get updates on security engineering, Rust, eBPF, and DevSecOps. No spam, unsubscribe anytime.
Check your inbox and click the confirmation link to complete your subscription.
Emulating a big-endian s390x with QEMU#
I got a bug report concerning my sqlite-fts4 project running on PPC64 and s390x architectures.
The s390x is an IBM mainframe architecture, which I found glamorous!
The bug related to those machines being big-endian v.s. my software being tested on little-endian machines. My first attempt at fixing it (see this TIL) turned out not to be correct. I really needed a way to test against an emulated s390x machine with big-endian byte order.
I figured out how to do that using Docker for Mac and QEMU.
multiarch/qemu-user-static #
This is the first command to run. It does something magical to your Docker installation:
1docker run --rm --privileged multiarch/qemu-user-static:register --resetThe qemu-user-static README says:
multiarch/qemu-user-staticandmultiarch/qemu-user-static:registerimages execute the register script that registers below kind of/proc/sys/fs/binfmt_misc/qemu-$archfiles for all supported processors except the current one in it when running the container.
It continues:
The
--resetoption is implemented at the register script that executes find/proc/sys/fs/binfmt_misc -type f -name 'qemu-*' -exec sh -c 'echo -1 > {}' \;to removebinfmt_miscentry files before register the entry.
I don’t understand what this means. But running this command was essential for the next command to work.
multiarch/ubuntu-core #
Having run that command, the following command drops you into a shell in an emulated s390x machine running Ubuntu Focal:
1docker run -it multiarch/ubuntu-core:s390x-focal /bin/bashUsing -focal gives you Python 3.8. I previously tried s390x-bionic but that gave me Python 3.6.
You don’t actually get Python until you install it, like so:
1apt-get -y update && apt-get -y install python3This will take a while. I think it’s slower because the hardware is being emulated.
Now you can check the Python version and confirm that the byte order is big-endian like this:
1root@ea63e288ce49:/# python3 --version2Python 3.8.103root@ea63e288ce49:/# python3 -c 'import sys; print(sys.byteorder)'4bigDoing this in GitHub Actions#
I figured out the following recipe for running this in GitHub Actions.
In this example I’m cloning my sqlite-fts4 repo and running the tests in it as well:
1name: QEMU to run s390x-focal2
3on:4 push:5 workflow_dispatch:6
7jobs:8 one:9 runs-on: ubuntu-latest10 steps:11 - name: Setup multiarch/qemu-user-static12 run: |13 docker run --rm --privileged multiarch/qemu-user-static:register --reset14 - name: ubuntu-core:s390x-focal15 uses: docker://multiarch/ubuntu-core:s390x-focal16 with:17 args: >18 bash -c19 "uname -a &&20 lscpu | grep Endian &&21 apt-get -y update &&22 apt-get -y install python3 git python3.8-venv &&23 python3 --version &&24 python3 -c 'import sys; print(sys.byteorder)' &&25 git clone https://github.com/simonw/sqlite-fts4 &&26 cd sqlite-fts4 &&27 python3 -m venv venv &&28 source venv/bin/activate &&29 pip install -e '.[test]' &&30 pytest31 "