You are not logged in.

#1 Yesterday 15:15:49

Enrico1989
Member
Registered: 2018-07-05
Posts: 297

How do I programmatiaclly compare installed and running kernel?

This is a spin off of my earlier question [SOLVED] How can I investigate USB not being detected?

I'm looking for a simple but reliable solution to programmatically tell whether I'm running the installed kernel or an older one. So I can make this info available in a statusbar or somewhere in a catchy way that reminds to perform a reboot.

From the linked question, it seemed obvious: compare the output of "uname -r" and the output of "pacman -Q linux".

Except that (after a few minutes wondering thining I was getting the bash syntax wrong) even when you're running the installed kernel, the former is not a prefix of the latter:

      6.18.13-arch1-1 # dash
linux 6.18.13.arch1-1 # dot

are these outputs' formats guaranteed? E.g. can I just turn the first dash of "uname -r" to a dot and expect the whole string to be a subfix of "pacman -Q linux" (if I'm running the installed kernel, obviously)?

Offline

#2 Yesterday 15:30:06

gromit
Administrator
From: Germany
Registered: 2024-02-10
Posts: 1,498
Website

Re: How do I programmatiaclly compare installed and running kernel?

Offline

#3 Yesterday 15:40:42

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,325

Re: How do I programmatiaclly compare installed and running kernel?

For a lazy hack

modinfo -n i915 >/dev/null 2>&1 || echo wahhh

The arch-update will screw you when you end up booting a dated kernel.

Offline

#4 Yesterday 15:46:59

cryptearth
Member
Registered: 2024-02-03
Posts: 1,975

Re: How do I programmatiaclly compare installed and running kernel?

unless you automate (background) updates this shouldn't be a question at all just by either rebooting everytime you update the kernel or don't update the kernel if you're not ready to reboot
or am i missing something deeper?

Offline

#5 Yesterday 16:03:45

Enrico1989
Member
Registered: 2018-07-05
Posts: 297

Re: How do I programmatiaclly compare installed and running kernel?

cryptearth wrote:

unless you automate (background) updates this shouldn't be a question at all just by either rebooting everytime you update the kernel or don't update the kernel if you're not ready to reboot
or am i missing something deeper?

I might be a bit naive, but before updating I tend to only check https://archlinux.org/. If there's no news since last time I checked, I proceed to update without even looking at what I'm updating, and this approach has never fired back in almost 10 years.

Last edited by Enrico1989 (Yesterday 16:04:37)

Offline

#6 Yesterday 17:22:22

cryptearth
Member
Registered: 2024-02-03
Posts: 1,975

Re: How do I programmatiaclly compare installed and running kernel?

Enrico1989 wrote:

I proceed to update without even looking at what I'm updating, and this approach has never fired back in almost 10 years.

well, if you reboot afterwards this isn't a problem ... although not looking at the output or at least what's updated before proceeding is not recommended and the cause of the issue you encountered

Offline

#7 Yesterday 21:29:06

GerBra
Forum Fellow
From: Bingen/Germany
Registered: 2007-05-10
Posts: 250

Re: How do I programmatiaclly compare installed and running kernel?

Enrico1989 wrote:

are these outputs' formats guaranteed? E.g. can I just turn the first dash of "uname -r" to a dot and expect the whole string to be a subfix of "pacman -Q linux" (if I'm running the installed kernel, obviously)?

I'm facing the same/similar problem yesterday working on a script.

The problem is that uname -r outputs differ from the package version strings. You have found one difference, with other kernel packages it's more difficult. So the zen kernel shows:
uname -r: 6.18.13-zen1-1-zen
pacman -Qi: 6.18.13.zen1-1
Same with ex. the -lts kernel.

My approach is something like this:

check_this="/usr/lib/modules/$(uname -r)/pkgbase"

if [[ -e "$check_this" ]]; then
  echo "Running installed kernel..."
else
  echo "Running kernel doesn't match kernel package!"
fi

So the kernel modules dir name (/usr/lib/modules/foo_bar) should match the "uname -r" value when running kernel == installed kernel.
I match on the file pkgbase in this dir cause you could read it also easily into a variable to get the package name of the running kernel.


My avatar: "It's not just a toilet... a FERGUSON. The King of bowls. Sit down and give me your best shot." Al Bundy

Offline

#8 Yesterday 21:51:19

Antiz
Member
From: France
Registered: 2022-06-04
Posts: 15
Website

Re: How do I programmatiaclly compare installed and running kernel?

seth wrote:

For a lazy hack

modinfo -n i915 >/dev/null 2>&1 || echo wahhh

The arch-update will screw you when you end up booting a dated kernel.

Well, the statement about arch-update would technically be true on other distros but it shouldn't be an issue on Arch Linux since we don't keep old kernel(s) around.

Cool lazy hack BTW smile

Last edited by Antiz (Yesterday 21:51:59)


Arch Linux Package Maintainer

Offline

#9 Yesterday 21:54:19

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,325

Re: How do I programmatiaclly compare installed and running kernel?

since we don't keep old kernel(s) around

Tell that all the people who's boot partition and mountpoint are out of sync tongue

Offline

#10 Yesterday 21:57:02

Antiz
Member
From: France
Registered: 2022-06-04
Posts: 15
Website

Re: How do I programmatiaclly compare installed and running kernel?

seth wrote:

since we don't keep old kernel(s) around

Tell that all the people who's boot partition and mountpoint are out of sync tongue

Haha well... sure, I have no doubt people can come up with creative way to break stuff tongue

I might adopt your "hack" actually... Might be more robust I guess.


Arch Linux Package Maintainer

Offline

#11 Yesterday 22:07:22

seth
Member
From: Don't DM me only for attention
Registered: 2012-09-03
Posts: 73,325

Re: How do I programmatiaclly compare installed and running kernel?

nb. it hinges on the idea of i915 being an available and not compiled in module - you might also go for something else (vfat) but the "not compiled in" part is obviously unreliable w/ every kernel update.
Testing "/usr/lib/modules/$(uname -r)/pkgbase" is a good idea if you're exclusively interested in pacman controlled kernel installations.

Offline

#12 Yesterday 22:13:37

Antiz
Member
From: France
Registered: 2022-06-04
Posts: 15
Website

Re: How do I programmatiaclly compare installed and running kernel?

seth wrote:

nb. it hinges on the idea of i915 being an available and not compiled in module - you might also go for something else (vfat) but the "not compiled in" part is obviously unreliable w/ every kernel update.
Testing "/usr/lib/modules/$(uname -r)/pkgbase" is a good idea if you're exclusively interested in pacman controlled kernel installations.

Yep, I exclusively care about pacman controlled kernel installation. Testing "/usr/lib/modules/$(uname -r)/pkgbase" is close to what I'm already doing but in a more elegant and robust way I guess. I might do that smile
Thanks!

Last edited by Antiz (Yesterday 22:32:56)


Arch Linux Package Maintainer

Offline

#13 Yesterday 23:51:15

GerBra
Forum Fellow
From: Bingen/Germany
Registered: 2007-05-10
Posts: 250

Re: How do I programmatiaclly compare installed and running kernel?

Antiz wrote:

I guess. I might do that smile Thanks!

(First: sorry my english isn't the best!)

I'm mostly interested (workflow) on package updates before the operation gets started with pacman -Syu. So I'm using checkupdates tool¹ and it's list of possible package updates.

Currently I'm experimenting with eww² "widgets" and a widget on pacman operations/informations.
I always has something "visible" that shows me the numer of updates (checkupdates|wc -l) and a possibility to get a list of outstanding updates (checkupdates). For displaying this list i always use fzf³

Myself update not often, so i could easily have a list of >100 packages. Now i thought: Hej, why not have a warning hint
in my fzf output when my running kernel is in the list of outstanding updates?
I use fzf's --preview window for this (and also when archlinux-keyring and pacman are in the list).

checkupdate's output ist:
package_name current_version -> new_version

How to find if "my" current kernel package (which could be any archlinux kernel package) in this list?
Ok, uname give the current version, and there are version strings in the output, so let's grep. At this point i run into the OP's problem.
Parsing and modifying uname and pacman versions need a lot of awk/sed/tr - not the best way.
So: all i really need is the **package name** of "my" running kernel.

And there i found /usr/lib/modules/$(uname -r)/pkgbase, which give me exactly this. Now i only have to grep the (kernel) package name in checkupdates output list to present my pre-update warning: Reboot ASAP after doing the real update.

Cause my workflow is before any "destructive" i could be sure that this /usr/lib/modules/ dir exists AND the pkgbase file. In "pacman language" a pre-hook situation.

But in this thread it could also be used in a post-hook situation, eg. when the filesystem structure was already modified.
Ideally the whole "old" /usr/lib/modules/$(uname -r) directory don't exist anymore and/or the pkgbase isn't there.
Both tests should give a strong hint that the running kernel was updated.

¹ pacman-contrib

² https://github.com/elkowar/eww

³ https://wiki.archlinux.org/title/Fzf


My avatar: "It's not just a toilet... a FERGUSON. The King of bowls. Sit down and give me your best shot." Al Bundy

Offline

#14 Today 01:10:59

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 490

Re: How do I programmatiaclly compare installed and running kernel?

Enrico1989 wrote:

are these outputs' formats guaranteed?

The format doesn't seem to be guaranteed. For example, linux-hardened package has version

6.17.13.hardened1-3

but the kernel's release string is

6.17.13-hardened1-3-hardened

So you can't just replace dot with dash or vice versa.

In addition to methods mentioned in the original thread, you can also read "/usr/lib/modules/$(uname -r)/pkgbase". Of cource, this also works only if the package is not yet updated, e.g. right after boot or in PreTransaction hook.

Last edited by dimich (Today 01:17:05)

Offline

#15 Today 01:25:32

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 490

Re: How do I programmatiaclly compare installed and running kernel?

If you just want to check whether reboot is required due to kernel update, simply test presence of "/usr/lib/modules/$(uname -r)/kernel" directory after update.

Offline

#16 Today 01:48:50

NuSkool
Member
Registered: 2015-03-23
Posts: 287

Re: How do I programmatiaclly compare installed and running kernel?

I faced the same issue you're having with package and uname formatting differences.
In my syuscript I avoid the package names all together with the following.
Not sure this is useful for your use case though...

    kernel_check(){
    
    	file /boot/vmlinuz* |
    	awk '/Linux kernel x86 boot executable/ {
    		split($1, a, "-");
    		kernel_type = a[3] ? a[2] "-" a[3] : a[2];
    		sub(/:$/, "", kernel_type);
    		match($0, /version ([^ ]+)/, v);
    		if (v[1]) {print kernel_type, v[1]}
    		}'
    }
    
    	kernel_check > /tmp/kern-before
    
    	printf '\n%s\n\n' "${BC}  Contents of prep4ud report ${PrepRep}: ${OFF}"
    	cat "${HOME}"/Desktop/prep4ud.dir/"${PrepRep}" 2>/dev/null || { echo "  Prep4ud report NA."; }
    
    	printf '\n%s\n\n' "${BC}  Running pacman -Syu....  ${OFF}"				|& tee_data
    	sudo pacman -Syu --color=always 							|& tee_data
    
    	kernel_check > /tmp/kern-after
    
    	printf '\n%s\n' "${BC}  Checking kernel update.... ${OFF}"				|& tee_data
    
    before=$(md5sum /tmp/kern-before | cut -d" " -f1)
    after=$(md5sum /tmp/kern-after | cut -d" " -f1)
    
    if	[[ ${after} != ${before} ]]; then
    	printf '%s\n' "${BY}  Updated kernel/s:${OFF}"						|& tee_data
    	comm -23 <(sort /tmp/kern-after) <(sort /tmp/kern-before) |
    		while IFS= read -r updated_kernel; do
          		printf '%s\n' "  ${updated_kernel}${OFF}"				|& tee_data
        		done
    	printf   '%s\n' "${BY}  Running kernel:${OFF}"						|& tee_data
    	printf   '%s\n'   "  $(uname -rs | tr '[:upper:]' '[:lower:]') ${OFF}"			|& tee_data
        else
      	printf '%s\n' "${BC}  Kernel/s not updated.${OFF}"					|& tee_data
    fi

The output:

  Checking kernel update.... 

  Updated kernel/s:
  linux-lts 6.12.74-1-lts
  linux-mainline 7.0.0-rc1-1-mainline

  Running kernel:
  linux 6.18.9-arch1-2

Scripts I Use                                                 :  https://github.com/Cody-Learner
grep -m1 'model name' /proc/cpuinfo    : AMD Ryzen 7 8745HS w/ Radeon 780M Graphics
grep -m1 'model name' /proc/cpuinfo    : Intel(R) N95
grep -m1 'model name' /proc/cpuinfo    : AMD Ryzen 5 PRO 2400GE w/ Radeon Vega Graphics

Offline

#17 Today 05:53:38

cryptearth
Member
Registered: 2024-02-03
Posts: 1,975

Re: How do I programmatiaclly compare installed and running kernel?

for the sake of argue (although i still strongly recommend: keep your eyes on the screen and think before act - and reboot if you see a kernel update): how about simple string manipulation: just strip both the uname string and the package version string from anything that's not a number
although - now that i give it a thought - it already breaks between 6.18.13 and 7.0 - because 61813 is bigger than 70
forget it - just don't do blind (background) updates and reboot after an update - get a daily routine into it as running pacman and reboot the first thing you do every day - or if you can't afford the down: then don't update!

Offline

Board footer

Powered by FluxBB