I have a dual boot on my desktop pc: Windows 11 and Ubuntu Linux. I hardly every use the Windows installation. Maybe for some games, but Steam has gotten better and better at supporting games on Linux. Or when you need to login on some government website with your eID and you can’t use the ItsMe app.
Many moons ago I did a boo-boo: for some reason I felt that I had to make my EFI system partition bigger. Which also meant resizing and moving all other partitions. Linux didn’t flinch but Windows pooped in its pants. Apparently that operating system is soooo legacy that it can’t cope with a simple partition move. I tried to fix it using a Windows system repair disk but the damn thing just couldn’t be arsed.
For a long time I just couldn’t be bothered with any further repair attempts. I don’t need that Windows anyway. I can always run Windows in VirtualBox if I really need it. It also means that I can nuke a 414 GiB partition and use that space for better things. As you can see in the screenshot, I mounted it on /mnt/windows with the intention of copying the directory Users/Amedee to Linux, in case there was still something of value there. Probably not, but better safe than sorry.
There’s just one small snag: for the life of me, I couldn’t find a Windows activation key, or remember where I put it. It’s not an OEM PC so the key isn’t stored in the BIOS. And I didn’t want to waste money on buying another license for an operating system that I hardly ever use.
I googled for methods to retrieve the Windows activation key. Some methods involve typing a command on the command prompt of a functioning Windows operating system, so those were not useful for me. Another method is just reading the activation key from the Windows Registry:
I don’t need a working Windows operating system to read Registry keys, I can just mount the Windows filesystem in Linux and query the Registry database files in /Windows/System32/config/. I found 2 tools for that purpose: hivexget and reglookup.
hivexget
This one is the simplest, it directly outputs the value of a registry key.
It wasn’t long until my bug got confirmed. Someone else chimed in that they had also experienced USB issues. In their case it were external drive devices. Definitely a showstopper!
As of this date, there is a beta for Ubuntu 22.04, and my hope is that this version will either include a new enough kernel (5.16 or up), or that Ubuntu developers have manually cherry-picked the commit that fixes the issue. Let’s check with the Ubuntu Kernel Team:
Oops… based on upstream 5.15… that’s not good. Maybe they cherry-picked upstream commits? I checked https://packages.ubuntu.com/jammy/linux-generic and the kernel is currently at 5.15.0.25.27. The changelog doesn’t mention anything about xhci or usb. I guess I still have to wait a bit longer…
Now that I have a way to compile kernels from source, I want to find the exact commit where my input devices stop working. That means doing a git checkout of a certain commit, build the kernel, install it, reboot, select the new kernel in Grub, and see if my keyboard works. I am quite sure that I need to search between 5.13.0-22 and 5.13.0-23, but that’s still 634 commits!
This is where git bisect comes in. It’s sort of a wizard that guides you to find a bad commit. You tell it on which commit your software was known to work ok, and a commit where it doesn’t. It then picks a commit somewhere in the middle, you build your software and do your tests, and then tell git bisect if the result was good or bad. It will then give you a new commit to inspect, each time narrowing the search.
Let’s do this!
$ git bisect start
$ git bisect good Ubuntu-5.13.0-22.22
$ git bisect bad Ubuntu-5.13.0-23.23
Bisecting: 316 revisions left to test after this (roughly 8 steps)
[398351230dab42d654036847a49a5839705abdcb] powerpc/bpf ppc32: Fix BPF_SUB when imm == 0x80000000
$ git describe --long
Ubuntu-5.13.0-22.22-317-g398351230dab
In this first step, I get the 317th commit after 5.13.0-22. Let’s compile that commit:
$ time make clean olddefconfig bindeb-pkg \
--jobs=$(getconf _NPROCESSORS_ONLN) \
LOCALVERSION=-$(git describe --long | tr '[:upper:]' '[:lower:]')
This creates 3 .deb packages in the directory above:
Now I can reboot, select the new kernel in Grub, and test the keyboard. With commit 317, the keyboard worked, so the first bad commit has to be somewhere between commit 317 and 634:
$ git bisect good ; git describe --long
Bisecting: 158 revisions left to test after this (roughly 7 steps)
[79b62d0bba892e8367cb46ca09b623c885852c29] drm/msm/a4xx: fix error handling in a4xx_gpu_init()
Ubuntu-5.13.0-22.22-475-g79b62d0bba89
Now it’s time again for make clean olddefconfig bindeb-pkg, dpkg --install and reboot. Turns out that commit 475 was a “bad” commit (one where the keyboard didn’t work):
$ git bisect bad ; git describe --long
Bisecting: 78 revisions left to test after this (roughly 6 steps)
[c3d35f3acc3a11b726959c7b2c25ab9e46310273] USB: serial: option: add Telit LE910Cx composition 0x1204
Ubuntu-5.13.0-22.22-396-gc3d35f3acc3a
I’m not going to describe all the steps in full detail, by now you should get the gist of it. This was the sequence of steps that git bisect gave me:
$ git bisect bad ; git describe --long
0fc979747dece96c189bc29ef604e61afbddfa2a is the first bad commit
commit 0fc979747dece96c189bc29ef604e61afbddfa2a
Author: Pavankumar Kondeti <pkondeti@codeaurora.org>
Date: Fri Oct 8 12:25:46 2021 +0300
xhci: Fix command ring pointer corruption while aborting a command
BugLink: https://bugs.launchpad.net/bugs/1951880
commit ff0e50d3564f33b7f4b35cadeabd951d66cfc570 upstream.
The command ring pointer is located at [6:63] bits of the command
ring control register (CRCR). All the control bits like command stop,
abort are located at [0:3] bits. While aborting a command, we read the
CRCR and set the abort bit and write to the CRCR. The read will always
give command ring pointer as all zeros. So we essentially write only
the control bits. Since we split the 64 bit write into two 32 bit writes,
there is a possibility of xHC command ring stopped before the upper
dword (all zeros) is written. If that happens, xHC updates the upper
dword of its internal command ring pointer with all zeros. Next time,
when the command ring is restarted, we see xHC memory access failures.
Fix this issue by only writing to the lower dword of CRCR where all
control bits are located.
Cc: stable@vger.kernel.org
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20211008092547.3996295-5-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/usb/host/xhci-ring.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
Ubuntu-5.13.0-22.22-387-g0fc979747dec
At first sight the commit description is quite cryptic, and the actual code change doesn’t tell me a lot either. But it’s a change in drivers/usb/host/xhci-ring.c, and xhci stands for eXtensible Host Controller Interface, and interface specification for USB host controllers. If it’s an issue with the USB host controller, then it makes sense that if I use 2 keyboards from different brands, neither of them would work. It also suggests that other USB devices, like external hard drives, wouldn’t work either, but that’s a bit harder to test. A keyboard is easy. Just look at NumLock LED, if it doesn’t go on then there’s an issue.
The first link in the commit description is just a long list of patches that were taken from upstream and integrated in the Ubuntu kernel, so that doesn’t help me. The second link is a thread on the kernel.org mailing list, and there it gets interesting.
Some excerpts from the thread:
This patch cause suspend to disk resume usb not work, xhci_hcd 0000:00:14.0: Abort failed to stop command ring: -110.
youling257
Thanks for the report, this is odd. Could you double check that by reverting this patch resume start working again. If this is the case maybe we need to write all 64bits before this xHC hardware reacts to CRCR register changes. Maybe following changes on top of current patch could help:
Mathias Nyman
Every time a developer says “this is odd”, my alarm bells go off. 😀
Further down in the thread there is a proposed update to the change. I’m going to try that patch, but that’s for another blog post.
Kernel ubuntu-5.13.0-22.22-0-g3ab15e228151 is, for all intents and purposes, the same as kernel 5.13.0-22-generic, so I expected it to be a “good” kernel, and it was.
For kernel Ubuntu-5.13.0-23.23 I did the same thing: starting from the git checkout. I skipped copying and editing the config file, because between minor releases I don’t expect there to be much change. I did run make olddefconfig for good measure, though. As expected, the keyboard and mouse didn’t work with the compiled ...-23 kernel.
Next up: using git bisect to find the exact commit where it went wrong. It’s got to be somewhere between ...-22 and ...-23!
As I wrote previously, I’m suspecting a Linux kernel bug somewhere between versions 5.13.0-22 and 5.13.0-23, in the Ubuntu kernels. I wanted to know if the issue only surfaced in Ubuntu-flavored kernels, or also in the upstream (mainline) kernels from kernel.org.
There is an Ubuntu Mainline PPA with all the upstream kernels, but I found it a bit too opaque to use. Fortunately I found the Ubuntu Mainline Kernel Installer (UMKI), a tool for installing the latest Linux kernels on Ubuntu-based distributions.
The UMKI is pretty straightforward. It fetches a list of kernels from the Ubuntu Mainline PPA and a GUI displays available and installed kernels, regardless of how they were installed. It installs the kernel, headers and modules. There is also a CLI client.
With that out of the way, there’s the matter of deciding which kernels to try. The “interesting” Ubuntu kernels are 5.13.0-22 and 5.13.0-23, so the mainline kernels I definitely want to test, are around those versions. That means 5.13.0 and 5.13.1. I also want to try the latest 5.13.x kernel, so that’s 5.13.19, and the most recent stable kernel, 5.16.11 (as of 2022-03-01).
To summarize, I have tested these mainline kernels:
5.13.0
5.13.1
5.13.19
5.16.11
The result (after several reboots)? With all of them, my keyboard and mouse worked without a hitch. That means the issue most likely doesn’t occur in (stable) mainline kernels, only in kernels with additional patches from Ubuntu.
The operating system on my computer is Ubuntu Linux, version 21.10 (Impish Indri). Recently I had an issue that, after a kernel update (and reboot), my USB keyboard and mouse didn’t work any more in the login screen. Huh, that’s unexpected. The issue was:
At the Grub boot menu, the keyboard works: I can use the keys, the numlock led lights up, the LCD of the Logitech G19 displays a logo.
At the Ubuntu login screen, the keyboard (and the mouse) went dark: no backlight of the keys, no numlock led, no logo on the display. And the mouse cursor didn’t move on screen.
Must be a problem at my end, I initially thought, because surely, something so essential as input devices wouldn’t break by a simple kernel update? So I did some basic troubleshooting:
Have you tried to turn it off and on again?
Plug the keyboard in another USB port.
Try a different keyboard.
Start with the older kernel, which was still in the Grub menu. And indeed, this gave me back control over my input devices!
So if the only thing I changed was the kernel, then maybe it’s a kernel bug after all?
I know that Ubuntu 21.10 uses kernel 5.something, and I know that I use the generic kernels. So which kernels are we talking about, actually?
$ apt-cache show linux-image-5*-generic | grep Package: | sed 's/Package: //g'
linux-image-5.13.0-19-generic
linux-image-5.13.0-20-generic
linux-image-5.13.0-21-generic
linux-image-5.13.0-22-generic
linux-image-5.13.0-23-generic
linux-image-5.13.0-25-generic
linux-image-5.13.0-27-generic
linux-image-5.13.0-28-generic
linux-image-5.13.0-30-generic
9 kernels, that’s not too bad. All of them 5.13.0-XX-generic. So I just installed all the kernels:
I tried all these kernels. The last kernel where my input devices still worked, was 5.13.0-22-generic, and the first where they stopped working, was 5.13.0-23-generic. Which leads me to assume that some unintended change was introduced between those two versions, and it hasn’t been fixed since.
For now, I’m telling Ubuntu to keep kernel 5.13.0-22-generic and not upgrade to a more recent version.
$ sudo apt-mark hold linux-image-5.13.0-22-generic
linux-image-5.13.0-22-generic set on hold.
I also want Grub to show me the known working kernel as the default change. To do that, I’ve put this in /etc/default/grub:
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 5.13.0-22-generic"
followed by sudo update-grub.
I’ll do the following things next, to get to the bottom of this:
Compile kernels from source, to hopefully find the exact change that caused the USB input devices to stop working. git bisect helps a lot in narrowing down the broken commit.
Een alinea in het artikel trok vooral mijn aandacht:
Van west naar oost slingert er een brede grillige vulkanische gordel onder ons land, van Diksmuide en Oostende over de taalgrens via Halle naar Hoei, Gembloux en Visé en andere Ardense plekken en Duitsland. Als ons land 4 kilometer groter was, dan hadden we warempel een nog bovengronds zichtbare vulkaan: die van Ormont, 4 kilometer over de Belgisch – Duitse grens. Dat is echt een “groentje” want daterend uit de laatste ijstijd.
Daaronder stond deze foto:
Met als bijschrift:
De nog zichtbare vulkaanvorm van Ormont
Zuiderhuis
Oh, cool, zo’n herkenbare vorm, dat moet zeker te zien zijn op Google Maps! Ik ga eens zien of ik die vulkaan kan vinden. Volg met mij mee: ga naar https://www.google.com/maps/place/Ormont,+Germany en zet de terreinlaag aan, zodat je de topografie ziet.
In het noordoosten van Ormont lijken de hoogtelijnen iets te vormen dat met een beetje verbeelding heel misschien een vulkaan zou kunnen zijn. Helaas is er in Duitsland geen Google Street View, dus op die manier kan ik het niet bevestigen.
Maar die hoogtelijnen… ik voel dat er iets niet klopt… dat is een zacht glooiend landschap, en er is geen echt duidelijk afgetekende “berg” zoals op de foto op de VRT-site.
Euhm, nee, dat landschap komt totaal niet overeen met de foto op de VRT-site.
Ik zoek verder op Google naar Ormont en ik vind iets op mindat.org, een internationale database van mineralen en mijnbouw: https://www.mindat.org/loc-214158.html. Op het kaartje daar staat een mijn genaamd “Goldberg” aangeduid:
En inderdaad, die mijn is ook goed te zien op Google Maps:
Er is trouwens geen goud te vinden in de Goldberg mijn, maar wel augiet, biotiet, diopsied, forsteriet, magnetiet, nefelien en sanidien. Voor de kenners: dat zijn allemaal mineralen die in magma te vinden zijn, dus die mijn ligt inderdaad op een vulkaan.
Maar waar komt de foto van de VRT dan wel vandaan? Bij het zoeken op Google naar “Ormont” had ik die foto ook al zien passeren. Ik heb dan Google Reverse Image Search gebruikt, en ik vond direct de bron op Wikipedia, namelijk het was inderdaad Ormont… in de Vogezen in Frankrijk: https://www.wikiwand.com/fr/Ormont_(montagne)!
Dit staat in de metadata van de Franse foto:
Genomen op 1 februari 2008 met een Nikon Coolpix S500
Op 17 februari 2008 geëxporteerd naar JPEG in Adobe Photoshop Elements 2.0
Op 29 februari 2008 toegevoegd aan Wikipedia door user Ji-Elle als eigen werk, en in public domain domain geplaatst
Beschrijving: “Robache (Saint-Dié des Vosges, France) au pied du massif de l’Ormont”
Ik kon de exacte locatie van de foto niet vinden, maar als ik op Google Maps 48.3068505N, 6.9732091E neem (Route Forestiere du Paradis, Robache), overschakel naar Street View, en dan pal oostwaarts kijk, dan herken ik de berg, inclusief de antenne op de top. Dat heeft me wel wat meer tijd op Google Maps gekost dan het duurde om deze blogpost te schrijven… 😅
Op Wikipedia zeggen ze nog het volgende over de Ormont in Robache:
Formée au cœur d’un bassin permien, la partie élevée de la montagne est supportée par des alternances de couches de grès et d’argiles.
Dat wil zeggen, afwisselende lagen van zandsteen en klei. Dus zeker geen vulkaan!
Ik bracht de redactie daarvan op de hoogte, en de foto werd inmiddels aangepast.
De nieuwsombudsman wil u ook danken voor uw kritische opmerking. Verder wensen wij u de komende dagen veel warmte, solidariteit en een goede gezondheid.
Met vriendelijke groeten, Ine Verhulst, medewerker van Tim Pauwels VRT Nieuwsombudsman
Suppose you have a couple of .dll files that were built on a TeamCity server and you want to bundle them into a NuGet package and publish them on nuget.org, how would you do that if you were a Linux user? Is that even possible??? Let’s find out!
Preparation
First things first, lets create a clean working environment:
mkdir -p ~/repos/qa-nugetlinux
cd qa-nugetlinux
git init
gi linux,vagrant >> .gitignore
git add .gitignore
git commit -m ".gitignore created by https://www.gitignore.io/api/linux,vagrant"
vagrant init --minimal ubuntu/yakkety64
git add Vagrantfile
git commit -m "Add Vagrantfile"
vagrant up --provider virtualbox
This creates a Vagrant box where I will conduct my experiments. Let’s dive in and make sure that everything is up-to-date inside:
file nuget.exe
nuget.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows
Oops, silly me. It’s a Mono executable.
mono nuget.exe
The program 'mono' is currently not installed. You can install it by typing:
sudo apt install mono-runtime
Thank you for that helpful message, Ubuntu!
sudo apt-get -y install mono-runtime
16 MiB later, I try again:
mono nuget.exe
Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies.
File name: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
at NuGet.CommandLine.Program.Main (System.String[] args) in :0
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies.
File name: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
at NuGet.CommandLine.Program.Main (System.String[] args) in :0
System.Core is missing? OK let’s install that.
sudo apt-get -y install libmono-system-*
And try again:
mono nuget.exe
Could not load file or assembly or one of its dependencies.
Sigh. Ok, let’s use a cannon to shoot a mosquito:
sudo apt-get -y install mono-complete
Does it work now?
mono nuget.exe
NuGet Version: 3.4.4.1321
usage: NuGet [args] [options]
Type 'NuGet help ' for help on a specific command.
Available commands:
add Adds the given package to a hierarchical source. http sources are not supported. For more info, goto https://docs.nuget.org/consume/command-line-reference#add-command.
config Gets or sets NuGet config values.
delete Deletes a package from the server.
help (?) Displays general help information and help information about other commands.
init Adds all the packages from the to the hierarchical . http feeds are not supported. For more info, goto https://docs.nuget.org/consume/command-line-reference#init-command.
install Installs a package using the specified sources. If no sources are specified, all sources defined in the NuGet configuration file are used. If the configuration file specifies no sources, uses the default NuGet feed.
list Displays a list of packages from a given source. If no sources are specified, all sources defined in %AppData%NuGetNuGet.config are used. If NuGet.config specifies no sources, uses the default NuGet feed.
locals Clears or lists local NuGet resources such as http requests cache, packages cache or machine-wide global packages folder.
pack Creates a NuGet package based on the specified nuspec or project file.
push Pushes a package to the server and publishes it.
NuGet's default configuration is obtained by loading %AppData%NuGetNuGet.config, then loading any nuget.config or .nugetnuget.config starting from root of drive and ending in current directory.
restore Restores NuGet packages.
setApiKey Saves an API key for a given server URL. When no URL is provided API key is saved for the NuGet gallery.
sources Provides the ability to manage list of sources located in %AppData%NuGetNuGet.config
spec Generates a nuspec for a new package. If this command is run in the same folder as a project file (.csproj, .vbproj, .fsproj), it will create a tokenized nuspec file.
update Update packages to latest available versions. This command also updates NuGet.exe itself.
For more information, visit http://docs.nuget.org/docs/reference/command-line-reference
cd ~/vagrant/itextcore-dotnet/itext/itext.barcodes/
mono ~/vagrant/nuget.exe pack itext.barcodes.csproj -verbosity detailed
Attempting to build package from 'itext.barcodes.csproj'.
MSBuild auto-detection: using msbuild version '4.0' from '/usr/lib/mono/4.5'. Use option -MSBuildVersion to force nuget to use a specific version of MSBuild.
System.NotImplementedException: The method or operation is not implemented.
at (wrapper dynamic-method) System.Object:CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,object)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0] (System.Runtime.CompilerServices.CallSite site, System.Dynamic.T0 arg0) in :0
at NuGet.CommandLine.ProjectFactory.ResolveTargetPath () in :0
at NuGet.CommandLine.ProjectFactory.BuildProject () in :0
at NuGet.CommandLine.ProjectFactory.CreateBuilder (System.String basePath) in :0
at NuGet.CommandLine.PackCommand.BuildFromProjectFile (System.String path) in :0
at NuGet.CommandLine.PackCommand.BuildPackage (System.String path) in :0
at NuGet.CommandLine.PackCommand.ExecuteCommand () in :0
at NuGet.CommandLine.Command.ExecuteCommandAsync () in :0
at NuGet.CommandLine.Command.Execute () in :0
at NuGet.CommandLine.Program.MainCore (System.String workingDirectory, System.String[] args) in :0
That seems like a big ball of NOPE to me… According to this GitHub comment from a NuGet member, this is to be expected.
Hand Crank the .nuspec File
So it’s going to be the hard way.
<TO BE CONTINUED> This blog post was a draft, and I decided to publish whatever I had already, and if anyone is ever interested, I may or may not finish it. ¯_(ツ)_/¯