Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
depclean script to protect installed kernels
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Kernel & Hardware
View previous topic :: View next topic  
Author Message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Thu Jan 21, 2021 7:05 pm    Post subject: depclean script to protect installed kernels Reply with quote

The following script will scan a directory such as /boot for kernels of the name "vmlinuz*" and generate an "emerge --depclean --exclude ..." command to prevent depcleaning the sys-kernel/gentoo-sources package slots for any of those kernels. You can pass depclean parameters on the command line, such as "--ask" in the usual way.

It doesn't handle /boot directories that need mounting before use. It's not intended to be secure or idiot proof, so it's only safe if your system has only one administrator, and that's you. It needs modification if you use a different set of kernel sources such as tuxonice or similar.

Enjoy. (or criticise)

Code:
#!/bin/sh

### Run emerge --depclean, but excluding the source for any kernels in boot directory

### Note - this is neither secure nor idiot-proof.
### It should only be run in environments where nobody will be putting strange stuff in /boot,
### or calling this script with silly parameters while running as root.
### That said, the only dangerous command is emerge --depclean, and that's pretty limited.

# Configuration option - specify your kernel directory
DIRECTORY="/boot"       # Might be /boot/efi or even /boot/efi/EFI

# Build a list of kernel versions to keep; the list contains the kernel version strings, like uname -v
keep=$(
        file -L $DIRECTORY/vmlinuz* | grep -Eo 'version [0-9.]+.*-gentoo' | sort -uV | while read txt ver
        do
                printf '%s\n' "$ver"
        done
)

# Depclean everything else.
# Note that command line parameters to this script (e.g. "--ask") get passed to the "emerge --depclean" command
for ver in $keep
do
        excludes="$excludes --exclude sys-kernel/gentoo-sources:${ver%-gentoo} "
done

emerge --depclean $excludes $*

_________________
Greybeard
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3624
Location: Rasi, Finland

PostPosted: Thu Jan 21, 2021 7:28 pm    Post subject: Reply with quote

I just emerge --noreplace <kernel_package>:<slot/version>
It should keep installed kernels away from depclean.

EDIT: Haven't ran the script yet, but looks like on the last line you should have "$@" (with the double quotes) instead of $*. Also arrays aren't supported in /bin/sh (the posix/dash ones), so maybe shebang should be #!/bin/bash?

EDIT02: Also the "keep" array can be used without the last loop creating the --exclude switches: emerge --exclude "${keep[*]}"
--exclude can take multiple package atoms separated with space, and thus the whole argument for --exclude needs to be quoted.

Note that I haven't tested this yet... Just my observations. ;)
_________________
..: Zucca :..
Gentoo IRC channels reside on Libera.Chat.
--
Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Fri Jan 22, 2021 10:52 am    Post subject: Reply with quote

Thanks for feedback.
Zucca wrote:
... Haven't ran the script yet, but looks like on the last line you should have "$@" (with the double quotes) instead of $*. Also arrays aren't supported in /bin/sh (the posix/dash ones), so maybe shebang should be #!/bin/bash?

Nope, as far as I was concerned, I was writing (AND testing) it for dash. Arrays? we don't need no stinking arrays :-)
Quote:
Also the "keep" array can be used without the last loop creating the --exclude switches: emerge --exclude "${keep[*]}"
--exclude can take multiple package atoms separated with space, and thus the whole argument for --exclude needs to be quoted....

I think I tried that version and ran into trouble with the extra quotes getting passed through to emerge; possibly one of those cases that needs eval, or maybe I'm misremembering; I'll give your version a spin.

Whatever, you need to put the "sys-kernel/gentoo-sources:" in front of each word of the "keep" string (for that's what it is).
_________________
Greybeard
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Fri Jan 22, 2021 12:16 pm    Post subject: Reply with quote

OK, here's the better version, one less loop (thanks Zucca). It's definitely OK for dash and it's ilk, no bashisms.
<edit> OOPS, forgot to check for errors such as unmounted /boot"</edit>
Code:
#!/bin/sh

### Run emerge --depclean, but excluding the source for any kernels in boot directory

### Note - this is neither secure nor idiot-proof.
### It should only be run in environments where nobody will be putting strange stuff in /boot,
### or calling this script with silly parameters while running as root.
### That said, the only command is emerge --depclean, and that's pretty limited.

# Configuration option - specify your kernel directory
DIRECTORY="/boot"       # Might be /boot/efi or even /boot/efi/EFI

# Build a list of kernel versions to keep; the grep result filters the kernel version strings, like uname -r, from file's output for kernels
keep=$(
        file -L $DIRECTORY/vmlinuz* | grep -Eo 'version [0-9.]+.*-gentoo' | sort -uV | while read -r _ ver
        do
                printf 'sys-kernel/gentoo-sources:%s ' "${ver%-gentoo}"
        done
)

if [ -z "$keep" ]
then
        printf "No kernels found in %s.  Did you forget to mount a filesystem?\n" "$DIRECTORY"
        exit 1
fi

emerge --depclean --exclude "$keep" "$@"

_________________
Greybeard


Last edited by Goverp on Sat Jan 23, 2021 9:58 am; edited 1 time in total
Back to top
View user's profile Send private message
figueroa
Advocate
Advocate


Joined: 14 Aug 2005
Posts: 3001
Location: Edge of marsh USA

PostPosted: Sat Jan 23, 2021 4:35 am    Post subject: Reply with quote

I add the kernel versions I don't want depcleaned into /var/lib/portage/world. I keep two or more kernels on board, usually three or four. When I want a kernel source depcleaned, I remove it from world. I think this goes contrary to conventional wisdom, but it's what I do. I currently have:
Code:
$ grep sources /var/lib/portage/world
sys-kernel/gentoo-sources
sys-kernel/gentoo-sources:4.19.160
sys-kernel/gentoo-sources:4.9.240
sys-kernel/gentoo-sources:5.4.80-r1

Usually the three or four sources are from the same major family, but I've been in the process of moving up.
_________________
Andy Figueroa
hp pavilion hpe h8-1260t/2AB5; spinning rust x3
i7-2600 @ 3.40GHz; 16 gb; Radeon HD 7570
amd64/23.0/split-usr/desktop (stable), OpenRC, -systemd -pulseaudio -uefi
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Sat Jan 23, 2021 10:02 am    Post subject: Reply with quote

figueroa wrote:
I add the kernel versions I don't want depcleaned into /var/lib/portage/world. ...

Understood. Depending on your bootmanager, that may be enough to decide which kernels come up. My script is so I only need to maintain the contents of /boot (or whatever). I have a glitzy script for that, a bit like eselect kernel, but with more features. When I have time, I'll put it on sourceforge or somewhere.
_________________
Greybeard
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3624
Location: Rasi, Finland

PostPosted: Sat Jan 23, 2021 11:20 am    Post subject: Reply with quote

Oh. My neurons didn't fire propely as I have quite a bad flu (tested negative for COVID-19, yay).
I thought keep was an array, but the syntax was missing an extra (). :P

I find it amusing that the output of file isn't very easily machine parseable, except for the -print0 which appends NULL-character after each filename so that one can cut out filenames containing special characters. Well. It helps some...

So I started to test if there was a clean way to parse file output...
I ended up here
Code:
$ find /boot/ -type f -name 'vmlinuz*' -exec file -L0 {} + | awk '{split($0,a,"\0"); if (a[2] ~ /^:[[:space:]]+Linux kernel/) {split(a[2],b,", version "); print substr(b[2],1,index(b[2]," ")) } }'
5.4.40
5.4.52
5.4.60
5.4.64
5.4.64-CEPTER_NY310-01_YS13G
5.4.64-CEPTER_NY310-01_YS13G
5.4.72-CEPTER_NY310-01_YS13G
5.4.83-CEPTER_NY310-01_YS13G
5.4.83-CEPTER_NY310-01_YS13G
... and gave up that route. The awk part seems too complex (and should have an extra if -statement or a pipe to uniq).
To be able to extract version string from that output one may need to use qatom, because as an example right there I have extra string appended to the kernel version string. You cannot just rely to cut from first dash (-) as, for example, -r3 can be a part of version string... This may be impossible to make fully "waterproof". There's no fully reliable way to match a kernel binary file to a ebuild... afaik. Any kernel packagers here to comment? ;)
_________________
..: Zucca :..
Gentoo IRC channels reside on Libera.Chat.
--
Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Sat Jan 23, 2021 11:31 am    Post subject: Reply with quote

I did a bit of digging on this myself, when I realized my UEFI laptop setup had three kernels - vmlinuz, vmlinuz.old and vmlinuz.new, and of course those filenames don't tell you the version. Various web things say there's a chain of offsets in the kernel file that will lead you to the release and version strings; I wasn't interested in chasing them down, so I wondered if any packages might have done the work for me. (Hence discovering "file" does. AFAIK, file makes no guarantees about it's output, so my script can stop working at any new release, but it definitely shows "version " followed by the "uname-r" release string. Since I'm only supporting gentoo-sources, the script can rely on -gentoo appearing in the release name. As an aside, you also get the version datestamp information "uname -v", so it's possible to tie the booted kernel to the file from which it was booted (assuming there are no duplicates).
_________________
Greybeard
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3624
Location: Rasi, Finland

PostPosted: Sat Jan 23, 2021 11:46 am    Post subject: Reply with quote

Yeah. That works as long as one hasn't specified CONFIG_LOCALVERSION.
_________________
..: Zucca :..
Gentoo IRC channels reside on Libera.Chat.
--
Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Sat Jan 23, 2021 3:09 pm    Post subject: Reply with quote

LOCALVERSION comes after the "-gentoo", so it works for me.
_________________
Greybeard
Back to top
View user's profile Send private message
Zucca
Moderator
Moderator


Joined: 14 Jun 2007
Posts: 3624
Location: Rasi, Finland

PostPosted: Sat Jan 23, 2021 5:15 pm    Post subject: Reply with quote

Goverp wrote:
LOCALVERSION comes after the "-gentoo", so it works for me.
Ah. Then it's not a problem.
Since I use sys-kernel/gentoo-kernel (which is sort of a Fedora kernel) on my laptop I got different results while probing kernel images.
_________________
..: Zucca :..
Gentoo IRC channels reside on Libera.Chat.
--
Quote:
I am NaN! I am a man!
Back to top
View user's profile Send private message
figueroa
Advocate
Advocate


Joined: 14 Aug 2005
Posts: 3001
Location: Edge of marsh USA

PostPosted: Sat Jan 23, 2021 5:44 pm    Post subject: Reply with quote

Goverp wrote:
I did a bit of digging on this myself, when I realized my UEFI laptop setup had three kernels - vmlinuz, vmlinuz.old and vmlinuz.new, ...

It would seem better to make vmlinuz~ to be symlinks to actual kernels with meaningful human-readable kernel filenames.
_________________
Andy Figueroa
hp pavilion hpe h8-1260t/2AB5; spinning rust x3
i7-2600 @ 3.40GHz; 16 gb; Radeon HD 7570
amd64/23.0/split-usr/desktop (stable), OpenRC, -systemd -pulseaudio -uefi
Back to top
View user's profile Send private message
Goverp
Advocate
Advocate


Joined: 07 Mar 2007
Posts: 2120

PostPosted: Sun Jan 24, 2021 1:34 pm    Post subject: Reply with quote

figueroa wrote:
... It would seem better to make vmlinuz~ to be symlinks to actual kernels with meaningful human-readable kernel filenames.


Indeed, what I do on my desktop, which uses Grub to boot. But the laptop boots using the kernel EFI stub loader directly from UEFI. That means the kernel file has to (a) have a fixed name in the EFI boot variables and (b) be in the EFI partition, which generally has to be FATish. So no symlinks or meaningful names.
_________________
Greybeard
Back to top
View user's profile Send private message
Ant P.
Watchman
Watchman


Joined: 18 Apr 2009
Posts: 6920

PostPosted: Sun Jan 24, 2021 1:50 pm    Post subject: Reply with quote

figueroa wrote:
Goverp wrote:
I did a bit of digging on this myself, when I realized my UEFI laptop setup had three kernels - vmlinuz, vmlinuz.old and vmlinuz.new, ...

It would seem better to make vmlinuz~ to be symlinks to actual kernels with meaningful human-readable kernel filenames.

That's one of the things you lose with this half-baked distro automation - the kernel makefile already does that for you automatically.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Kernel & Hardware All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum