Posts in Linux (20 found)
./techtipsy 1 weeks ago

You can run Forza Horizon 6 on an unsupported AMD RX 400/500 series GPU on SteamOS

This post serves as a personal bookmark and a mirror of this fantastic guide by Ok-Pace-1900 on /r/linux_gaming to ensure that this information does not get lost. I learned the hard way that the GPU I have in a DIY Steam Machine PC, the AMD RX 480, is strictly unsupported by Forza Horizon 6. Forza Horizon 6 will not work for AMD users with GPUs based on the Polaris or Vega architectures and older (for example Radeon 400 and 500 series players). These architectures are below our minimum supported specification. I knew that asking for a refund on Steam would be the easy way out. Deciding against it, I did a quick search for the FH201 error code and stumbled on the Reddit post mentioned above. My CPU is good enough for Forza Horizon 6 (Intel i5-10500), so the additional launch options command that worked for me is the following: Simple fix, but the context around this is actually kind of funny. The way a lot of Windows-only games work on SteamOS is via a translation layer referred to as Proton. With this trick, you can pretend that your GPU has some DirectX features that it actually does not have, but it doesn’t matter since it can be successfully emulated via translation to Vulkan, which the GPU supports well! As a result, I can play Forza Horizon 6 on a hacky SteamOS build, with 1080p low or medium settings. Low settings is a 60 FPS experience, with medium settings some areas like Tokyo can struggle a bit and drop below it to ~40 FPS. Now all I need to do is to get rid of the urge to splurge on a great GPU, which would also require a case and PSU upgrade… Slightly off-topic, but can you monitor your gaming PC via Prometheus Node Exporter and visualize it in Grafana? :)

0 views

Installing JPilot on Arch

This post is a quick tip for anyone else running into issues installing the Palm Pilot desktop software, JPilot on Arch Linux. If you just try installing via , the build will fail as the dependency no longer builds on modern systems. The solution is to first install , then .

0 views
David Bushell 3 weeks ago

Unscrewing lightbulbs

Giving lightbulbs a MAC address was a mistake that I’m living with. I’m literally unscrewing lightbulbs to renew their DHCP lease @dbushell.com - Bluesky Instead of enjoying the bank holiday Monday I updated my homelab software. I was ‘inspired’ by the Copy Fail Linux bug to run full distro upgrades. This is my self-hosted update for Spring 2026 (rough documentation to give future me a chance). Monday’s fun risked a week of pain. I do have backups but restoring them on a broken LAN is tricky. I have an ISP provided wifi router to dust off in an emergency. Along with an absurdly long 15 metre HDMI cable I do not care to unravel. My winter update added a hardware fallback but that too requires careful rejigging. I have Proxmox hosts, virtual machines, and Raspberry DietPis . They were all on Debian 12 (Bookworm) with a kernel potentially susceptible to the bug. Minimal Debian installs are perfect because I run everything in Docker anyway. Data volumes are easy to backup or network mount. I can change host at will for any service. Debian is just sensible, well documented no-fuss Linux. I used to run “minimal” Ubuntu server. Following 24.04 I found myself debloating most of the Ubuntu part (i.e. snaps). It sounds like the new coreutils are a CVE party . Glad I escaped before that drama! As it happens, this week’s Linux Unplugged episode had Canonical’s VP of Engineering spewing embarrassing AI platitudes. “Ubuntu is not for you” was the only thing said worth remembering. I updated most of my VMs first because they’re easy to restore if anything fails. I followed Lubos Rendek’s guide . Start with a full package update and then change the package sources before running another step-by-step upgrade. The only non-Debian sources I have are Docker and Tailscale. Yes that means I run Docker inside Proxmox VMs — and you can’t stop me! That’s not even my worse crime… After the Trixie upgrade I found VMs were failing to obtain a LAN IP address. The virtual network device had been renamed from to . I edited and just changed the reference. There is surely a better/more predictable fix but this was the quickest. The same name was used across all VMs so I guess 18 is the magic number. Everything has been stable so far. If issues arise I’ll just nuke and pave from a Debian 13 ISO. Docker config and volumes are backed up independently of the VM images. DietPi has a long Trixie upgrade post I didn’t read. I just curled to bash: I gave the script a cursory glance before hitting enter. I have a Pi 4 running failover DNS and a Pi 5 running my public Forgejo instance . DietPi is ideal because of the tiny footprint; I run Docker here too. Raspberry Pi still hasn’t merged upstream Copy Fail fixes. I’m already in trouble if this bug can be exploited but I did the temporary fix out of caution. I wasn’t going to bother with Proxmox 9 but after a GUI update I was informed version 8 “end of life” was August 2026 . That is soon! I followed the official upgrade guide on my Mini-ITX server . Proxmox has a tool to check compatibility. I saw no red lights so I stopped all VMs, updated package sources to Trixie, and ran the upgrade. It is critical to run again before rebooting. I ran into the systemd-boot issue . Apparently if this is not removed the system fails to boot. If my particular box fails to boot I’m in big trouble because I broke video output and have yet to fix it. I have another Proxmox machine running virtualised OPNsense for my home router. I can’t stop the OPNsense VM and upgrade the host to Proxmox 9 because the host would have no network access. I had two options: I specifically set up option 1 for such a purpose. I went with option 2. I figured any software running in memory is still alive until I reboot, right? I didn’t question whether Proxmox would kill any processes itself (it didn’t). The update was suspiciously fast. I ran again and saw a lot of yellow warnings. Yikes. Eventually I noticed I’d failed to update some sources to Trixie and I’d installed a franken-distro. After fixing mistakes all I could do was reboot and pray for an agonising two minutes. OPNsense is the only non-Debian operating system in my homelab. I manage it entirely via the web GUI. The 26.1 update had quite a few significant changes. My DHCP setup was considered “legacy” and my firewall rules required a manual migration. Despite dumbening my smart home my lightbulbs still demand a WiFi connection. I program them myself to avoid Home Assistant and proprietary apps. Turns out I hard-coded IP addresses (discovery protocols are a joke.) Despite having dynamic IPs they remained stable until the OPNsense 26.1 DHCP update. I had no easy way to identify each light. Why would they name themselves anything useful? That’s how I ended up unscrewing the bulbs one by one to see which MAC address fell off the network. I gave them static IPs on a VLAN for future me to appreciate. And with that, my home network is up to date! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Use my failover VM YOLO it live

0 views
The Coder Cafe 1 months ago

How Linux 7.0 Broke PostgreSQL

☕ Welcome to The Coder Cafe! On April 3, 2026, Salvatore Dipietro, an engineer at AWS, posted a patch to the Linux kernel mailing list. The reason: on a 96-vCPU Graviton4 machine running Linux 7.0, PostgreSQL throughput had dropped to roughly half of what it produced on Linux 6.x. In this post, we will trace what changed in Linux 7.0, how PostgreSQL manages memory, and what role memory pages play in making the problem appear (or disappear). Get cozy, grab a coffee, and let’s begin! The Problem Salvatore Dipietro ran pgbench (PostgreSQL’s standard benchmarking tool) on a Graviton4 processor with 96 vCPUs. The workload was a benchmark doing simple updates at scale factor 8,470 (i.e., roughly a 847 million row table), simulating 1,024 clients and 96 threads. A serious, high-parallelism load designed to stress the system. The results were striking. Linux 7.0 delivered roughly half the throughput of Linux 6.x on the same hardware and workload: Linux 6.x : 98,565 transactions per second Linux 7.0 : 50,751 transactions per second To find where the time was going, Dipietro ran , a Linux profiling tool that samples what the CPU is actually doing. The result was unambiguous: 55% of the machine’s CPU time was spent inside a single function: . The culprit was traced back to a change in how Linux 7.0 schedules processes. Let’s start there. When multiple threads run on a machine, the OS needs to share the CPU between them. That’s the scheduler’s job. But the scheduler also decides something subtler: when to interrupt a running thread and hand the CPU to another. That decision is called preemption , and the answer varies depending on how the kernel is configured. Before Linux 7.0, there were three options: : The kernel almost never interrupts a running thread. A thread runs until it voluntarily gives up the CPU: when it makes a syscall, blocks on I/O, or explicitly sleeps. This was the traditional server default with fewer context switches, higher throughput, and predictable behavior under load. : The kernel can interrupt a running thread at almost any safe point, even if it is in the middle of doing useful work. This means a thread never has to wait for the current one to finish its slice before getting CPU time, which reduces response time but increases context-switch overhead. Historically, the desktop default, where responsiveness matters more than raw throughput. : Introduced in Linux 6.12 as a compromise between the two. The scheduler can interrupt threads, but tries to wait for natural boundaries rather than cutting in aggressively. The intent is to approximate ‘s throughput behavior while still allowing preemption when needed. In Linux 7.0, was removed as an option on modern CPU architectures, leaving only and . Indeed, was designed to be a drop-in replacement on throughput workloads, and for the vast majority of server software, it is. But PostgreSQL hit a specific case where the difference is catastrophic, and to understand why, we need to look at how PostgreSQL manages memory. PostgreSQL, like most databases, doesn’t store data as rows in a flat file. Instead, it uses a fixed-size abstraction called a data page (8 KB by default) as its basic unit of storage. Everything on disk (e.g., table rows, B-tree index nodes, metadata) is stored in these pages. A table with millions of rows is ultimately a large sequence of data pages on disk. Reading from disk is slow. So PostgreSQL maintains a shared buffer pool , a large region of shared memory that caches recently read data pages . The more of the working set that fits in the buffer pool, the less disk I/O is needed. When a client connects to PostgreSQL, the server spawns a dedicated process to handle that connection, called a backend . Every backend that needs a data page not already in the buffer pool has to first read it from disk, then find a buffer to store it in: either one that is already free, or one currently holding another page that can be evicted. The job of finding that buffer falls to a single crucial function called . To coordinate access to the buffer pool across hundreds of concurrent backends, uses a spinlock. A spinlock is a locking mechanism built on a simple idea: instead of going to sleep while waiting for a lock to become available, a process just keeps checking in a tight loop (it spins ): Why would we ever want that? For very short critical sections, the overhead of putting a thread to sleep and waking it back up can be more expensive than just “spinning“ , meaning actively waiting. If we know the lock holder will be done in nanoseconds, spinning is faster than sleeping. The key assumption behind spinlocks is the following: the thread holding the lock will release it very soon. Nobody is going to preempt that thread in the middle of a 20-nanosecond critical section. The holder will finish and release the lock before anyone has time to notice. uses a single global spinlock to protect the critical section where it selects a buffer. On a 96-vCPU machine with 1,024 clients all hammering the database, every backend competes for the same lock, and any time it takes longer than expected to release, all of them burn CPU spinning. But why did the Linux 7.0 preemption change make it so much worse? The answer lies in how memory works at the hardware level. Every process in Linux, including PostgreSQL, works with virtual memory addresses. For example, the address in one process is a completely different memory from the same address in another process. The hardware translates virtual addresses to physical addresses using a data structure called the page table , maintained by the kernel in memory. A page table is a multi-level tree, so a single address translation requires several sequential memory reads to walk it. Doing that for every memory access would be impossibly slow. Instead, CPUs have a small hardware cache for recent translations called the Translation Lookaside Buffer (TLB): When a process accesses an address it has accessed recently, the TLB already has the translation, and the memory access proceeds quickly. When a process accesses an address it hasn’t seen before, it gets a TLB miss : the CPU has to walk the page table, find the physical address, and store the translation in the TLB. That takes time. There is one more concept to introduce. When PostgreSQL starts, it allocates the shared buffer pool as a large virtual memory region. But allocating virtual memory and having physical memory ready to use are two different things. Indeed, Linux uses a principle called lazy allocation : the allocation is noted, but the actual physical pages are only mapped on first access. The first time any code touches a previously-unmapped virtual address, a minor page fault occurs: the kernel allocates a physical page and stores the mapping. That takes microseconds, orders of magnitude slower than a regular read or write where the page is already mapped. When a process accesses memory for the first time, the kernel doesn’t map it byte by byte. Instead, it maps memory in fixed-size chunks called memory pages via the page table. NOTE : We already used the word “page” to characterize data pages, meaning how PostgreSQL organizes data on disk into fixed-size 8 KB blocks. This is a different concept than a Linux page, which is the unit the kernel uses to manage physical memory. By default, a Linux memory page is 4 KB. PostgreSQL's shared buffer pool, like all memory on Linux, is backed by Linux memory pages under the hood. In Dipietro’s benchmark, the shared buffer pool was configured to 120 GB via the parameter, which at 4 KB per Linux memory page means roughly 31 million memory pages . Therefore, 31 million potential first-touch page faults. Now let’s consider what happens inside . Each backend acquires the spinlock to find a free slot in the buffer pool. To do so, it reads or writes shared memory. If that region of shared memory hasn’t been touched yet, accessing it triggers a minor page fault , meaning that the kernel has to allocate a physical memory page and store the mapping. During a long benchmark with a 120 GB shared buffer pool, new regions keep entering the working set throughout the run, so these faults happen constantly, not just at startup . And when a fault occurs while a backend is holding the spinlock, the consequences are severe. Indeed, we discussed that the key assumption behind spinlocks is that the lock will be released very soon. In that case, the assumption breaks : the holder is stuck inside the kernel fault handler while it stores a physical memory page mapping, and every other backend on the machine is spinning, burning CPU, waiting for a lock that won't be released until the faulting process resumes. The impact of a fault when the lock was acquired depends on the preemption model . Let’s consider the following example. Backend acquires the lock but triggers a page fault. Meanwhile, backends , , and arrive and try to acquire the lock. Since they can’t, they spin, burning CPU on a tight loop while waiting for backend to release the lock. With (before Linux 7) : Once backend enters the fault handler, the kernel handles the fault. Since avoids voluntary rescheduling points, backend is unlikely to be scheduled away before the fault resolves and the lock is released. The spinners wait a bit longer than expected, but the damage is limited. With (Linux 7 and beyond) : The scheduler may decide to preempt backend A while it’s still inside the fault handler, scheduling another process in its place. Backend won’t resume until the scheduler hands control back to it, which can take some time, even after the fault is fully handled: The spinlock hold time goes from “ duration of the fault ” to “ duration of the fault + time waiting for the scheduler .” And that extra wait, let’s call it , is not just of wasted CPU; instead, it is multiplied by every backend currently spinning . In the previous example, backends B, C, and D each burn extra cycles, making the total waste . On a 96-vCPU machine with hundreds of backends, that multiplier is devastating. That's how the benchmark ended up with 56% of the CPU burning in . That extra time waiting for the scheduler was the root cause of the issue. Fortunately, there is an option to overcome this issue in PostgreSQL. The main variable we discussed was , 120 GB in the benchmark, meaning roughly 31 million memory pages. But there is another variable we can adjust: the size of a memory page . As we said, it defaults to 4 KB, but the kernel supports larger pages called huge pages . On x86_64 and ARM64, the supported sizes are 2 MB and 1 GB: 4 KB pages : ~31,000,000 potential page faults 2 MB huge pages : ~61,440 potential page faults 1 GB huge pages : ~120 potential page faults Increasing the size of a memory page reduces the number of potential page faults but also reduces TLB pressure. Indeed, far fewer entries need to cover the same memory, so the working set fits comfortably in the TLB, meaning far fewer TLB misses and page table walks on the hot path. Overall, stops triggering faults while holding the lock. The lock holder finishes quickly. The other backends wait microseconds instead of milliseconds. The regression disappears . NOTE : Setting huge pages in PostgreSQL is controlled by the configuration parameter, which accepts three values: , , and (the default). With , PostgreSQL uses huge pages if available and silently falls back to 4 KB pages otherwise. Use instead so PostgreSQL fails to start rather than running misconfigured without you noticing. The size of the huge pages themselves is a Linux configuration. However, setting huge pages is not without tradeoffs . Huge pages are pre-allocated and reserved upfront, meaning that memory is no longer available to the rest of the system even if PostgreSQL isn’t using it all. There is also a memory waste concern: a huge page is allocated as a whole, so if only a fraction of it is used, the rest is wasted. For most production PostgreSQL deployments with large , these tradeoffs are probably worth it, but they are good to know about. Peter Zijlstra, the Intel kernel engineer who authored the preemption change, proposed a fix: PostgreSQL should adopt Restartable Sequences ( ), a Linux kernel facility that lets userspace code detect whether it was preempted or migrated during a critical section and restart it if so. PostgreSQL's spinlock paths would use to detect preemption and retry, avoiding the scenario where a preempted lock holder stalls all waiting backends. The PostgreSQL community’s response was not enthusiastic. Using a kernel facility specifically to recover performance that PostgreSQL had for free before Linux 7.0 is a tough sell. It also sits uncomfortably next to the kernel’s long-standing principle of not breaking userspace : if software worked correctly before a kernel upgrade, it should work correctly after. AI is getting better every day. Are you? At The Coder Cafe, we serve fundamental concepts to make you an engineer that AI won’t replace. Written by a Google SWE, trusted by thousands of engineers worldwide. Linux 7.0 removed on modern CPU architectures, leaving only and . On most distributions, the default shifted to . An AWS engineer benchmarked PostgreSQL on a 96-vCPU Graviton4 and found throughput cut in half on Linux 7.0, with 55% of CPU burning inside a single spinlock in . The root cause is minor page faults occurring while a backend holds the spinlock. With 4 KB memory pages backing a 120 GB , there are up to 31 million potential first-touch faults throughout a benchmark run. Under , the faulting process resumed quickly and released the lock. Under , the scheduler may preempt it mid-fault, extending the hold time and causing every waiting backend to keep spinning. Enabling huge pages (2 MB or 1 GB) reduces the number of potential faults by orders of magnitude and eliminates TLB pressure, making the regression disappear. Linux Soft vs. Hard Lockup Instruction Pipelining Explained Simultaneous Multithreading Explained [PATCH 0/1] sched: Restore PREEMPT_NONE as default AWS Engineer Reports PostgreSQL Performance Halved By Linux 7.0, But A Fix May Not Be Easy PREEMPT_NONE Is Dead; Your Postgres Probably Doesn’t Care The long road to lazy preemption Buffer Manager Restartable Sequences The Problem Salvatore Dipietro ran pgbench (PostgreSQL’s standard benchmarking tool) on a Graviton4 processor with 96 vCPUs. The workload was a benchmark doing simple updates at scale factor 8,470 (i.e., roughly a 847 million row table), simulating 1,024 clients and 96 threads. A serious, high-parallelism load designed to stress the system. The results were striking. Linux 7.0 delivered roughly half the throughput of Linux 6.x on the same hardware and workload: Linux 6.x : 98,565 transactions per second Linux 7.0 : 50,751 transactions per second : The kernel almost never interrupts a running thread. A thread runs until it voluntarily gives up the CPU: when it makes a syscall, blocks on I/O, or explicitly sleeps. This was the traditional server default with fewer context switches, higher throughput, and predictable behavior under load. : The kernel can interrupt a running thread at almost any safe point, even if it is in the middle of doing useful work. This means a thread never has to wait for the current one to finish its slice before getting CPU time, which reduces response time but increases context-switch overhead. Historically, the desktop default, where responsiveness matters more than raw throughput. : Introduced in Linux 6.12 as a compromise between the two. The scheduler can interrupt threads, but tries to wait for natural boundaries rather than cutting in aggressively. The intent is to approximate ‘s throughput behavior while still allowing preemption when needed. When a process accesses an address it has accessed recently, the TLB already has the translation, and the memory access proceeds quickly. When a process accesses an address it hasn’t seen before, it gets a TLB miss : the CPU has to walk the page table, find the physical address, and store the translation in the TLB. That takes time. With (before Linux 7) : Once backend enters the fault handler, the kernel handles the fault. Since avoids voluntary rescheduling points, backend is unlikely to be scheduled away before the fault resolves and the lock is released. The spinners wait a bit longer than expected, but the damage is limited. With (Linux 7 and beyond) : The scheduler may decide to preempt backend A while it’s still inside the fault handler, scheduling another process in its place. Backend won’t resume until the scheduler hands control back to it, which can take some time, even after the fault is fully handled: The spinlock hold time goes from “ duration of the fault ” to “ duration of the fault + time waiting for the scheduler .” And that extra wait, let’s call it , is not just of wasted CPU; instead, it is multiplied by every backend currently spinning . In the previous example, backends B, C, and D each burn extra cycles, making the total waste . On a 96-vCPU machine with hundreds of backends, that multiplier is devastating. That's how the benchmark ended up with 56% of the CPU burning in . That extra time waiting for the scheduler was the root cause of the issue. Huge Pages to the Rescue Fortunately, there is an option to overcome this issue in PostgreSQL. The main variable we discussed was , 120 GB in the benchmark, meaning roughly 31 million memory pages. But there is another variable we can adjust: the size of a memory page . As we said, it defaults to 4 KB, but the kernel supports larger pages called huge pages . On x86_64 and ARM64, the supported sizes are 2 MB and 1 GB: 4 KB pages : ~31,000,000 potential page faults 2 MB huge pages : ~61,440 potential page faults 1 GB huge pages : ~120 potential page faults Linux 7.0 removed on modern CPU architectures, leaving only and . On most distributions, the default shifted to . An AWS engineer benchmarked PostgreSQL on a 96-vCPU Graviton4 and found throughput cut in half on Linux 7.0, with 55% of CPU burning inside a single spinlock in . The root cause is minor page faults occurring while a backend holds the spinlock. With 4 KB memory pages backing a 120 GB , there are up to 31 million potential first-touch faults throughout a benchmark run. Under , the faulting process resumed quickly and released the lock. Under , the scheduler may preempt it mid-fault, extending the hold time and causing every waiting backend to keep spinning. Enabling huge pages (2 MB or 1 GB) reduces the number of potential faults by orders of magnitude and eliminates TLB pressure, making the regression disappear. Linux Soft vs. Hard Lockup Instruction Pipelining Explained Simultaneous Multithreading Explained [PATCH 0/1] sched: Restore PREEMPT_NONE as default AWS Engineer Reports PostgreSQL Performance Halved By Linux 7.0, But A Fix May Not Be Easy PREEMPT_NONE Is Dead; Your Postgres Probably Doesn’t Care The long road to lazy preemption Buffer Manager Restartable Sequences

0 views
Alex White's Blog 1 months ago

Photo Journal - Day 2

Realized I issued myself a challenge, but failed to define any parameters! My goal is to post at least 1 photo taken with my Sony A7IV per day. Let's see how it goes! Today's photos are from a short e-bike ride my wife and I did along the trail near our home. I want to give some serious kudos to RapidRaw , it's a seriously fast Lightroom alternative that runs on Linux. I've been loving it!

0 views
Kev Quirk 1 months ago

Stop Ubuntu Resetting Your Icon Theme When Toggling Dark Mode

The Papirus icon theme is my favourite - I've used it for years and it continues to work beautifully. So while I've been rebuilding my Framework 13 , it was one of the first things I installed. But there's a problem, dear reader. You see, I'm a proud light mode person, but I regularly switch to dark mode when working in the evening. However, Ubuntu has this silly bug where it switches back to the default Yaru icon theme whenever one switches between light and dark mode. On my previous machine I had a cronjob running every minute that simply checked the theme and switched it to Papirus if it was Yaru. That worked fine, but wasn't the most elegant solution. So, this time I did more research and came up with a slightly more elegant fix workaround. Ok, it's pretty simple. It consists of a small script that runs whenever Ubuntu flips between light/dark mode, then 0.2 seconds later, switches the icon theme back. Far from perfect, but it's better than a script that runs every minute the machine is running. To do this, create a new script at with the following contents: You need to make the script executable, so run this next: Next thing is create a file that tells GNOME to automatically start the script when we log in: Remember to change on the line to whatever your Ubuntu username is. That's it! Log out, and back in again, and the script should be doing it's thing in the background. So the next time you switch between light and dark mode, your fancy-pants icon theme should persist. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Alex White's Blog 1 months ago

I Use Arch BTW

In my previous post I talked about my frustration that the used Thinkpad I bought was crashing when unplugged in Linux. My conclusion at the end of the post was that I would return to Mac OS. Well that lasted about 1 day. I'm back to Linux on the Thinkpad, here's what happened (with added rants about Mac OS and Windows): After using Linux on my System76 for a few months, Mac OS felt...old? Everything was laggy: the animation for switching spaces, launching apps, even typing. Sure, my Mac is a 5+ year old computer at this point (14" MacBook M1 Pro), but still, it shouldn't feel that bad. Then there's how Apple treats you like a child. Want to install that app you downloaded? No, it's too dangerous (aka the developer didn't pay us)! We recommend you just throw it away. In parallel to dealing with Mac OS, I went through the terrible process of installing Windows 11 on the Thinkpad with the idea of giving it to my wife. Seriously, I can't properly articulate how awful Windows 11 is these days (but I can try). First off, just getting a bootable ISO is a pain. You can't just flash with any normal program, you're expected to use another Windows computer to setup a USB. Thankfully I found a Mac app ( WinDiskWriter ) that could do it. It took 2 tries though, the first time I choose exFat and it wouldn't boot, so I tried again with fat32. Once you're in the installer, the shit show truly begins. Off the bat, the installer has a completely different design language then Windows 11. The built-in disk practitioner is one of the worst I've used (compared to Linux installers). The install process takes forever and the computer has to reboot 3-4 times. Again, compared to Linux, this is so bizarre. Almost every distro out there has a live environment, an intuitive installer (not you Fedora), takes ~10 minutes and doesn't reboot a single time. Finally you get to the post-install setup wizard. It's filled with laggy animations, how wonderful! Right off the bat it required me to be on the internet, but it didn't recognize my WiFi. There was a "load driver" button though, so I downloaded the WiFi driver from Lenovo onto a USB drive. Nope, not recognized. I had to unplug one of my WiFi APs and use it's ethernet to finish the install. While doing this, screen kept flashing as it tried to figure out the display drivers. Again, Linux just works. WiFi, graphics, etc. Once online I of course had to login to a Microsoft account. I also had to agree to sell my information to advertisers. Then I was presented with 7 pages of upsells. I'm not kidding! "Subscribe to Gamepass", "How about Office 365?", "You need Onedrive, right?". Buying a used car from a sketchy salesman is a better experience than installing Windows. Once everything was finally installed, I had to "check updates" and reboot multiple times. It's funny how installing all the available updates just leads to more updates after reboot. Why not, ya know, install them all at once? But here's where something good finally happened! First, I verified that the Thinkpad worked perfectly in Windows, no crashing at all when unplugged. I also noticed a "Lenovo Updater" app got auto installed. After running the app, it found one "critical" firmware update for my SSD. This update wasn't found by in Linux, and there was no way to get the firmware on the Lenovo site beyond the Windows . The next day, I got fed up with Mac OS and decided I would bite the bullet and order a Framework. I could have gone back to the System76, but once you ride a Cervelo it's hard to get back on a Huffy ya' know? In a last ditch effort, I flashed EndeavourOS to a USB to try one more time with the Thinkpad. My thought was Arch would be bleeding edge and have a higher chance of working. Sure enough, no more crashes! I stress tested quite a bit across a few reboots and it was rock solid! I'm 90% the issue was the SSD firmware, but it might be Arch. I'm honestly pretty happy with EndeavourOS so I didn't try Ubuntu or Fedora, instead I happily wiped Windows with a EndeavourOS + GNOME install. I'm overjoyed that the Thinkpad is rock solid now, it's such a great little machine! I have a feeling my future laptops are going to be Thinkpads, but I expect this will last me quite awhile. TL;DR for those facing the issues I did: To fix AMD data fabric sync flood event in Linux when plugging in or unplugging the charger on a Lenovo Thinkpad P14s Generation 4 that leads to a full system reboot, install the NVMe Solid State Drive Firmware Update from the Lenovo Support website. You will need Windows 11 to install the driver, but can switch back to Linux after install.

0 views
Alex White's Blog 1 months ago

New Thinkpad Means Back to Mac OS

On Wednesday I picked up a new (to me) Thinkpad P14s Gen 4. I was excited to finally get off my System76 Pang12, a computer that works, but has a long list of hardware and reliability issues. Thinkpad in hand, I installed Ubuntu 25.10 and immediately put it to work with a night of trimming down my client request backlog. The computer was incredible! Amazing keyboard, vastly better trackpad, perfect 14” form factor and everything worked out of the box on Ubuntu. Heck, it even had a usable webcam! But like a majority of things in my life, something always goes wrong. I knew it was too perfect, and wondered what I was going to find that ruined the joy. How about complete system crashes when you plug/unplug the system? Yep, that’ll do it. I spent all of yesterday and this morning debugging. Multiple distress, a long list of kernel params, different chargers and tweaking bios settings. Nada. About 50% of the time when you unplug, Gnome will slowly start to lock up, then the system restarts. Looking at logs it’s caused by a . At first I thought it might be related to the WiFi chips (based on pre-crash logs). Disabled via bios and still crashes. I’ve tested RAM, SSD and battery, all good. I have a new battery coming Monday just in case, but fully expect it won’t help. I’m out $500 USD, and honestly, I’m done with Linux for now. I love Gnome and Fedora+Ubuntu, but it’ll be a few years before I buy a new laptop after throwing away money on the Thinkpad (and the Pang12 2 years ago). Back to Mac OS Tahoe it is. Liquid ass and all. I’m hopeful that the Thinkpad problems are just on Linux. My wife has been wanting a laptop and she’s not ready to jump off Windows making it the perfect computer for her.

0 views
Brain Baking 1 months ago

Hello Again, SuSE Linux

It’s good to see you again, old friend. It’s been a while. Twenty-three years, you say? How come we managed to drift apart that far? I know, I know, I betrayed you. But my room was cold at night and Gentoo offered me the ability to keep on compiling. And then I betrayed GNU/Linux for FreeBSD. And then I switched the demon for the apple. I’ve been on an apple diet for so long now, I can barely remember the tux. What is it you say? Oh, it’s openSUSE now. Sure, you’re a chameleon, you can take on any colour you’d like. Great to see it’s still green. I like green. How’s YaST doing these days? ? What’s that, no more ? That’s cool, it looks like you’ve made some progress! Let’s make a screenshot the proper nerdy way and do some in a terminal! Oh, that’s no longer cool? ? So first and then that command? Let’s try that: openSUSE Tumbleweed running on the HP work laptop. My last experience with the Linux desktop was indeed about twenty years ago. Since 2012, I’ve been a macOS user. I’m no longer proud of it: I miss Linux and I think macOS is boring and full of bloat . Yet the rise of the Apple silicon made me buy another one in 2020, which is still the one I’m using right now. The hardware is amazing, the screen is amazing, and the weight and fanless features are amazing. But I still miss customisation features—the ability to truly make the desktop mine—and I stopped updating the OS as a protest to ever increasing bloatware. This laptop is still running Sonoma which is bad enough as it is. I have no intentions to go out and buy another machine any time soon; this one’s still doing fine; but I did start to wonder. What if… I got a ThinkPad and installed Linux back onto it? Would the hardware match the high standards I’m accustomed to now? Would I still be able to make my way around the OS? I ran GNOME 2 and KDE 3 (and then got nerdy with Fvwm). I compiled my own Linux 2.6 kernel patches back when that was brand new. I have no idea what’s happening now. That’s not to say that I don’t touch Linux: I use it daily to host this website, to run the NAS at home, and in virtual containers. But that’s not the Linux Desktop Experience . My main motivation for moving away from Linux was my frustration with endless configuration and compilation. Back in the day, hibernate didn’t just work out of the box, the fan speed had to be configured depending on the type of the laptop, nVidia drivers were a pain (still are), etc. Work and life started getting in the way: I no longer had endless seas of time on my hand to go nuts with Gentoo. With two young kids, that times has dwindled even more, so NixOS or even Arch is out of the question. Being fed up with the crappy Windows 11 installation on my work laptop, I wiped that partition and remembered my old friend The European Chameleon. So here I am, testing the waters yet again. Thanks to Valve, Lutris is amazing . KDE Plasma feels mature (even though some configuration settings seem sluggish). I don’t want to dive into the rabbit hole of AwesomeWM (but I do). I don’t want to try and live without systemd or have to hurt my brain about X11 vs Wayland. I want the thing to “just work”. I want my chameleon to be an apple. A proper one, like a “back in the day” apple one. I haven’t had the time to give openSUSE a proper trail. I’m mainly fighting my muscle memory with versus that strange location which is somewhat diminished by Toshy that then doesn’t work well in combination with my Emacs configuration. What I did notice is that hibernation/suspend is still ugly: if I close the lid for a night without putting the laptop in true hibernate mode (with its dedicated swap partition), the battery drain is ridiculous, especially coming from a MacBook Air that I just jam shut and open up again a hundred times a day. This made me realise I will probably have to give up on the hardware quality part if my next laptop is going to be a non-Apple one. Which I don’t really want to? Seb and I discussed which laptop to get when ours would break down. The Framework is an obvious one as are the System76 ones that specifically support Linux. Alex White’s everyday carry post made me realise the build quality of these is average at best. It’s going to be a painful experience migrating from that. I know Kev is happy with his Framework , but I’m not yet fully convinced. The fact that this HP EliteBook 6 G1a 16 work laptop’s screen and overall build quality is terrible is not helping either. The touchpad palm detection experience is horrible on KDE. Let’s first give the chameleon another chance to see if on an OS level I could live without macOS and my usual mac-exclusive power tools. The ones I’ll miss the most might be Alfred and DEVONthink . My recent migration to do-everything-in-Emacs does make the transition a lot easier. I also moved from iTerm2 to Ghostty last year and am now trying out Kitty with the Fish shell. My RSS feed now lives inside my FreshRSS server making me less dependent on NetNewsWire. Software-wise, I’m getting there. I’m sure I’ll get there. But what about hardware-wise? Related topics: / linux / By Wouter Groeneveld on 22 April 2026.  Reply via email .

0 views
Alex White's Blog 1 months ago

Linux Apps Starter Kit (Gnome Edition)

I find beautiful, well-designed, native applications to be a source of inspiration when using my computer. I've posted on Mastodon about the native Mac applications that were hard to leave when switching to Linux. Now that I've fully made the switch, I figure it's only fitting to do the reverse post on the Linux applications that I've fallen in love with. For this post, I'll be focusing on Gnome/GTK/Adwaita applications. Why? Two reasons. First off, I use Fedora with Gnome 49 so I'm most familiar with this territory. Second, Gnome has a very well defined HIG (Human Interface Guidelines), resulting in a strong visual identity. Applications enhance the operating system in a consistent, fluid way, rather than serving a jarring experience (ie an electron app with radically different UI/UX). This is key to me for finding inspiration and joy when using an application. With all that said, let's dig into the apps I consider essential! Internet radio is awesome and Shortwave is the best application I've found on any platform for listening to it. Search for stations, add to your library and jam! It also has a DVR-like function (okay I get it, I'm getting old) so you can download tracks you've listened to. Finally, there's an amazing skeuomorphic mini-player (I'm a sucker for skeuomorphic design). 📦 Shortwave on Flathub ♥️ Support Shortwave 👤 Meet the Developer "Plays music, and nothing else" is the tagline of this beautiful audio player. For those of us still rocking local media collections, Amberol is the way to go. I mean, just look at it! Point it at a folder, play the music inside, easy! I have my NAS mounted as a bookmark in Nautilus, so I just point Amberol to my network music folder. Who needs streaming?!? 📦 Amberol on Flathub ♥️ Support Amberol 👤 Meet the Developer I've been using Blanket longer than most apps on this list, long before I made the full switch to Linux (and heck, it's probably one of the reasons I eventually made the switch). It's a no-frills ambient noise machine. Comes with a large selection of high-quality samples that can individually be toggled and adjusted. You can save preset configurations (ie coffee shop in a thunder storm), and add your own audio samples. On any other platform this would cost $15 or more, but here it is on Linux, free and open-source. 📦 Blanket on Flathub ♥️ Support Blanket 👤 Meet the Developer Need to quickly edit an image or make a thumbnail? Pinta to the rescue! It's fast and has a familiar UX. Sure, it's not as powerful as GIMP, but I find myself reaching to it more often. 📦 Pinta on Flathub 👤 Meet the Developers This app right here should be a default Gnome app, it's that good! Hands down the most powerful and user friendly screenshot tool I've used (and yeah, I've tried the popular Mac OS ones). Bind Gradia to a shortcut (I use Super + Shift + S) and it'll open after you take a screenshot. Gradia lets you add arrows, drawings, blur text, perform OCR, crop, add backdrops and more. It's honestly an essential application, and performs better than apps I paid $15+ for on Mac. 📦 Gradia on Flathub ♥️ Support Gradia 👤 Meet the Developer There's a lot of single purpose, well-built applications for Gnome, and Switcheroo is a great one I use daily. It takes an image in, and outputs in a different format. You can add on compression, resizing, strip metadata and replace transparency. I use it to optimize images for web. 📦 Switcheroo on Flathub ♥️ Support Switcheroo 👤 Meet the Developer I don't use social media beyond Mastodon, but Tuba makes me glad I'm at least on that platform. Tuba is well designed, fast and filled with thoughtful features (like a custom emoji picker and the ability to schedule posts). I've tried the best on Mac (Ice Cubes), and it doesn't get close to comparing with Tuba. 📦 Tuba on Flathub ♥️ Support Tuba 👤 Meet the Developer Mmmm RSS, my favorite (and probably how you're reading this article)! Newsflash is a great excellent, way to stay on top of your feeds. It's got categories, tags, OPML import/export, themes, and more. My favorite feature is the "Today" tab filtered by unread, great to catch up on what's new. 📦 Newsflash on Flathub 👤 Meet the Developer Here it is, my top pick. You don't even need to read this, just go download Planify, it's incredible. Alain took todos and added a bucketload of thoughtfully designed microinteractions. Labels, scheduling, today view, sections, kanban board, natural text to date parsing, the list goes on. When you hover the "Add" button, it does a little animation. When you complete a task, it gives a little sound. There's so many thoughtfully designed pieces in here! 📦 Planify on Flathub ♥️ Support Planify 👤 Meet the Developer Markdown based note taking, done very well. Notes are organized into notebooks and paired with a pleasant, minimalist markdown editor. 📦 Folio on Flathub 👤 Meet the Developer Distraction free markdown editor for writing long form content. Basically, the Linux alternative to iA Writer on Mac. It's beautiful, fast and has just enough features. I use it to write most of my blog posts! 📦 Apostrophe on Flathub ♥️ Support Apostrophe 👤 Meet the Developer Another excellent, single-purpose application that I use on a daily basis. Sessions is an egg/pomodoro timer that beeps when time's up. You just drag the slider and the timer starts. Great for keeping yourself focused! 📦 Sessions on Flathub ♥️ Support Sessions 👤 Meet the Developer Holy crap this app looks good! John did an incredible job building the best ebook reader on Linux. You can bring your own books, or use the catalogs feature to discover public domain literature. There's support for annotations (with import/export), bookmarks, text to voice and theming. 📦 Foliate on Flathub ♥️ Support Foliate 👤 Meet the Developer Got a sqlite database and want to know what's inside? Bobby to the rescue! Drag and drop your database file in and see the data. Simple, well designed and useful! 📦 Bobby on Flathub ♥️ Support Bobby 👤 Meet the Developer There's so much value packed into this app! Replace random sketchy websites you found on Google by using Dev Toolbox to generate a QR code, check contrast ratios, parse CRON strings and so much more. There's too much in here to cover, but it's become an essential part of my toolkit. 📦 Dev Toolbox on Flathub 👤 Meet the Developer Bazaar is a faster, more reliable and visually more appealing alternative to the default Gnome Software application. It's one of my first installs on a new system and another application that should be a default Gnome app. 📦 Bazaar on Flathub ♥️ Support Bazaar 👤 Meet the Developer The absolute best way to discover, install and update Gnome shell extensions! 📦 Extension Manager on Flathub ♥️ Support Extension Manager 👤 Meet the Developer Copyous is a shell extension, and it's the best clipboard manager out there. Visually browse and search your clipboard history. Supports image previews, syntax highlighting, color previews (ie copy a hex code and it shows the color) and so much more! 📦 Copyous on Gnome Extensions There's so many amazing applications on Linux that I definitely missed some! Feel free to shoot me an email at [email protected] with recommendations. I'll do a separate post in the future for KDE applications! I mentioned a few times in this article that some applications on Linux provide better value than alternatives I paid for on Mac OS. There's not a single paid application on this list, but that does not mean you shouldn't support the developers! These developers work hard to design, build, test and support the software that makes Linux great. If you like their work, show them some love!

0 views
DHH 1 months ago

The malleable computer

Open source promised that users would be free to change whatever code they were running. The reality, however, is that hardly any of them ever did — it was simply too hard. Now, with AI, it suddenly isn't. This is very exciting. Being able to add features to any local open-source application and then use that bespoke fork for your own benefit is an incredible step toward the original open source promise. This isn't just about regular users, either. Even if you are a programmer, you might not be familiar with the language the application is written in. And even if you are, taking the time to get familiar with any substantial codebase is a tall order. AI is compressing that complexity and making it malleable at a ferocious rate. What excites me even more, though, is when this power is applied to the operating system, and thus the entire computer. When you're able to change not just individual applications, but your system's menu bars, your window manager, your notification system, your everything.  But you can only do this on Linux. With Windows and macOS, the core elements of the operating system are owned by the companies that make them. While it's often possible to hack certain aspects, it's far from truly having the malleable computer that Linux allows. I've already seen this a lot in the Omarchy world: users who aren't super technical making the system their own with the help of AI and being utterly delighted by the outcome. And while this is still a pretty nerdy thing to do, I don't think it will remain contained to that niche for long. As models get even more powerful, the idea that your system is tied down as a fixed black box is likely to become an archaic notion pretty quickly. As always, the future is already here, it's just not evenly distributed.

0 views
Unsung 1 months ago

“Approximately 21 times the estimated age of the universe”

A few years ago, some sort of a bug at my work caused all of the timestamps appear as “54 years ago,” a seemingly arbitrary date. It took me a bit to realize: “Wait, you know what year was 54 years ago? 1970!” “Why is 1970 important?” asked another designer. I explained that by convention, Linux time counts up from Jan 1, 1970 – and so if the time “value” is zero or unavailable, as it was because of the bug, it would be rendered not as an error, but as that specific day long ago. Computing is filled with all sorts of arbitrary numbers like these. The most famous one was Y2K (99 + 1 = 00 if you only allocate two digits), Pac-Man’s kill screen was number 256, people still bring up the infamous and likely non-existent “ 640 kilobytes should be enough for everybody ” quote, and the Deep Impact space probe died a lonely and undignified death after its timers overflowed the two pairs of bytes given to them. Here’s a new magic number to remember: macOS Tahoe has, for a while at least, a kill screen of its own – after 49 days, 17 hours, 2 minutes, and 47 seconds (or, 4,294,967,295 milliseconds), one of its time counters overflows and no new network connections can be made, rendering the machine rather useless. The only solution is a reboot. Talk about a dead line! (Well, new-ish. In perhaps a bit of karmic payback , Windows 95 and 98 once had a similar problem with the exact same threshold of 49.7 days.) Wikipedia has a nice list of other time storage bugs . The next big one? The problem of the year 2038 . The technical fix, as always, is to give the numbers a bit more room to breathe. This is, in a way, kicking the can down the road, but that might be okay since the road is rather long: Modern systems and software updates address this problem by using signed 64-bit integers, which will take 292 billion years to overflow—approximately 21 times the estimated age of the universe. However, as always, the technical side won’t be the hard part .

0 views
Abhinav Sarkar 1 months ago

Running NixOS Micro VMs on MacOS

microvm.nix is a framework to run NixOS based micro VMs on various platforms. In particular, it can use vfkit to run micro VMs on macOS that use the macOS virtualization framework to provide a more performant VM than QEMU . microvm.nix works well but the documentation is a bit lacking. I had to figure out some gotchas while setting this up on my MacBook Pro M4, so I decided to write this note. This tutorial requires Nix and Nix Darwin to be installed on the macOS machine. To build a micro VM, we need a NixOS builder machine running AArch64 Linux. Thankfully, it is really easy to set up one with Nix Darwin. Assuming we have Nix Darwin set up with a Nix flake like: First, we add Nix Linux builder config: Now, we switch the system config to build and start the Linux builder: We should verify that the builder is working: It may take up to a minute for the builder to start. Once SSH works, we can proceed. We create a file with the micro VM configuration: This configures a micro VM with 4 VCPU, 8GB RAM and 40 GB disk. The disk image is used to store the Nix packages downloaded within the VM. It is mounted at . The host’s Nix store is mounted read-only at . The option combines these two with overlays to create the VM’s Nix store at . We can share additional directories from the host and mount them in the VM, as we do here for the directory from the macOS host. Next couple of lines set up networking in the VM. The vfkit hypervisor supports only NAT networking. This means: There are ways to work around this using gvisor-tap-vsock and vmnet-helper , but we are not going into it here. We can uncomment the line if we want a graphical NixOS VM. Finally, the workaround for the big gotcha! By default Nix does builds in a sandbox and the sandbox is created (and deleted) on the root filesystem. However, microvm.nix uses a temporary filesystem residing in RAM for the root filesystem. This means that the Nix builds may cause the root FS and RAM to fill up, causing out-of-memory or out-of-disk-space errors. To prevent that, we disable the sandbox and set the build directory to be at on the disk image we mounted. Next, we integrate the VM config with the Nix Darwin flake: Let’s go over the tricky bits. The wrapper script rebinds Ctrl + ] to send the interrupt, suspend and quit signals instead of the usual Ctrl + C so that we can use Ctrl + C inside the VM without it causing the VM to shut down. We add the script to our system packages. Lastly, the defines the actual micro VM using the file. Finally, we build and install the micro VM: And, now we can run it from any directory: Note that the disk image file will be created in the directory in which we run the above command. After this, we can remove the Linux builder config and switch again to stop and delete it. Now we have a performant micro VM running NixOS to play around with in our macOS machine. That’s all I had for this note. I hope this helps. If you have any questions or comments, please leave a comment below. If you liked this post, please share it. Thanks for reading! Thanks for reading this post via feed. Feeds are great, and you're great for using them. ♥ This post was originally published on abhinavsarkar.net . Read more of my posts and notes . The VM can make outgoing connections to the host/internet. The host cannot initiate connections to the VM.

0 views
Brain Baking 2 months ago

App Defaults In March 2026

It’s been almost three years since sharing my toolkit defaults (2023) . High time to report an update. There’s a second reason to post this now: I’ve been trying to get back into the Linux groove (more on that later), so I’m hoping to either change the defaults below in the near future or streamline them across macOS & Linux. When the default changed I’ll provide more information; otherwise see the previous post as linked above. Some more tools that have been adapted that don’t belong in one of the above categories: A prediction for this post in 2027: all tools have been replaced with Emacs. All silliness aside; Emacs is the best thing that happened to me in the last couple of months. Related topics: / lists / app defaults / By Wouter Groeneveld on 29 March 2026.  Reply via email . Backup system : Still Restic, but I added Syncthing into the loop to get that 1-2-3 backup number higher. I still have to buy a fire-proof safe (or sync it off-site). Bookmarks and Read It Later systems : Still Alfred & Obsidian. Experimenting with Org-mode and org-capture; hoping to migrate this category to Emacs as well. Browser : Still Firefox. Calendar and contacts : Still Self-hosted Radicale. Chat : Mainly Signal now thanks to bullying friends into using it . Cloud File Storage : lol, good one. Coding environment : For light and quick scripting, Sublime Text Emacs! Otherwise, any of the dedicated tools from the JetBrains folks. and can only do so much; it’s dreadful in Java. Image editor : Still ImageMagick + GIMP. Mail : Apple Mail for macOS for brainbaking Mu4e in Emacs! and Microsoft Outlook for work Apple Mail for the work Exchange server. I didn’t want to mix but since Mu cleared up Mail, that’s much better than Outlook. Music : Still Navidrome. Notes : Still pen & paper but I need to remind myself to take up that pen more often. Password Management : Still KeePassXC. Photo Management : Still PhotoPrism. I considered replacing it but I barely use it; it’s just a photo dump place for now. Podcasts : I find myself using the Apple Podcast app more often than in 2023. I don’t know if that’s a bad thing—it will be if I want to migrate to Linux. Presentations : Haven’t found the need for one. RSS : Still NetNewsWire but since last year it’s backed by a FreshRSS server making cross-platform reading much better. Android client app used is Randrop now, so that’s new. Spreadsheets : For student grading, Google Sheets or Excel if I have to share it with colleagues . My new institution is pro Teams & Office 365. Yay. Text Editor : I’m typing this Markdown post in Sublime Text Emacs. Word Processing : Still Pandoc if needed. Terminal : emulator: iTerm2 Ghostty, but evaluating Kitty as well (I hated how the iTerm2 devs shoved AI shit in there); shell: Zsh migrated to Fish two days ago! The built-in command line option autocomplete capabilities are amazing. Guess what: more and more I’m using eshell and Emacs. Karabiner Elements to remap some keys (see the explanation ) I tried out Martha as a Finder alternative. It’s OK but I’d rather dig into Dired (Emacs)—especially if I see the popularity of tools like that just steal Dired features. I replaced quite a few coreutils CLI commands with their modern counterparts: now is , now is , now is , now is , and can be used to enhance shell search history but Fish eliminated that need. AltTab for macOS replaces the default window switcher. The default didn’t play nice with new Emacs frames and I like the mini screenshot.

1 views
マリウス 2 months ago

Hold on to Your Hardware: BadRAM

We’re living in unprecedented times, once again , in which holding on to our existing hardware has become more important than ever before. With prices for solid state drives and especially RAM going through the roof, it can be at the very least frustrating to have a computer malfunction due to faulty memory. In this post, I’d like to show how to check a system’s memory for defects and how to work around those defects to prolong a system’s life without needing to replace the RAM module(s), or worse the whole mainboard, right away. Note: This guide is intended for Linux users, specifically systems with GRUB that do not use secure boot / lockdown mode . If you are a Windows user, look up the command, specifically its subsection. If you’re on a Mac, you will probably have to dig into tools like this or make use of the setting. The first thing we need to do is to check whether our RAM is the actual culprit of any system instability we might be experiencing. For that, we can use the open-source program . Most Linux distributions either come with it pre-installed, have it as an installable package in their repos, or at the very least offer it on their installation live CD/DVD/USB media. If you start your computer and you see a bootloader entry for then you already have it installed. If not, consult the documentation of your specific distro on how to install it. Otherwise you can simply download any live media (e.g. Ubuntu Desktop , Fedora Workstation , etc.) and boot into from there. As soon as launches you should go into its configuration, select all tests and set the output to BadRAM patterns . Depending on the amount of RAM in your system the test will take anything between a few hours to multiple days. will use various patterns to test the RAM for errors and will either finish with a green message or show a big red and output the relevant BadRAM patterns that can be used to blacklist the presumed faulty addresses. Bear in mind that these test results can be flaky and should be validated by running repeatedly over a period of time to see whether issues show up consistently. The resulting list of BadRAM patterns can be used to blacklist the specific addresses, so that the Linux kernel does not try to access those areas. To do so, it is either possible to utilize the configuration in , or manually append the kernel parameter, e.g. via . The advantage of is that you can simply copy-paste the output of into the setting and be done with it. However, the downside is that GRUB will generate a dedicated boot attribute from this, which, if faulty (e.g. due to typos or bugs ) will brick the bootloader and require booting from a recovery medium to fix the issues. The more manual solution requires a bit more work but can be fixed right from within the GRUB boot prompt if anything goes wrong, by editing ( key) the boot entry. An example entry could look as follows: Depending on the mask for every specific address you might need to adjust the size of the isolated area from to a value that fits the specific address. To calculate the area, we take the mask, e.g. and XOR it with to get or decimal . This is our area of faulty RAM in bytes. We round the value up to the next power of 2, which is , which translates to the following : Keep in mind that the minimum viable area is . It also makes sense to blacklist a slightly larger area, as it is likely that surrounding addresses will fail moving forward. A complete GRUB configuration for several s could look as follows: Due to how works the character has to be escaped, and the escape character has to be escaped as well. Don’t even ask. The last step that remains is to actually run to re-generate the file. Make sure to double-check that afterwards to make sure that GRUB did not mess it up. The Linux kernel supports a long list of parameters , one of which is . This parameter “specifies the number of memtest passes to be performed. Each pass selects another test pattern from a given set of patterns. Memtest fills the memory with this pattern, validates memory contents and reserves bad memory regions that are detected.” We can append e.g. to our to enable this feature. The Linux kernel memory test takes around half a minute on my system with 64GB of RAM during boot and will ideally identify any new RAM issues and automatically mark those addresses as unusable. For runtime insights into the system memory, it is possible to , and . You should be able to identify blacklisted regions within the output of these commands. This is supposed to act as a temporary measure and not a long-term solution. Faulty RAM will cause headaches down the road and can lead to irreparable data corruption.

0 views
Rik Huijzer 2 months ago

Granting Explicit ACL Access to a File on Linux

Say there is a file, `openui/open-webui/webui.db`, and you want to have write access to it without using `sudo`. The most reliable way is to not use various `chown` and `chmod` commands, but instead use `setfacl`, which is available on Debian via `apt install acl`. To first check the permissions, run `namei`, ```text $ namei -mo openui/open-webui/webui.db f: openui/open-webui/webui.db drwxrwxr-x rik rik openui drwxrwxr-x 777 rik open-webui webui.db - Permission denied ``` It looks like permissions to enter the `openui/open-webui` dir are missing. This can be fixed by...

0 views
Rik Huijzer 3 months ago

How To Run Services on a Linux Server

I have been running services myself for a few years on Linux servers. It took a while to figure out what works best. Here's what I've learned. First of all, all maintenance is done on headless servers via SSH. Learning this might seem daunting for some at first, but it is truly unbeatable in terms of productivity and speed. To easily log in via SSH, add the SSH keys to the server and then add the server to your `~/.ssh/config`. For example, ``` Host arnold Hostname 123.456.789.012 User rik IdentityFile ~/.ssh/arnold ``` Now you can log in via `ssh arnold` instead of having to ma...

0 views
Karboosx 3 months ago

How Docker Actually Works (No Magic, Just Linux)

Stop thinking of Docker as a mini-VM. It’s not! It’s just a normal Linux process that has been told a very elaborate series of lies. I'll show you exactly how the Linux kernel uses Namespaces and cgroups to create the "magic" of containers without any of the VM overhead.

0 views

remotely unlocking an encrypted hard disk

Your mission, should you choose to accept it, is to sneak into the earliest parts of the boot process, swap the startup config without breaking anything, and leave without a trace. Are you ready? Let's begin. In which our heroes are introduced, and the scene is set. For a very long time I had a beat-up old ThinkPad that couldn’t hold a charge for the life of it, especially when running Windows. It tended to die a lot when I was traveling, and I travel a lot. To save battery when I’m away from home, I often ssh back into my home desktop, both so I have persistent state even if my laptop battery dies, and so I get much faster builds that don’t kill the battery. This has two small problems: For a long time I solved 1. by enabling “Power On" after "Restore AC Power Loss” in the BIOS and 2. with tailscale . However, I recently installed Arch with an encrypted boot partition, which means that boot doesn’t finish until I type in the encryption password. Well. Well. What if I Simply put tailscale in initramfs? In which our intrepid heroes chart the challenges to come. Oh, right. If you weren’t aware, early boot in a Linux operating system 1 is just running a full second operating system that happens to be very small, lol. That’s loaded from a compressed archive file in /boot 2 and run from memory, with no access to persistent storage. This OS running from memory is called initramfs (initial RAM filesystem). So when you see a screen like this: That’s actually a whole-ass OS, with an PID and service management and everything. This is how, for example, can show you stats about early boot — there’s another copy of systemd running in initramfs, and it passes its state off to the one in the main OS. Well. That implies we can install things on it ^^. There’s three parts to this: We also want to make this as secure as possible, so there’s some more things to consider: We can solve this in a few ways: Some background about Tailscale’s ACLs (“access control lists”). Tailscale’s users are tied to their specific login method: you can, for example, add a passkey, but that passkey counts as a fully separate user than your original account. Tailscale also has “groups” of users, which are what they sound like, “ auto groups ”, which again are what they sound like, “hosts”, which are a machine connected to the network, and “tags”. Tags are odd, I haven't seen anything like them before. They group hosts, not users, and when you add a tag to a host, that counts as its login method , rather than the host being tied to a user account. A consequence of this is that the group does not include tagged machines, because tagged machines aren’t tied to a user account. (A second consequence is that you can’t remove all tags from a machine without logging out and logging back in to associate it with your user account.) So we can write a policy like this: This says “allow devices tied to a user account to access any other device, and allow no permissions at all for devices tied to a tag”. here is my desktop, and is its initramfs. 3 Because initramfs is just a (mostly) normal Linux system, that means it has its own PID 1. On Arch, that PID is in fact just systemd. That means that we can add systemd services to initramfs! There's a whole collection of them in ( is the tool Arch uses to regenerate initramfs). We need two services: an SSH server (I went with ) and something to turn on networking, which this collection names . It's possible to run directly, rather than having a separate SSH server, but I didn't find any way to configure tailscale's SSH command, and I don't want to let anyone have a shell in my initramfs. In which our heroes execute their plan flawlessly, sneaking in without a sound. If you follow these steps on an Arch system, you should end up with roughly the same setup as I have. Most of these commands assume you are running as root. Install the dropbear SSH server: Install the systemd packages: Add networking ( ), tailscale ( ), and dropbear ( ) to : Set up the keys for your new tailscale device: In the tailscale web console , mark your new device with , and disable key expiry. It should look something like this: In , configure dropbear to only allow running the unlock command and nothing else: Tell systemd to wait forever for a decryption password. I use , so I edited . Under , I extended the existing to . 4 Copy your public keys into so they get picked up by the dropbear hook: Generate a new public/private keypair for use by the dropbear server. Without this, the dropbear hook will try to load keys from openssh, which means they'll be shared between early boot and your normal server. In particular that would mean your SSH server private keys would be stored unencrypted in initramfs. Setup early networking. (Note: these instructions are only for Ethernet connections. If you want WiFi in early boot, good luck and godspeed.) All this rigamarole is necessary because the OS doesn't set the network interfaces to predictable names until late boot, so it needs some way to know which interface to use. Last but not least, rebuild your initramfs: . Next time you reboot, you should be able to ssh into and get a prompt that looks like this: In which a moral is imparted, and our scene concluded. The takeaway here is the same as in all my other posts: if you think something isn't possible to do with a computer, have you considered applying more violence? and I believe in Windows, although I’m less sure about that ↩ sometimes /boot/EFI ↩ Here “initrd” stands for “initramdisk”, which is another word for our initramfs system. ↩ See the docs for more information about this. ↩ Sometimes my home loses power and the desktop shuts off. Sometimes when the power comes back on it has a new public IP. Networking in initramfs Tailscale in initramfs SSH in initramfs Putting tailscale in initramfs means that it has unencrypted keys lying around. Tailscale keys expire (by default) after 90 days. At that point this will all break. You really really don’t want people to get SSH access to your early boot environment. Use Tailscale ACLs to only allow incoming connections to initramfs, not outgoing connections. Set the key to never expire. Set the SSH server to disallow all shells except the actual unlock command ( ). Install the dropbear SSH server: Install the systemd packages: Add networking ( ), tailscale ( ), and dropbear ( ) to : Set up the keys for your new tailscale device: In the tailscale web console , mark your new device with , and disable key expiry. It should look something like this: In , configure dropbear to only allow running the unlock command and nothing else: Tell systemd to wait forever for a decryption password. I use , so I edited . Under , I extended the existing to . 4 Copy your public keys into so they get picked up by the dropbear hook: Generate a new public/private keypair for use by the dropbear server. Setup early networking. (Note: these instructions are only for Ethernet connections. If you want WiFi in early boot, good luck and godspeed.) Add the following config in : Register it in so it gets picked up by the hook: Last but not least, rebuild your initramfs: . and I believe in Windows, although I’m less sure about that ↩ sometimes /boot/EFI ↩ Here “initrd” stands for “initramdisk”, which is another word for our initramfs system. ↩ See the docs for more information about this. ↩

0 views
Jason Scheirer 4 months ago

Steam on non-Conventional Desktops (Niri)

I’m trying out Niri ! You know how I encourage getting used to the defaults ? Well I’m not following my own advice ! I’m using it with Dank Shell too, also ignoring my own advice ! Anyhow! One liner! If Steam isn’t working do this: edit and change the line to this:

0 views