Tuesday, October 6, 2026

Using an LLM to Assist With Hardware Testing and Functionality

I recently picked up a Microsoft Surface Pro X ARM64 tablet, specifically the 16GB SQ2 (the second iteration of Microsoft's version of the Qualcomm 8cx Gen 2 ARM SoC. In my initial evaluation, I was impressed by the usual Surface qualities: the screen, the decent typing experience of the type cover without the weight of Apple's Magic Keyboard for the iPad. However, as many have noted, the ARM+Windows experience isn't the greatest. This is especially evident when trying to run power-hungry x86-64 applications.

I had checked on the state of support for the SQ2 version of the Pro X under Linux, and things mostly are functional, with a few sharp edges. Folks (especially the amazing @qzed) have put a  ton of effort into the development of the support drivers for this machine. The main blocker to this being usable as a daily driver machine is the lack of audio. Neither the speakers nor the built-in microphones work. At the level of annoying, rather than being a true blocker, is the sometimes problem of the eDP interface not syncing properly on boot, causing the display to remain black after the transition from the GRUB-initiated dumb framebuffer mode to the activation of the Qualcomm Adreno graphics. For some reason, I tend to hit this problem more often than some others seem to, but I just reboot until things sync properly.

I have been using LLMs as code assistance when writing Ansible playbooks for almost two years now, and I have found them to be genuinely helpful. So, given the success that others have had with having LLMs assist with emulator development, I thought that it would be worth the effort to try having Claude Sonnet (the mid-level option in Anthropic's LLM portfolio) work with me to try to create the devicetree support for the audio.

As it turned out, this was a good path to take. I did encounter a bug in the existing wcd934x sound CODEC, which has already been fixed upstream, but haven't made it to the linux-surface kernel yet. The start of the work was significantly sped up by another SPX user (@jiringgot) who commented that the underlying hardware in the Surface Pro X is somewhat similar to that in the Lenovo Flex 5g, in the open issue on sound support in the linux-surface/surface-pro-x repository. It turns out that the SPX is very similar to the Flex 5g. They use the same WCD9340 CODEC, hooked up to the same SLIMbus, with a very similar speaker and amp configuration. Given this, I started feeding data to Claude, and doing the requisite (and long, and repetitive) testing on my SPX. I also helped the LLM get past some internal inconsistencies with how it was seeing my data, but overall, Claude did the heavy lifting, and I did the testing and evaluation.

What we ended up with is this:

  • the speakers work
    • they are currently limited to 16bit audio @ 48kHz. 24bit samples come out silent, so WirePlumber forces 16 bit
    • there is no speaker protection, and so could be damaged by turning the levels up too high
    • the soundwire master and the amps can't currently suspend properly. there is a workaround udev rule that pins them on.
  • the mics work
    • there are 2 digital mics built into the SPX, and they are both powered from MIC BIAS1
  • there has been no effort to make USB-C headphones or displayport audio work. bluetooth audio has already been reported to work, but I haven't verified this.

The details of what has been created are below, after a more detailed description of the hardware.

The audio path is a Qualcomm WCD9340 codec on SLIMbus, two WSA881x-family speaker amplifiers on the codec's SoundWire master, and two digital microphones on the codec's DMIC0 and DMIC1 inputs. It closely follows the Lenovo Flex 5G devicetree in the Snapdragon 8cx Mainline repository, which the nodes below are modeled on.

PartWhat it isHow it was established
CodecWCD9340 ("Aqstic") on SLIMbus, address 217:250:1:0, SLIM controller at 0x171c0000Windows ACPI (the SLM1 device), the codec name in Windows' calibration database, and Linux enumerating it ("WCD934x chip id major 0x108, minor 0x1")
Audio DSPADSP booted from qcom/msft/surface/pro-x-sq2/qcadsp8180.mbnAlready booted by remoteproc before this work. APR/q6 audio services hang off its glink edge
Speaker ampsTwo WSA881x-family devices, SoundWire ID 0217:2110, unique IDs 3 and 4Windows driver config (two slaves, speaker-protection parameters) and Linux SoundWire enumeration
MicrophonesTwo digital mics on DMIC0 and DMIC1, both powered from MIC BIAS1Measured: only MIC BIAS1 makes either mic respond
Codec resetTLMM GPIO 143Windows ACPI
Codec interruptTLMM GPIO 123Copied from the Flex 5G; Windows lists the line as a pin that does not map to a TLMM number, but the interrupt count rises during playback
Codec clockRPMh LN_BB_CLK2Windows platform power table (BBCLK2) and the Flex 5G devicetree
Amp railLDO14 at 1.8 VWindows platform power table and the Flex 5G devicetree
Amp power-down and battery-rail pinsCodec GPIOs 1 and 2 (power-down), 4 (battery rail)Copied from the Flex 5G; they work, but were not independently confirmed

There are seven total changes needed to get things working. Five of them are devicetree patches, one is a new file (sc8180x-wcd9340.dtsi, taken from the 8cx-mainline repo), and one is a minor fix to an already upstream-fixed issue that hasn't made it to the linux-surface kernel tree yet.

  • 0000-arm64-dts-qcom-sc8180x-add-adsp-audio-and-slimbus.patch
    • adds the SLIMbus BAM and controller (slim-ngd@171c0000), the APR/q6 audio service nodes under the ADSP glink edge, and an empty sound node. Values come from the sc8180x-mainline fork and match the stream IDs in the Windows IORT table (0x1b46 and 0x1b21). The linux-surface tree's sc8180x.dtsi had none of these.
  • sc8180x-wcd9340.dtsi
    • copy this file from the sc8180x-mainline fork into arch/arm64/boot/dts/qcom/. It describes the codec under the SLIMbus controller, its SoundWire master with per-port parameters, its GPIO block, the interrupt (TLMM 123) and 1.8 V mic bias values. 
  • 0001-arm64-dts-qcom-sc8180x-surface-pro-x-add-audio-codec.patch
    • modifies the file sc8180x-surface-pro-x.dts which adds the q6 front-end DAIs, the codec properties (reset on TLMM 143, 1.8 V supply) and the sound card with its MultiMedia and SLIMbus links.
  • 0002-arm64-dts-qcom-sc8180x-surface-pro-x-add-speaker-amps.patch
    • defines the speakers, an LDO14 regulator at 1.8 V, a fixed regulator for the amplifier battery rail (codec GPIO 4), two SoundWire speaker nodes at addresses 0,3 and 0,4, and the routes from SPK1 OUT and SPK2 OUT. 
  • 0004-arm64-dts-qcom-sc8180x-surface-pro-x-use-sdm845-sndcard.patch
    • sets the sound system to bind to the sdm845 (the Snapdragon 845's sound card) since the sm8250 doesn't handle SLIMbus
  • 0005-arm64-dts-qcom-sc8180x-surface-pro-x-add-dmic-bias-route.patch
    • configures the two microphone routes to their single bias MIC BIAS1
  • 0008-ASoC-codecs-wcd934x-fix-typo-in-dt-parsing.patch
    • the aforementioned simple fix that can go away when linux-surface merges the fix described here that has already gone into the mainline kernel 

Once these patches are applied and the kernel rebuilt and installed, providing the updated module and the dtb, you will need to run the installer script install-surface-pro-x-audio-v6.sh, which will install the UCM profile, create the udev rules needed to avoid the suspend problem, and create the WirePlumber rules.

I am testing here on Arch, as that is where most of the work to create a running Surface Pro X has been directed, and a nice installation image creator has been published here. My patch to the existing linux-surface kernel PKGBUILD is this:

[ajacocks@surfaceprox aarch64-packages]$ diff -u linux-surface/PKGBUILD linux-surface-patched/PKGBUILD 
--- linux-surface/PKGBUILD    2026-10-04 01:59:33.926999697 -0400
+++ linux-surface-patched/PKGBUILD    2026-10-06 02:27:56.861225699 -0400
@@ -4,7 +4,7 @@
 
 pkgbase="linux-surface"
 pkgver="6.18.3"
-pkgrel="1"
+pkgrel="1.0002"
 
 _pkgdesc="Linux Surface"
 
@@ -22,12 +22,26 @@
     "surface.config::https://raw.githubusercontent.com/qzed/aarch64-kernel-configs/${_ref_config_surface}/fragments/spx.config"
     "overrides.config"
     "linux-surface.preset"
+    sc8180x-wcd9340.dtsi
+    0000-arm64-dts-qcom-sc8180x-add-adsp-audio-and-slimbus.patch
+    0001-arm64-dts-qcom-sc8180x-surface-pro-x-add-audio-codec.patch
+    0002-arm64-dts-qcom-sc8180x-surface-pro-x-add-speaker-amps.patch
+    0004-arm64-dts-qcom-sc8180x-surface-pro-x-use-sdm845-sndcard.patch
+    0005-arm64-dts-qcom-sc8180x-surface-pro-x-add-dmic-bias-route.patch
+    0008-ASoC-codecs-wcd934x-fix-typo-in-dt-parsing.patch
 )
 sha256sums=('548fb5c7b626e955af82c77ee6fdd9437f6a5383ac962f825d40b71186ebb3cb'
             '7224624cb815e7c4d989cea2d8c6abf25f02c280db66ce28e023e12cb177965f'
             '6769de357507321f4332b1bbd20f4e3fd4460790f2ef4728d49ab9e2634f085a'
             'f8041d666e2775b2e36d243708b0fae574914a0ce2a4e260c19127932f3d072e'
-            '93a04085e8cebbd5feab98482d764b515b30dd95945d33117d1cd27ffe03e3e7')
+            '93a04085e8cebbd5feab98482d764b515b30dd95945d33117d1cd27ffe03e3e7'
+            '1a468e0be9874dabd85e561809a006a79fa2eea3c7a74b8865d84d62c3c2ab14'
+            '7b1b92784ead83498a93653b76a9c7ae28d967c2f7b128a85b2af329e5aa6fd6'
+            '66ba391aee3ef39d2c61adc8d2fa403dd10e06a5f5926d543cc6d0aaf1d15ad4'
+            '39267677172f730aba56f842721027184fc2ac190d06e049a610a6d4bb314cd6'
+            '36c2e431f7fbd3a624defe3d83e2f83fcf2031b158622d9cf75f9107f1befc57'
+            '8938804b6d6a4f03a61b1accccd69e1d6f97e5413deac0704884a5bbf4defc39'
+            '62458c6ed87b19673b091516ba801ec98ab904fbfbb800b7970be831ece364f4')
 
 prepare() {
     cd "${srcdir}/kernel"
@@ -41,6 +55,24 @@
 
     msg2 "Configuring..."
     ./scripts/kconfig/merge_config.sh -m "${srcdir}/base.config" "${srcdir}/surface.config" "${srcdir}/overrides.config"
+
+    msg2 "Applying patches..."
+    for patchfile in \
+0000-arm64-dts-qcom-sc8180x-add-adsp-audio-and-slimbus.patch \
+0001-arm64-dts-qcom-sc8180x-surface-pro-x-add-audio-codec.patch \
+0004-arm64-dts-qcom-sc8180x-surface-pro-x-use-sdm845-sndcard.patch \
+0002-arm64-dts-qcom-sc8180x-surface-pro-x-add-speaker-amps.patch \
+0005-arm64-dts-qcom-sc8180x-surface-pro-x-add-dmic-bias-route.patch \
+0008-ASoC-codecs-wcd934x-fix-typo-in-dt-parsing.patch \
+; do
+        msg2 "  ${patchfile}"
+        patch -p1 < "${srcdir}/${patchfile}"
+    done
+
+    msg2 "Adding missing dtsi..."
+    cp "${srcdir}/sc8180x-wcd9340.dtsi" arch/arm64/boot/dts/qcom/
+        msg2 "  cp ${srcdir}/sc8180x-wcd9340.dtsi arch/arm64/boot/dts/qcom/"
+
     make olddefconfig
 }
 
@@ -59,7 +91,7 @@
     unset LDFLAGS
     unset CFLAGS
 
-    make all modules dtbs
+    make -j5 all modules dtbs
 }
 
 _package() {

The patches themselves are linked in the "Support for Audio Subsystem" issue #21 in the linux-surface/surface-pro-x repo. I'll create a fork of the https://github.com/linux-surface/aarch64-packages repo and submit the patches, though I don't know if they'll be acceptable or not.

I'm curious to hear what anyone who might read this thinks of this kind of AI assisted development. Definitely, the work wouldn't have been done by me without the work of Claude Sonnet, but Claude wouldn't have gotten anything done without my input, testing and evaluation, either. In the end, the patches to the devicetree are based on the work of Srinivas Kandagatla and the report by Joel Selvaraj and the existing archived 8cx mainline tree, but integrated by Claude. The PKGBUILD changes are mine. I have tested them pretty significantly on my own hardware, but of course, there's no guarantee that they will work on yours.

Saturday, August 30, 2025

Ayaneo Next Lite Stick Calibration, and Other Complaints

A few years ago, I bought my daughter an Ayaneo Next Lite, which is a low-end, but fairly well-made Windows handheld. She loves the device, and uses it a ton to play games, but it has a few issues that annoy me.

First, the machine is pretty darned slow for a device that was released in 2024, at least in the Ryzen 5 4500U version. I've used plenty of Ryzen 5 U-series APUs, and they're usually not particularly slow, so I'm going to chalk this up to thermal limitation. Additionally, the device's storage isn't fast at all. 

Next, the joysticks go out of calibration quite a bit. The fix for this one is fairly straight-forward, but it's not well documented, since very few articles or docs on Ayaneo's site reference the Next Lite, at all. The fix is this:

Press the Select and the A button at the same time for 2 seconds. It vibrates, swirl the joysticks around a couple of times, push RB and throttle 3 times down at the same time and it vibrates again.

That gets the sticks back in service.

Ayaneo also doesn't have a good site, at all. Knowledge is hard to find, and drivers are stored in various places, and it isn't easy to figure out what goes to what.

Oh well, the device was cheap, and my daughter likes it, so I guess that it serves the purpose. 

Wednesday, April 2, 2025

Custom Fonts for GRUB

Have you ever looked at the GRUB boot menu, and just felt bored? Or, more importantly, been completely unable to read it? I have been in both camps, and I finally got up enough motivation to figure out how to fix the problem.

As it turns out, the process is very simple. It's just not very well documented. Here's how to do it in Arch Linux, but the process is pretty similar in any other common distribution:

$ sudo pacman -S ttf-monofur-nerd  # or any other TTF font that you wish to use
$ sudo grub-mkfont -s 60 -o /boot/grub/fonts/monofur.pf2 /usr/share/fonts/TTF/MonofurNerdFont-Regular.ttf

This creates the proper format font file for GRUB, PFF2, which is a format that only GRUB uses.

After doing this, you can add the configuration line to /etc/default/grub, and then regenerate the GRUB configuration:

GRUB_FONT="/boot/grub/fonts/monofur.pf2"

Presto! 

As a side note, the "spleen" console font has a 32x64 console font, making life a lot more liveable for high-resolution console users.

Thursday, January 30, 2025

Immigration, Illegal Aliens, Dehumanization and Money

I'm going to again depart from the tech-focused nature of this blog to comment on an issue that was brought to my attention, on Tuesday, January 28th. Justin Keen, a Mississippi State representative introduced House Bill 1484, "AN ACT TO CREATE THE MISSISSIPPI ILLEGAL ALIEN CERTIFIED BOUNTY HUNTER PROGRAM...", on January 22nd, of this year. Here is an excerpt from the text of the proposed bill:

     (2)  A person commits the offense of trespass by an illegal alien if such person:  (a) Is an illegal alien; (b) Knowingly enters this state and remains in this state; and (c) Is physically present in this state at the time a licensed bounty hunter or a peace officer apprehends such person. 

     (3)  (a)  The offense of trespass by an illegal alien under this section is a felony for which the authorized term of imprisonment is life imprisonment without eligibility for probation, parole, conditional release, or release except by act of the Governor or the natural death of such person.

On the surface, this might seem like a simple attempt to assist police and immigration services in locating, detaining, and deporting unauthorized immigrants, but if you look at the history of such proposals, and laws, a much different picture appears.

This is not only an issue in Mississippi, or even only in the United States, but is world-wide. People and families subject to strife, famine, intolerance or abuse have often tried to migrate to a different place, where conditions might be more tolerable. You can probably look at your own family history and see ancestors who have done exactly that. For example, a significant part of my own family originated in Ireland. The Irish Potato Famine, and the reaction to it by the government of the United Kingdom, drove many to abandon everything that they owned, and large parts of their own family, and to attempt to immigrate to the United States. My wife is partially Cajun in ancestry, and the forced migration of Acadians (the original name of the Cajun population) is well documented. Outside my own family, many of my generation remember the Rwanda genocide of 1994, where as many as 2 million Rwandans fled their country to save their lives. The Arab Spring of pro-democracy protests, that began in 2010, also created a migrant crisis when governments cracked down on protest, causing a massive wave of migration to Europe and elsewhere. All of these migrants fled to somewhere other than where they were born, and when they arrived, they almost universally found themselves to be unwelcome, even though the decisions to leave their homelands were anything but voluntary.

Now that we understand why people migrate, let's take a look at something closer to home, from the history of the United States: fugitive slave laws and bounties. Until the end of slavery, in the United States, slaves who fled plantations where they were forced to live, work, and die, often in miserable and inhumane conditions, were considered fugitives from the law. The US congress passed the Fugitive Slave Act of 1793 which made it clear that these people were the property of their masters, and that protecting them was unlawful, and subject to penalty. In the wake of this, multiple states passed laws that paid bounties for the reporting and recapture of slaves, even in states that were ardently anti-slavery.

Last, let's take a look at the State of Mississippi, and how it profits from the labor of convicts. From Mississippi's own web site for the Mississippi State Penitentiary, you can read about the Mississippi Prison Industries Corp and the Mississippi Prison Agricultural Enterprises which provide convict labor to reduce the cost of incarceration. Mississippi also has a convict restitution system which requires people subject to court-ordered debt to work for minimal pay. You can also read about how disproportionately this system targets Black Americans. These systems directly emerged from the chain gang system that the state used to deal with its financial problems, starting after the Civil War.

With the perspective gained from reading some of the history that I have linked to in the three previous paragraphs, do you now see proposals, like Mississippi HB 1484, in a different light? Illegal aliens could be reported by citizens, who would then receive a bounty for their efforts. Once captured, these people would then be subject to life imprisonment, during which time they would likely be forced to labor for the government of Mississippi.

I cannot think of a more inhuman and evil way to treat people who are simply trying to escape the horrors of poverty, famine and violence.

Monday, October 14, 2024

Compiling Software that Uses the GNU Build System (autoconf, automake, etc.)

It used to be that almost all open-source software for Linux used the GNU build system. Anytime you saw that ubiquitous 'configure' script in your source code directory, you knew what you were in for. Recently, though, it seems that use of autoconf/automake/etc. has declined, and I'm seeing more use of cmake, ninja-build, and other newer tools.

Now, that doesn't mean that these tools have completely disappeared, like imake seems to have. And, because of this, it seems worthwhile to write up a quick guide on what to do, as a builder-of-software, when you see that 'configure.ac' file, in a source code repository. I'm not going to go into depth, here, so if you would like to read more, you can check out Gentoo Linux's excellent overview.

I'm going to use the diskfit tool as an example, since I ran across it, and went through the process, earlier today. When you clone the repository from GitHub, you see this collection of files:

$ git clone https://github.com/velnias75/diskfit.git
Cloning into 'diskfit'...
remote: Enumerating objects: 1647, done.
remote: Total 1647 (delta 0), reused 0 (delta 0), pack-reused 1647 (from 1)
Receiving objects: 100% (1647/1647), 340.88 KiB | 4.94 MiB/s, done.
Resolving deltas: 100% (1201/1201), done.
$ cd diskfit
$ ls -l
total 56
-rw-r--r--. 1 ajacocks ajacocks  3456 Oct 14 14:22 configure.ac
-rw-r--r--. 1 ajacocks ajacocks 35147 Oct 14 14:22 COPYING
-rw-r--r--. 1 ajacocks ajacocks   255 Oct 14 14:22 diskfit.bc.in
-rw-r--r--. 1 ajacocks ajacocks   140 Oct 14 14:22 diskfitrc
-rw-r--r--. 1 ajacocks ajacocks   484 Oct 14 14:22 Makefile.am
-rw-r--r--. 1 ajacocks ajacocks   826 Oct 14 14:22 README.md
drwxr-xr-x. 4 ajacocks ajacocks   103 Oct 14 14:22 src

You'll notice that there is a 'configure.ac' file, but not a 'configure' script. This means that we need to build it ourselves. The process is actually very easy, but it was a real pain to find a good explanation. I did finally find one, on stackoverflow, which explains the process very well. Just in case this disappears, I'll repeat it, here:

In an autoconf/automake/libtool project you need to run:

  • libtoolize: this copies/links a few support scripts, including ltmain.sh (which is the main component of libtool).
  • aclocal: this looks up all m4 macros that your configure script will need, and make a local copy for easier access.
  • autoheader: optional, if you want to use config.h/AC_CONFIG_HEADERS, otherwise all the test result macros will be inlined when you call the compiler.
  • autoconf: to expand all the macros used by configure.ac into the configure script.
  • automake: to convert all the Makefile.am into Makefile.in templates. You probably want to invoke this with --add-missing so additional support scripts can be linked/copied to your project (such as compile, missing, depcomp, test-driver, etc).

Don't worry about running each tool. Just invoke autoreconf -i and it'll run the tools that are needed. Add -v if you want to see what tools is being executed. To avoid mistakes, just put a script like this at the root of your project:

#!/bin/bash -x
mkdir -p m4
exec autoreconf --install "$@"

Users that checkout/clone the project directly from the source repository will need to run this ./bootstrap script at least once. This is not needed if the user got a tarball distribution.

Automake can take fairly good care of itself; it'll re-invoke the above tools when needed, when you run make. But if you generate a broken Makefile, you'll need to invoke ./bootstrap and ./configure again to generate new Makefiles.

This is a far better explanation than I could have given. Thanks, DanielKO!

To continue our build process, we just need to do what DanielKO said in his snippet:

$ mkdir -p m4
$ autoreconf --install
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltoptions.m4'
libtoolize: copying file 'm4/ltsugar.m4'
libtoolize: copying file 'm4/ltversion.m4'
libtoolize: copying file 'm4/lt~obsolete.m4'
configure.ac:19: warning: The macro `AC_PROG_CC_C99' is obsolete.
configure.ac:19: You should run autoupdate.
./lib/autoconf/c.m4:1659: AC_PROG_CC_C99 is expanded from...
configure.ac:19: the top level
configure.ac:103: warning: AC_OUTPUT should be used without arguments.
configure.ac:103: You should run autoupdate.
configure.ac:9: installing './compile'
configure.ac:9: installing './config.guess'
configure.ac:9: installing './config.sub'
configure.ac:10: installing './install-sh'
configure.ac:10: installing './missing'
src/Makefile.am: installing './depcomp'

You will now see that 'autoreconf' has created a number of new files, in particular the 'configure' script that we will need to build the program: 

$ ls -l
total 1132
-rw-r--r--. 1 ajacocks ajacocks  70520 Oct 14 14:37 aclocal.m4
drwxr-xr-x. 2 ajacocks ajacocks    150 Oct 14 14:37 autom4te.cache
-rwxr-xr-x. 1 ajacocks ajacocks   7400 Oct 14 14:37 compile
-rwxr-xr-x. 1 ajacocks ajacocks  49939 Oct 14 14:37 config.guess
-rw-r--r--. 1 ajacocks ajacocks   4070 Oct 14 14:37 config.h.in
-rwxr-xr-x. 1 ajacocks ajacocks  35796 Oct 14 14:37 config.sub
-rwxr-xr-x. 1 ajacocks ajacocks 506842 Oct 14 14:37 configure
-rw-r--r--. 1 ajacocks ajacocks   3456 Oct 14 14:22 configure.ac
-rw-r--r--. 1 ajacocks ajacocks  35147 Oct 14 14:22 COPYING
-rwxr-xr-x. 1 ajacocks ajacocks  23568 Oct 14 14:37 depcomp
-rw-r--r--. 1 ajacocks ajacocks    255 Oct 14 14:22 diskfit.bc.in
-rw-r--r--. 1 ajacocks ajacocks    140 Oct 14 14:22 diskfitrc
-rwxr-xr-x. 1 ajacocks ajacocks  15358 Oct 14 14:37 install-sh
-rw-r--r--. 1 ajacocks ajacocks 332808 Oct 14 14:37 ltmain.sh
drwxr-xr-x. 2 ajacocks ajacocks    104 Oct 14 14:37 m4
-rw-r--r--. 1 ajacocks ajacocks    484 Oct 14 14:22 Makefile.am
-rw-r--r--. 1 ajacocks ajacocks  31261 Oct 14 14:37 Makefile.in
-rwxr-xr-x. 1 ajacocks ajacocks   6878 Oct 14 14:37 missing
-rw-r--r--. 1 ajacocks ajacocks    826 Oct 14 14:22 README.md
drwxr-xr-x. 4 ajacocks ajacocks    122 Oct 14 14:37 src

Now that we have what we need, we can execute 'configure' to build the Makefiles needed to successfully compile 'diskfit':

$ ./configure --prefix=/opt/diskfit
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for gcc... gcc
(trimmed for brevity)
config.status: creating src/python/qdiskfit/util/Makefile
config.status: creating config.h
config.status: executing libtool commands
config.status: executing depfiles commands

And now, we compile:

$ make
make  all-recursive
make[1]: Entering directory '/home/ajacocks/src/diskfit'
Making all in src
make[2]: Entering directory '/home/ajacocks/src/diskfit/src'
Making all in lib
make[3]: Entering directory '/home/ajacocks/src/diskfit/src/lib'
/bin/sh ../../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../..  -DHAVE_INLINE -DGSL_C99_INLINE  -fvisibility=hidden -ffast-math -fstrict-aliasing  -finline-functions -g -O2 -MT libdiskfit_la-libdiskfit.lo -MD -MP -MF .deps/libdiskfit_la-libdiskfit.Tpo -c -o libdiskfit_la-libdiskfit.lo `test -f 'libdiskfit.c' || echo './'`libdiskfit.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../.. -DHAVE_INLINE -DGSL_C99_INLINE -fvisibility=hidden -ffast-math -fstrict-aliasing -finline-functions -g -O2 -MT libdiskfit_la-libdiskfit.lo -MD -MP -MF .deps/libdiskfit_la-libdiskfit.Tpo -c libdiskfit.c  -fPIC -DPIC -o .libs/libdiskfit_la-libdiskfit.o
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../.. -DHAVE_INLINE -DGSL_C99_INLINE -fvisibility=hidden -ffast-math -fstrict-aliasing -finline-functions -g -O2 -MT libdiskfit_la-libdiskfit.lo -MD -MP -MF .deps/libdiskfit_la-libdiskfit.Tpo -c libdiskfit.c -o libdiskfit_la-libdiskfit.o >/dev/null 2>&1
(trimmed for brevity)
/usr/bin/sed -e 's|@bindir[@]|/opt/diskfit/bin|g' < diskfit.bc.in > diskfit
make[2]: Leaving directory '/home/ajacocks/src/diskfit'
make[1]: Leaving directory '/home/ajacocks/src/diskfit'

And now, we install:

$ sudo make install
Making install in src
make[1]: Entering directory '/home/ajacocks/src/diskfit/src'
Making install in lib
make[2]: Entering directory '/home/ajacocks/src/diskfit/src/lib'
make[3]: Entering directory '/home/ajacocks/src/diskfit/src/lib'
 /usr/bin/mkdir -p '/opt/diskfit/lib'
 /bin/sh ../../libtool   --mode=install /usr/bin/install -c   libdiskfit.la '/opt/diskfit/lib'
(trimmed for brevity)

 /usr/bin/install -c -m 644 README.md '/opt/diskfit/share/doc/diskfit'
make[2]: Leaving directory '/home/ajacocks/src/diskfit'
make[1]: Leaving directory '/home/ajacocks/src/diskfit'

The results:

$ tree /opt/diskfit
/opt/diskfit
├── bin
│   └── diskfit
├── etc
│   └── diskfitrc
├── include
│   └── diskfit
│       └── diskfit.h
├── lib
│   ├── libdiskfit.a
│   ├── libdiskfit.la
│   ├── libdiskfit.so -> libdiskfit.so.1.0.2
│   ├── libdiskfit.so.1 -> libdiskfit.so.1.0.2
│   └── libdiskfit.so.1.0.2
└── share
    ├── doc
    │   └── diskfit
    │       └── README.md
    └── man
        └── man1
            └── diskfit.1

11 directories, 10 files

I hope that this helps someone, or in all honestly, me. This is something that I've had to research every time that I have done it, since I don't do it often, and my memory isn't all that good.

Monday, September 30, 2024

PowerDNS and MariaDB (MySQL) Replication - What do you do when things get out of whack?

I use PowerDNS to manage my fairly extensive home lab environment's DNS. Because DNS is needed for not only the lab, but also so that my wife and daughter can watch TV or to use any other 'net-based resource, keeping things up and running is critical. Because of that, I have 3 seperate DNS servers, linked via MariaDB replication. Generally, this has been very reliable, and the configuration is much simpler than my previous setup, which used PowerDNS replication.

However, a couple of times, now, things have gotten out of sync. And, because it happens very rarely, I always forget how to get things resynced. Lucky me, though, user David Espart posted an excellent step-by-step process for getting things going again, here.

I'll repeat the steps below, in case Stack Overflow ever goes away or loses the content:

This is the full step-by-step procedure to resync a master-slave replication from scratch:

At the master:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;


And copy the values of the result of the last command somewhere.

Without closing the connection to the client (because it would release the read lock) issue the command to get a dump of the master:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

Now you can release the lock, even if the dump hasn't ended yet. To do it, perform the following command in the MySQL client:

UNLOCK TABLES;


Now copy the dump file to the slave using scp or your preferred tool.

At the slave:

Open a connection to mysql and type:

STOP SLAVE;

Load master's data dump with this console command:

mysql -uroot -p < mysqldump.sql

Sync slave and master logs:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;


Where the values of the above fields are the ones you copied before.

Finally, type:

START SLAVE;

To check that everything is working again, after typing:

SHOW SLAVE STATUS;

you should see:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes


That's it!

Hope this helps someone, some day, or just jogs my own failing memory.

Monday, September 2, 2024

The Plague of Education Debt

Today, I responded to a Facebook comment that complained about the difficulty of repaying graduate school education debt. The original poster and spouse apparently left graduate school in 2001-2002 with a total of ~$70,000 in debt. After paying $500/mo for the past 23 years, they are still $60,000 in debt.

Many would argue that $500/mo is too small of a monthly payment amount, but given average salaries after graduate school completion, it could well be all the couple could afford.

The original poster asked why education debt should not be cancelled. The responses were predictable, and varied from the sympathetic to those who thought that the borrowers had erred, and must therefore suffer the consequences, to those who commented that cancelling education debt directly adds to taxpayer burden.

Why assume that taxpayers have to foot the bill?

This is clearly (given the high interest rate) a private student loan. Loan cancellation would only affect the private lender, and since the principal amount has been paid, and then almost paid again, they have been adequately compensated. No need for a treasury outlay, just cancel the loan.

I’m sure that someone will call me “communist” or “socialist,” for this view, but I know exactly how the private lending system works. Loans are offered to young people with little experience in borrowing who are hoping that their education will lead to higher lifetime earnings, as we always tell young people. The terms are often unclear, and the interest rates border on the extortionate.

These loans have variable interest rates, and all kinds of fees and penalties, and can leave borrowers in terrible situations, with virtually no way out, since private loans are almost always not discharged in bankruptcy. (see https://scholarlycommons.law.emory.edu/ebdj/vol32/iss1/11/)

I also did not borrow much money to go to college, but the fact that I did not led me to have to both work full time and to attend college at the same time, which helped to cause me to drop out in my 5th year, as a senior. There were indeed other factors involved, including my own errors, but money was a huge concern.

If I had been offered some large private loan, I surely would have taken it, as an inexperienced young person. I am only protected from that by my age, since the cost of education in compared to average salary was much lower in the 1990s.

The rising cost of education, and the flood of high-interest private education loans are a direct threat to the future of this country. We already live in a world where it is not a good financial prospect to go to medical school and become a general practitioner. (see https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4226775/)

Given that the need for education is greater each year, since there are fewer and fewer jobs that do not require a college degree, and the complexity of the world continues to rise, why do we, as a nation, feel that it is in our best interest to place the burden of education financing on the student, who is least well equipped both to understand it, and to pay it off?