Software development notes
by Andrew
I’ve had an M1 MacBook Pro Max lying beside me for some time now, waiting for me to find a good workflow and migrate onto it.
As it turns out, sandbagging on migrating for 6 months or so turned out to be a bit of a blessing. The software ecosystem evolved quite a bit from when I first tried to figure out how I wanted to work with it. Until now I’ve been running Linux on various Lenovo Thinkpads and so I wanted a workflow with similar properties. I want to use Linux, but am constrained to continuing to run macOS, so that rules out e.g. Asahi.
However, we can run Linux under a hypervisor, and with that I had the following goals:
Critical data in this case is essentially my $HOME
from my Linux laptop. I
want to keep the point of coherency on the host so I don’t accidentally wipe the
critical data out by mindlessly blowing away a VM disk image. Essentially, the
VM itself shouldn’t be special. Further, I’d like that $HOME
data copied from
my Thinkpad(s) to serve as my $HOME
in the Linux guest.
To continue performing secondary activities under macOS, I plan to use
terminal.app
and just ssh
into the guest. This keeps all the copy/paste and
click semantics working without too much hassle.
Previously I’d cooked up some horrific combination of QEMU,
vde_vmnet for network bridging, and 9pfs for directory sharing
betwen the host and the guest. There were many things that were wrong with this.
Hooking QEMU up to vde_vmnet
avoids the need to run QEMU as root for bridge
networking, but externalises the network from the QEMU process. This appeared to
cause some throughput issues. The throughput issues were compounded by fs-cache
bugs for 9pfs in the guest Ubuntu kernel, which
meant I had to rebuild the guest kernel to disable fs-cache. Further, it turned
out that QEMU had 9pfs issues all of its own.
To get there this time around I’ve used:
I’ve created a guest with the following configuration and resources:
With that, I did a stock install of Fedora 37.
With Fedora 37 installed in the guest I needed a few tricks to get things working as I desired.
$HOME
onto the case-sensitive volumemkdir /mnt/host
echo 'share /mnt/host virtiofs rw,nofail 0 0' >> /etc/fstab
rm -rf /home/$USER
ln -s /mnt/host/$USER /home/$USER
Fixing this is a double win as we can keep the build artifacts inside the guest and save on some overhead out to the host.
mkdir -p /var/tmp/bitbake/build
ln -s /var/tmp/bitbake/build ~/src/openbmc/openbmc/build
meson
actually works under bitbake
Attempting to build OpenBMC in the guest eventually lead to meson
complaining
that the executables created by cross-compilers weren’t runnable. On the surface
this seems fair, but due to ✨implementation details✨ of the meson
support
in Poky, running cross-built binaries on the build machine is
necessary.
Once I eventually dug through all the bitbake
and meson
logs to find out
what was actually being invoked, it turned out qemu-arm
was producing the
following error:
qemu-arm: Unable to reserve 0xffff0000 bytes of virtual
address space at 0x8000 (Success) for use as guest address
space (check your virtual memory ulimit setting,
min_mmap_addr or reserve less using -R option)
In the process of tracking this down I ended up sending a couple of minor patches to qemu. Anyway, the issue was largely solved by:
sudo dnf install qemu-user
echo 'vm.mmap_min_addr = 65536' > /etc/sysctl.d/qemu-arm.conf
systemctl reboot
Various things went wrong in silly ways. As a bit of a record:
I hadn’t done any upstream development in recent times and submodules had come, gone and shifted around:
git submodule sync --recursive
git submodule update --recursive
dnf builddep qemu
Github managed to publish their private SSH RSA host key
right around the time I started this migration, so that needed fixing in my
~/.ssh/known_hosts
.
Not sure what happened here, but I managed to freeze the VM several times and this may have contributed to the issue. The freezing seemed to begin after allocating 32GiB of memory to the VM, which is the entirety of the host RAM. It’s been stable since I reduced that to 16GiB.
timedatectl set-ntp false
timedatectl set-time 22:09
timedatectl set-ntp true
With all this configured I found I could build a full OpenBMC image in the guest in a bit over an hour, from cold caches. Taking that straight to the bank!
tags: