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/hostecho 'share /mnt/host virtiofs rw,nofail 0 0' >> /etc/fstabrm -rf /home/$USERln -s /mnt/host/$USER /home/$USERFixing 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/buildln -s /var/tmp/bitbake/build ~/src/openbmc/openbmc/buildmeson actually works under bitbakeAttempting 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-userecho 'vm.mmap_min_addr = 65536' > /etc/sysctl.d/qemu-arm.confsystemctl rebootVarious 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 --recursivegit submodule update --recursivednf builddep qemuGithub 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 falsetimedatectl set-time 22:09timedatectl set-ntp trueWith 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: