Compare commits

..

54 commits

Author SHA1 Message Date
Denys Vlasenko
1af058e32f macros.kmp: restore previous backslash-escaping of newline in "latest_kernel" macro
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Resolves: #2108441
2025-08-12 03:59:11 +02:00
Denys Vlasenko
6e2e136a06 macros.kmp: make the "do not run rpm -qa" change less intrusive
Let's not delete "latest_kernel" macro

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Resolves: #2108441
2025-08-12 03:50:35 +02:00
Denys Vlasenko
6b9840e4cb Merge #7 Speedup macros.kmp 2025-08-12 01:41:24 +00:00
Fedora Release Engineering
4b3dba68e8 Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild 2025-07-24 18:23:31 +00:00
Andrea Bolognani
a2453a1952 Finish adding riscv64
The %kernel_arches macro has been extended to include the
architecture in commit 0f81ee97a5 but on RHEL the value gets
overwritten at package build time. Make sure we do the right
thing there too.

Thanks: Zhengyu He <hezhy472013@gmail.com>
Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2025-04-01 15:46:54 +02:00
Fedora Release Engineering
b3edcbf9d6 Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild 2025-01-17 08:38:09 +00:00
Fedora Release Engineering
cf850ea1cf Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild 2024-07-18 11:39:22 +00:00
David Abdurachmanov
0f81ee97a5 Add riscv64
Signed-off-by: David Abdurachmanov <davidlt@rivosinc.com>
2024-03-06 10:06:15 +00:00
Fedora Release Engineering
c61b1e942a Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-24 23:55:28 +00:00
Miroslav Suchý
240db1cd7b Migrate to SPDX license
This is part of https://fedoraproject.org/wiki/Changes/SPDX_Licenses_Phase_3
2024-01-23 15:11:28 +00:00
Fedora Release Engineering
66ea9d2986 Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild 2024-01-21 00:15:22 +00:00
Fedora Release Engineering
eaea3e58bc Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-07-20 08:42:13 +00:00
Eugene Syromiatnikov
39f5c4ac3d kernel-srpm-macros.spec: bump the release
* kernel-srpm-macros.spec (Release): Change to 19.
(%changelog): New record.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-20 15:55:04 +02:00
Eugene Syromiatnikov
148ee639b5 find-provides.ksyms, find-requires.ksyms: unify symbol parsing
Since the immediate symbols can be retrieved for "objdump -t" output
as well, it makes some sence to use it as the sole data source and
handle both vaiants inside the awk script.  This simplification comes
at some runtime cost for the simpler case of the immediate symbols,
though, and overall it is about 5% faster in the relative symbols case
and about the same 5% slower in the absolute symbols case, with the
latter not as important moving forward, probably:

    $ for i in ./lib/modules/*; do \
        echo "====== $i ====="; \
        diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \
        echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \
        echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \
    done
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  3.98s user 3.04s system 129% cpu 5.411 total
    new: ./find-provides.ksyms.new > /dev/null  3.78s user 3.06s system 132% cpu 5.181 total
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  6.18s user 4.00s system 124% cpu 8.161 total
    new: ./find-provides.ksyms.new > /dev/null  6.57s user 4.84s system 132% cpu 8.644 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  4.70s user 2.94s system 126% cpu 6.061 total
    new: ./find-provides.ksyms.new > /dev/null  4.37s user 3.03s system 127% cpu 5.793 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  6.66s user 4.35s system 123% cpu 8.884 total
    new: ./find-provides.ksyms.new > /dev/null  7.07s user 5.00s system 130% cpu 9.218 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  3.81s user 2.62s system 128% cpu 5.018 total
    new: ./find-provides.ksyms.new > /dev/null  3.55s user 2.56s system 128% cpu 4.743 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  13.79s user 8.59s system 125% cpu 17.817 total
    new: ./find-provides.ksyms.new > /dev/null  13.18s user 8.78s system 127% cpu 17.247 total

* find-provides.ksyms: Do not perform an intial "nm | awk" run in an attempt
to capture absolute symbols, just parse "objdump -t" output and handle both
absolute and relative symbols in the awk script based on the section name.
* find-requires.ksyms (all_provides): Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-20 15:55:04 +02:00
Eugene Syromiatnikov
28c1a86a0c find-provides.ksyms: add a short description of the parsing logic
Add a comment that, hopefully, sheds some light on what is going on in
the following code.

* find-provides.ksyms: Add a comment.

Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-20 15:55:04 +02:00
Eugene Syromiatnikov
a9123f8dde find-provides.ksyms, find-requires.ksyms: avoid iterating over sections
Since the section retrieval code is implemented inside the awk script
now, the next step is to eliminate external iteration over the section
list and just retrieve the required sections inside awk on demand.  This
allows calling (and processing the output of) objdump -t just once,
which saves around 8-12% of time on kernels that store modversions
as non-absolute symbols:

    $ for i in ./lib/modules/*; do \
        echo "====== $i ====="; \
        diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \
        echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \
        echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \
    done
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  4.41s user 3.46s system 136% cpu 5.756 total
    new: ../find-provides.ksyms.new > /dev/null  3.90s user 2.94s system 129% cpu 5.279 total
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  6.04s user 3.88s system 124% cpu 7.993 total
    new: ../find-provides.ksyms.new > /dev/null  6.08s user 3.91s system 124% cpu 8.012 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  5.09s user 3.51s system 133% cpu 6.452 total
    new: ../find-provides.ksyms.new > /dev/null  4.65s user 2.89s system 126% cpu 5.949 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  6.52s user 4.14s system 123% cpu 8.638 total
    new: ../find-provides.ksyms.new > /dev/null  6.64s user 4.12s system 123% cpu 8.690 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  4.45s user 3.29s system 136% cpu 5.661 total
    new: ../find-provides.ksyms.new > /dev/null  3.84s user 2.54s system 127% cpu 4.980 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  7.34s user 4.33s system 129% cpu 9.019 total
    new: ../find-provides.ksyms.new > /dev/null  6.67s user 3.51s system 122% cpu 8.278 total

* find-provides.ksyms: Remove "objdump -t" section loop, do not supply
sectname to the awk script, treat sectdata as an array keyed on section
name, convert section retrieval to a function with a section name
as an argument, call it if a section name is not present in sectdata.
* find-requires.ksyms (all_provides): Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-07 02:13:40 +02:00
Eugene Syromiatnikov
2264680063 find-provides.ksyms, find-requires.ksyms: avoid calling nm twice
Instead of running the nm output through grep and then running it
through awk again, run it directly through awk, and bail of immediately
if a non-absolute symbol is found.

Also, while we're here, avoid executing the indirect parsing code
if no __crc_* symbols are present at all, which shaves around 8-18% off
of the run time:

    % for i in ./lib/modules/*; do \
        echo "====== $i ====="; \
        diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \
        echo old:; find $i | time ./find-provides.ksyms.old > /dev/null; \
        echo new:; find $i | time ./find-provides.ksyms.new > /dev/null; \
    done
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  5.10s user 4.52s system 150% cpu 6.412 total
    new: ../find-provides.ksyms.new > /dev/null  4.41s user 3.48s system 136% cpu 5.764 total
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  7.80s user 6.19s system 143% cpu 9.740 total
    new: ../find-provides.ksyms.new > /dev/null  6.07s user 3.97s system 124% cpu 8.066 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  5.87s user 4.35s system 143% cpu 7.113 total
    new: ../find-provides.ksyms.new > /dev/null  5.12s user 3.56s system 132% cpu 6.533 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  8.44s user 6.78s system 144% cpu 10.535 total
    new: ../find-provides.ksyms.new > /dev/null  6.55s user 4.17s system 123% cpu 8.666 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x =====
    old: ../find-provides.ksyms.old > /dev/null  5.04s user 3.95s system 145% cpu 6.166 total
    new: ../find-provides.ksyms.new > /dev/null  4.64s user 3.17s system 136% cpu 5.719 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 =====
    old: ../find-provides.ksyms.old > /dev/null  8.49s user 5.54s system 139% cpu 10.043 total
    new: ../find-provides.ksyms.new > /dev/null  7.41s user 4.31s system 129% cpu 9.046 total

* find-provides.ksyms: Rewrite the "if nm | grep -q; then nm | awk"
with straight "nm | awk", update the awk script to return the exit code
accordingly, execute indirect symbol parsing only if inderect __crc_*
symbols are present.
* find-requires.ksyms (all_provides): Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-07 02:13:40 +02:00
Eugene Syromiatnikov
df57f906eb find-provides.ksyms, find-requires.ksyms: do section data parsing inside awk
Previous approach with passing the section contents as a command line
option proven to be error-prone, as it hits the command line option size
limit on some kmods.  Move the reading and processing of the section
contents inside the awk script itself;  it also saves a bit (around 3—4%)
of time on the kernels with indirect __crc_* symbols:

    $ for i in ./lib/modules/*; do \
        echo "====== $i ====="; \
        diff -u <(find $i | ./find-provides.ksyms.old) <(find $i | ./find-provides.ksyms.new); \
        echo -n "old: "; find $i | time ./find-provides.ksyms.old > /dev/null; \
        echo -n "new: "; find $i | time ./find-provides.ksyms.new > /dev/null; \
    done
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  5.38s user 4.66s system 150% cpu 6.693 total
    new: ./find-provides.ksyms.new > /dev/null  5.20s user 4.52s system 149% cpu 6.484 total
    ====== ./lib/modules/4.18.0-372.57.1.el8_6.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  7.85s user 6.34s system 143% cpu 9.864 total
    new: ./find-provides.ksyms.new > /dev/null  7.75s user 6.32s system 143% cpu 9.809 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  6.19s user 4.68s system 144% cpu 7.506 total
    new: ./find-provides.ksyms.new > /dev/null  5.93s user 4.46s system 143% cpu 7.219 total
    ====== ./lib/modules/5.14.0-284.15.1.el9_2.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  8.47s user 6.71s system 144% cpu 10.523 total
    new: ./find-provides.ksyms.new > /dev/null  8.44s user 6.59s system 144% cpu 10.435 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.s390x =====
    old: ./find-provides.ksyms.old > /dev/null  5.21s user 4.09s system 145% cpu 6.383 total
    new: ./find-provides.ksyms.new > /dev/null  5.04s user 3.85s system 145% cpu 6.120 total
    ====== ./lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64 =====
    old: ./find-provides.ksyms.old > /dev/null  8.68s user 5.77s system 139% cpu 10.326 total
    new: ./find-provides.ksyms.new > /dev/null  8.47s user 5.57s system 139% cpu 10.067 total

* find-provides.ksyms: Add assign to revbytes the result of endianness
chack test instead of the code snippet;  do not generate SECTDATA
variable;  do not pass SECTDATA to the awk script;  pass module
and revbytes to the awk script;  retrieve the section data
into the sectdata variable and perform the byte re-shuffling
in accordance to the revbytes value in the BEGIN section of the awk
script.
* find-requires.ksyms (all_provides): Likewise.

Fixes: cd7e9e8a2f "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing"
Resolves: #2135901
References: https://bugzilla.redhat.com/show_bug.cgi?id=2178935
Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-06-07 02:12:41 +02:00
Etienne Champetier
72be62cfea macros.kmp: do not run rpm -qa
If kernel_version is defined, there is no need to lookup the latest
kernel*-devel package version, if it's not defined, we can only
look for the relevant packages instead of using `rpm -qa`.

Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
Resolves: #2108441
2023-06-01 09:16:07 -04:00
Eugene Syromiatnikov
2cb3604727 find-provides.ksyms, find-requires.ksyms: rewrite section data matching
Currently, it just matches the 2nd to 5th fields with awk, which leads
to occasional capturing of some garbage at the end of the section data
and minor issues when supplying it to the symbol extracting awk script:

    awk: cmd. line:1: (FILENAME=- FNR=19) fatal: argument index with `$' must be > 0
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: cmd. line:1: (FILENAME=- FNR=9) fatal: not enough arguments to satisfy format string
    	`78b624dbc125415351be965ex.$..%ASQ..^'
    	                              ^ ran out for this one

While at it, also eliminate grep and sed calls (with the pair of awk and
sed being the most offending).

* find-provides.ksyms: Generate part of the awk script that performs
the byte reversal based on the endianness in the readelf -h output,
inject it into the awk script;  use substr for matching parts
of the section data instead of fields.
* find-requires.ksyms (all_provides): Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:39 +02:00
Eugene Syromiatnikov
5910d31329 find-provides.ksyms: factor out the output sorting
To bring it more in line with the implementation in find-requires.ksyms.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:39 +02:00
Eugene Syromiatnikov
0f60c336b4 find-requires.ksyms: set LC_ALL=C globally
To bring it more in line with the way it is implemented
in find-provides.ksyms and avoid the inconsistencies prodiced by missing
the environment setting.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:39 +02:00
Eugene Syromiatnikov
30b19c9d63 find-provides.ksyms, find-requires.ksyms: use "read -r"
To avoid all kinds of fun that might stem from interpreting the user-supplied
input.

* find-provides.ksyms: Supply -r option to the read call.
* find-requires.ksyms (all_provides): Likewise.

Fixes: cd7e9e8a2f "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing"
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:39 +02:00
Eugene Syromiatnikov
459cc0478d find-requires.ksyms: call readelf -R on the sectname and not hard-coded .rodata
* find-requires.ksyms (all_provides): Pass $sectname to the readelf -R call.

Fixes: cd7e9e8a2f "find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing"
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:39 +02:00
Eugene Syromiatnikov
0a8324122a find-provides.ksyms, find-requires.ksyms: match only the section being processed
Instead of ignoring the section name in the objdump -t output, section
name has to be checked in the awk script to produce only the meaningful
output;  hit when both __kcrctab and __kcrctab_gpl are present.

* find-requires.ksyms (all_provides): Pass $sectname to the awk script,
check that the relevant field of the input matches it.
* find-provides.ksyms: Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-24 16:09:36 +02:00
Eugene Syromiatnikov
027d626014 find-provides.ksyms, find-requires.ksyms: filter local __crc_* symbols as well
Apparently, these are local in the recent kernels.

* find-provides.ksyms (all_provides): Filter local __crc_* symbols
in additional to global in the objdump -t call output.
* find-requires.ksyms: Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-05-16 09:27:51 +02:00
Eugene Syromiatnikov
96aa636698 kabi: handle symvers.xz
Check for symvers.xz support in addition to symvers.gz,
due to unnanounced unilateral change[1][2] in the kernel packaging.

[1] 2644665657
[2] https://src.fedoraproject.org/rpms/kernel/c/2db77a072a997c00ee63ddf38b79766699094f1c?branch=rawhide

* kabi.attr: Add xz extension to the file matching pattern
* kabi.sh: Add xz extension to the matching pattern;  determine catenation
program based on extension.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
References: https://bugzilla.redhat.com/show_bug.cgi?id=2192895
2023-05-16 09:27:51 +02:00
Denys Vlasenko
9008a32c7d README.md: update docs, add some questions
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-12 15:48:56 +02:00
Denys Vlasenko
efa36b601a tests: adjust internal patch to apply cleanly
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-08 11:28:24 +02:00
Denys Vlasenko
f46d3e8522 modalias.prov: rename "class" and "tag" variables to "prev" and "next"
The old names are misleading.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-08 11:12:45 +02:00
Denys Vlasenko
5683c50270 modalias.prov: use standard "match any char not in set" glob pattern, and sed -E option
[^set] is not correct in glob (it's regexp construct). [!set] is.

sed: -n is not necessary. -e too. manpage recommends using -E instead of -r.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-07 17:56:30 +02:00
Denys Vlasenko
35e1f2fc73 modalias.prov: speed up, explain and make more correct combining code
The time to run on tests/* data decreased from 34.517s to 30.201s.

Do not allow combining of any glob meta characters, either in first
or second line.

The code is still buggy, it may attempt to combine
    modalias(abc[def]123)
    modalias(abc[dXf]123)
into
    modalias(abc[d[eX]f]123)
(presumably there won't be any such cases in real modules, but still).

Eliminate "| head -n1" - do it with bash string ops.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-07 17:49:24 +02:00
Denys Vlasenko
c39c0162a0 tests: add tests for modalias.prov
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-07 17:36:00 +02:00
Denys Vlasenko
7cd7d838cf modalias.prov: group modalias lines by length
On my machine, out of 2604 modules, this reduces number of
"provides" items by ~800 (to 12689 items).

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-07 17:29:18 +02:00
Denys Vlasenko
c2b1f3e458 modalias.prov: avoid a subshell (fork) in position check
This creates a subshell: ... && ( [ -z "$pos" ] || [ $n = $pos ] )

For example, processing ath9k.ko needed ~80 forks here.
Rather expensive.

This should do the same: ... && [ -z "$pos" -o "$n" = "$pos" ]

While at it, explain algorithm in comments.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-05 18:17:29 +02:00
Denys Vlasenko
653ec7d086 modalias.prov: use "local" builtin rather than "declare"
While (in this case) their effect is the same,
many more people know that "local" makes variables function-local,
than that "declare" in bash does the same. I didn't know.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-05 17:40:03 +02:00
Denys Vlasenko
510e0c8261 modalias.prov: make sort locale-independent with LC_ALL=C
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-05 17:35:42 +02:00
Denys Vlasenko
6a6920aed2 modalias.prov: use "command" rather than "which" to check existence of commands
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-05 17:34:05 +02:00
Denys Vlasenko
0c336570df kmod.attr: cosmetic fixes: %{1} to %1, indentation fix
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-04 12:55:15 +02:00
Denys Vlasenko
e9cc0440fd kmod.attr: fix string.gsub patterns and return values
basename(): return one value, not two (principle of least confusion).
strip_compress_sfx(): ditto

strip_compress_sfx(): fix it, it had several problems:
    (a) incorrect escaping of . (period) ... masked by incorrect use of backslash
    (b) lua has no | "or" pattern

Use simpler gsub patterns / replacements, presumably faster (did not measure).

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-04 12:51:15 +02:00
Denys Vlasenko
5df3d6d58b kmod.attr: optimization: do not call strip_compress_sfx() twice
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-04 12:43:01 +02:00
Denys Vlasenko
491a3411df kmod.attr: fix "%g+.ko" pattern (erroneously matches "anythingko") to "%g+%.ko"
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-04 12:37:36 +02:00
Denys Vlasenko
9d75b962fc modalias.prov: fix spurious exitcode of 1 on reaching EOF
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-05-03 11:30:18 +02:00
Denys Vlasenko
0c32043719 README.md: add notes to understand what is done by which file
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-04-28 15:56:49 +02:00
Denys Vlasenko
05ce41491c test commit
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2023-04-26 09:33:20 +02:00
Eugene Syromiatnikov
9e9dc09cda find-provides.ksyms, find-requires.ksyms: avoid awaking debuginfod
Starting with RHEL 9.2 and Fedora 35, debuginfod is enabled by default,
which leads to significant startup times of various tools
from the elfutils package (namely, readelf and objdump).
Unset DEBUGINFOD_URLS to avoid it.

* find-provides.ksyms (DEBUGINFOD_URLS): Unset.
* find-requires.ksyms (DEBUGINFOD_URLS): Ditto.
* kernel-srpm-macros.spec (Release): Bump to 18.
(%changelog): Add a record.

Suggested-by: Panu Matilainen <pmatilai@redhat.com>
Co-Authored-by: Denys Vlasenko <dvlasenk@redhat.com>
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-04-25 12:40:16 +02:00
Eugene Syromiatnikov
891b09a028 kernel-srpm-macros.spec: bump RPM release
* kernel-srpm-macros.spec (Release): Bump to 17.
(%changelog): Add a record.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-04-25 12:20:18 +02:00
Eugene Syromiatnikov
90757faf53 kernel-srpm-macros.spec: update Requires: for binaries used in scripts
Add "Requies:" tags for binearies used in various scripts, namely
brp-kmod-compress, brp-kmod-set-exec-bit, find-provides.ksyms,
find-requires.ksyms, and kmodtool.

* kernel-srpm-macros.spec (%package -n kernel-rpm-macros) <Requires>:
Add %{_bindir}/xz, %{_bindir}/find, %{_bindir}/sed, %{_bindir}/awk,
%{_bindir}/grep, %{_bindir}/nm, %{_bindir}/objdump, %{_bindir}/readelf,
%{_sbindir}/modinfo, %{_sbindir}/modprobe.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
Resolves: #2135047
2023-03-07 14:57:02 +01:00
Eugene Syromiatnikov
cd7e9e8a2f find-provides.ksyms, find-requires.ksyms: rewrite indirect CRC parsing
Linux commit v5.19-rc1~139^2~2 ("kbuild: link symbol CRCs at final link,
removing CONFIG_MODULE_REL_CRCS") has broken the assumption aobut
the placement of non-absolute CRC symbols in .rodata (and also affects
the architectures that used to have these symbols as absolute);  rewrite
the parsing by utilising "objdump -t" output to figure out
the section(s) where the __crc_* symbols are stored and process
it instead of the hard-coded ".rodata" section.  The change also speeds
up the processing a bit, around 33% on synthetic tests:

    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null'
    sh -c   10.36s user 5.58s system 137% cpu 11.613 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null'
    sh -c   7.82s user 4.59s system 142% cpu 8.686 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null'
    sh -c   11.85s user 6.76s system 129% cpu 14.318 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.ppc64le -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null'
    sh -c   8.91s user 5.51s system 135% cpu 10.647 total

* find-provides.ksyms: Process "objdump -t" output to get the list
of sections where __crc_* symbol contents are placed;  retrieve
each one with "readelf -R" and supply it to an awk script that cuts
the required part of it for each __crc_* symbol in that section.
* find-requires.ksyms (all_provides): Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
Resolves: #2135047
2023-03-07 14:56:55 +01:00
Eugene Syromiatnikov
297a5b711f find-provides.ksyms, find-requires.ksyms: work around printed __crc_* type change
Commit binutils-2_33~1385[1] has changed (and binutils-2_35~1768[2]
has not reverted) the calculated type for symbols in read-write .rodata section
from 'R' to 'D' on architectures where CONFIG_MODULE_REL_CRCS is enabled
(namely, ppc64* and s390*), since, apparently, many kernel modules have it indeed
read-write.  Work around it by matching both D and R as possible __crc_* symbol
type.

[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=a288c270991d
[2] https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=49d9fd42acef

* find-provides.ksyms: Match D as possible __crc_* symbol type in
addition to R.
* find-requires.ksyms: Likewise.
* kernel-srpm-macros.spec (Release): Bump to 11%{?dist}.
(%changelog): Mention the change.

Resolves: #2055464
Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
2023-03-07 14:56:48 +01:00
Eugene Syromiatnikov
4eeb063077 find-provides.ksyms, find-requires.ksyms: rewrite absolute CRC parsing
Avoid running sed on the whole "nm" output and also avoid "sed | awk"
pipe in favor of a single awk call.  Overall, this gives around 20%
speedup on some quick synthetic tests:

    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.x86_64 -name "*.ko.xz" | find-provides.ksyms.old > /dev/null 2> /dev/null'
    sh -c   14.20s user 8.93s system 144% cpu 16.014 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.x86_64 -name "*.ko.xz" | find-provides.ksyms.new > /dev/null 2> /dev/null'
    sh -c   12.01s user 7.46s system 143% cpu 13.567 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.x86_64 -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.old" \; > /dev/null 2> /dev/null'
    sh -c   16.31s user 10.77s system 134% cpu 20.092 total
    $ time sh -c 'find ./lib/modules/5.14.0-258.el9.x86_64 -name "*.ko.xz" -exec sh -c "echo {} | find-provides.ksyms.new" \; > /dev/null 2> /dev/null'
    sh -c   13.95s user 8.92s system 135% cpu 16.836 total

* find-provides.ksyms: Check presence of absolute __crc_* symbols with
"grep -q" exit code and not presence of sed output;  rewrite awk script to match
the __crc_* symbols instead of preprocessing the nm output with sed.
* find-requires.ksyms: Likewise.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
Resolves: #2135047
2023-03-07 14:52:22 +01:00
Eugene Syromiatnikov
7945a35005 find-provides.ksyms: set LC_ALL=C globally
This makes the sort order a bit more predictable across various
environments and also speeds up grep/sed/sort a bit as they no longer
need to deal with non-trivial collations and multibyte sequences
that may appear when some garbage is being parsed accidentally.

* find-provides.ksyms: Add "export LC_ALL=C", remove "LC_ALL=C" from the
specific calls.

Signed-off-by: Eugene Syromiatnikov <esyr@redhat.com>
Resolves: #2135047
2023-03-07 14:52:16 +01:00
Fedora Release Engineering
c8c9d28cff Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2023-01-19 14:22:32 +00:00
Fedora Release Engineering
d3674971b2 Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng@fedoraproject.org>
2022-07-21 15:52:52 +00:00
13 changed files with 492 additions and 90 deletions

View file

@ -1,3 +1,79 @@
# kernel-srpm-macros
The kernel-srpm-macros package
The kernel-srpm-macros package
This source package results in two "binary" packages, kernel-rpm-macros
and kernel-srpm-macros. The role and locations of files is as follows:
kernel-srpm-macros:
/usr/lib/rpm/fileattrs/kmod.attr
For /lib/modules/XYZ/modules.builtin and .../MODULE.ko.XYZ
specifies a Lua script to generate kmod(MODULE.ko)
"Provides:" deps
/usr/lib/rpm/macros.d/macros.kernel-srpm
Automatically included by all rpm invocations.
Defines %kernel_arches (try rpm --eval '%kernel_arches')
Question: what uses this macro? I didn't find any users.
kernel-rpm-macros:
/usr/lib/rpm/redhat/find-provides.ksyms
Runs from rpmbuild at the end of kernel builds and 3rd party module
builds, to extract
kernel(SYMBOL)=0xHASH "Provides:" deps from modules in kernel packages,
and ksym(SYMBOL)=0xHASH for 3rd party modules.
Takes input list of files on stdin.
/usr/lib/rpm/fileattrs/provided_ksyms.attr
For newer rpmbuild with "internal dependency generators",
this file specifies that find-provides.ksyms should be run
only on .ko.XYZ files
(with "external dependency generators", the script needs to
filter out the files by itself).
/usr/lib/rpm/redhat/find-requires.ksyms
?
/usr/lib/rpm/fileattrs/required_ksyms.attr
For newer rpmbuild with "internal dependency generators",
this file specifies that find-requires.ksyms should be run
only on .ko.XYZ files, and not for /lib/modules/XYZ/kernel/*
(IOW: only for building 3rd-party modules)
/usr/lib/rpm/redhat/find-provides.d/modalias.prov
Runs from rpmbuild at the end of kernel builds and 3rd party module
builds, to extract
modalias(pci:SOMETHING)=OPTIONALLY_VERSION "Provides:" deps from modules
in kernel and 3rd party modules packages.
Takes input list of files on stdin.
Question: what uses these deps?
/usr/lib/rpm/fileattrs/modalias.attr
For newer rpmbuild with "internal dependency generators",
this file specifies that modalias.prov should be run
only on .ko.XYZ files
/usr/lib/rpm/redhat/find-provides.d/firmware.prov
?
/usr/lib/rpm/kabi.sh
Runs from rpmbuild at the end of kernel build to extract
kernel(SYMBOL)=0xHASH "Provides:" deps.
/usr/lib/rpm/fileattrs/kabi.attr
For newer rpmbuild with "internal dependency generators",
this file specifies that kabi.sh should be run on
/boot/symvers-* and /lib/modules/XYZ/symvers.gz
/usr/lib/rpm/macros.d/macros.kmp
Automatically included by all rpm invocations.
Defines a number of macros.
/usr/lib/rpm/redhat/brp-kmod-restore-perms
?
/usr/lib/rpm/redhat/brp-kmod-set-exec-bit
?
/usr/lib/rpm/redhat/kmodtool
?
/usr/lib/rpm/redhat/rpmsort
?
/usr/lib/rpm/redhat/symset-table
?

View file

@ -1,12 +1,16 @@
#! /bin/bash
IFS=$'\n'
export LC_ALL=C
# Prevent elfutils from trying to download debuginfos
unset DEBUGINFOD_URLS
for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
dep_pfx="ksym"
# For built-in kmods, "kernel()" syntax is used instead of "ksym()"
printf "%s" "$module" | grep -v "^${RPM_BUILD_ROOT}/\?lib/modules/[1-9][^/]*/kernel" > /dev/null \
|| dep_pfx="kernel"
|| dep_pfx="kernel"
tmpfile=""
if [ "x${module%.ko}" = "x${module}" ]; then
@ -33,24 +37,102 @@ for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
module="$tmpfile"
fi
if [[ -n $(nm $module | sed -r -ne 's:^0*([0-9a-f]+) A __crc_(.+):0x\1 \2:p') ]]; then
nm $module \
| sed -r -ne 's:^0*([0-9a-f]+) A __crc_(.+):0x\1 \2:p' \
| awk --non-decimal-data '{printf("'"${dep_pfx}"'(%s) = 0x%08x\n", $2, $1)}' \
| LC_ALL=C sort -u
else
ELFRODATA=$(readelf -R .rodata $module | awk '/0x/{printf $2$3$4$5}')
if [[ -n $(readelf -h $module | grep "little endian") ]]; then
RODATA=$(echo $ELFRODATA | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/g')
else
RODATA=$ELFRODATA
fi
for sym in $(nm $module | sed -r -ne 's:^0*([0-9a-f]+) R __crc_(.+):0x\1 \2:p'); do
echo $sym $RODATA
done \
| awk --non-decimal-data '{printf("'"${dep_pfx}"'(%s) = 0x%08s\n", $2, substr($3,($1*2)+1,8))}' \
| LC_ALL=C sort -u
fi
# A modversion can be stored as an ELF symbol in various ways:
# - An immediate symbol whose value is available directly; it shows up
# in the nm or objdump -t output, for example:
# $ nm mlx5_core_5.14.x86_64.ko | grep '__crc_' | head -n 3
# 0000000092f175ca A __crc_mlx5_access_reg
# 000000005b88c9f1 A __crc_mlx5_add_flow_rules
# 00000000e7c0ec8a A __crc_mlx5_alloc_bfreg
# $ objdump -t lib/modules/mlx5_core_5.14.x86_64.ko | grep __crc_ | sort -k 5,5 | head -n 3
# 0000000092f175ca g *ABS* 0000000000000000 __crc_mlx5_access_reg
# 000000005b88c9f1 g *ABS* 0000000000000000 __crc_mlx5_add_flow_rules
# 00000000e7c0ec8a g *ABS* 0000000000000000 __crc_mlx5_alloc_bfreg
# $ zgrep mlx5_access_reg ./lib/modules/5.14.0-284.15.1.el9_2.x86_64/symvers.gz
# 0x92f175ca mlx5_access_reg drivers/net/ethernet/mellanox/mlx5/core/mlx5_core EXPORT_SYMBOL_GPL
# This approach was being used on x86 and arm before Linux 5.19,
# for example.
#
# - A globally or locally visible symbol in a read-only (or not;
# sometimes .rodata is not a read-only section, after all, as binutils
# commit binutils-2_33~1385 has revealed (and binutils-2_35~1768 hasn't
# concealed back)) section (historically .rodata, __kcrctab/__kcrctab_gpl
# since Linux v5.19-rc1~139^2~2):
# $ nm mlx5_core_5.14.s390x.ko | grep '__crc_' | head -n 3
# 0000000000002f7c R __crc_mlx5_access_reg
# 0000000000003304 R __crc_mlx5_add_flow_rules
# 0000000000002d2c R __crc_mlx5_alloc_bfreg
# This layout is used on ppc since Linux v4.10-rc7~15^2~1, for example,
# and on all architectures since Linux 5.19. To extract the symbol
# versions in this case, we get the offset and the section name
# from the "objdump -t" output:
# $ objdump -t lib/modules/mlx5_core_5.14.s390x.ko | grep '__crc_' | sort -k 5,5 | head -n 2
# 0000000000002f7c g .rodata 0000000000000000 __crc_mlx5_access_reg
# 0000000000003304 g .rodata 0000000000000000 __crc_mlx5_add_flow_rules
# and the section contents from the "readelf -R" call:
# $ readelf -R .rodata mlx5_core_5.14.s390x.ko
# [... skipped output ...]
# 0x00002f70 6c6f635f 6e6f6465 00000000 ed6560a8 loc_node.....e`.
# ^^^^^^^^
# comparison with the contents
# of lib/modules/5.14.0-284.15.1.el9_2.s390x/symvers.gz corroborates
# its correctness:
# 0xed6560a8 mlx5_access_reg drivers/net/ethernet/mellanox/mlx5/core/mlx5_core EXPORT_SYMBOL_GPL
# As mentioned earlier, for the later kernel versions, __kcrctab{,_gpl}
# sections are used:
# $ objdump -t lib/modules/mlx5_core_6.4.x86_64.ko | grep '__crc_' | sort -k 5,5 | head -n 2
# 0000000000000000 l __kcrctab_gpl 0000000000000000 __crc_mlx5_access_reg
# 0000000000000090 l __kcrctab 0000000000000000 __crc_mlx5_add_flow_rules
# $ readelf -R __kcrctab_gpl mlx5_core_6.4.x86_64.ko
# 0x00000000 38b0d3c3 1840ce35 b99babc7 70b4700c 8....@.5....p.p.
# ^^^^^^^^
# and in lib/modules/6.4.0-0.rc1.20230511git80e62bc8487b.19.eln126.x86_64/symvers.xz
# we see that it is correct (when accounted for the little endianness):
# 0xc3d3b038 mlx5_access_reg drivers/net/ethernet/mellanox/mlx5/core/mlx5_core EXPORT_SYMBOL_GPL
# This data, after some post-processing, can be used in the awk script
# that extracts parts of the section according to the offsets got
# from the "objdump -t" output.
objdump -t "$module" \
| awk \
-v 'dep_pfx='"$dep_pfx" \
-v 'module='"$module" \
--non-decimal-data \
'BEGIN { revbytes = 0 }
function check_endianness( t) {
if (revbytes) return revbytes;
revbytes = -1;
while (("readelf -h \"" module "\"" | getline t) > 0) {
if (match(t, /^ Data: *2\047s complement, little endian$/)) {
revbytes = 1;
break;
}
}
return revbytes;
}
function readsect(name, a, t) {
a = "";
while (("readelf -R \"" name "\" \"" module "\"" | getline t) > 0) {
if (match(t, /^ 0x[0-9a-f]{8}/))
a = a substr(t, 14, 8) substr(t, 23, 8) substr(t, 32, 8) substr(t, 41, 8);
}
if (check_endianness() == 1)
a = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", a);
sectdata[name] = a;
}
match($0, /^([0-9a-f]+) [gl]...... (.*) [0-9a-f]+ __crc_(.*)$/, a) {
if (a[2] == "*ABS*") {
printf("%s(%s) = 0x%08x\n", dep_pfx, a[3], strtonum("0x" a[1]));
} else {
if (!(a[2] in sectdata)) { readsect(a[2]) }
printf("%s(%s) = 0x%08s\n", dep_pfx, a[3], substr(sectdata[a[2]], (strtonum("0x" a[1]) * 2) + 1, 8))
}
}'
[ -z "$tmpfile" ] || rm -f -- "$tmpfile"
done
done \
| sort -k1,1 -u

View file

@ -6,6 +6,10 @@
# provided by an external module and "ksym" replaces th regular "kernel" dep.
IFS=$'\n'
export LC_ALL=C
# Prevent elfutils from trying to download debuginfos
unset DEBUGINFOD_URLS
# Extract all of the symbols provided by this module.
all_provides() {
@ -35,26 +39,49 @@ all_provides() {
module="$tmpfile"
fi
if [[ -n $(nm "$module" | sed -r -ne 's:^0*([0-9a-f]+) A __crc_(.+):0x\1 \2:p') ]]; then
nm "$module" \
| sed -r -ne 's:^0*([0-9a-f]+) A __crc_(.+):0x\1 \2:p' \
| awk --non-decimal-data '{printf("%s:0x%08x\n", $2, $1)}'
else
ELFRODATA=$(readelf -R .rodata "$module" | awk '/0x/{printf $2$3$4$5}')
if [[ -n $(readelf -h "$module" | grep "little endian") ]]; then
RODATA=$(echo $ELFRODATA | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/g')
else
RODATA=$ELFRODATA
fi
for sym in $(nm "$module" | sed -r -ne 's:^0*([0-9a-f]+) R __crc_(.+):0x\1 \2:p'); do
echo $sym $RODATA
done \
| awk --non-decimal-data '{printf("%s:0x%08s\n", $2, substr($3,($1*2)+1,8))}'
fi
objdump -t "$module" \
| awk \
-v 'dep_pfx='"$dep_pfx" \
-v 'module='"$module" \
--non-decimal-data \
'BEGIN { revbytes = 0 }
function check_endianness( t) {
if (revbytes) return revbytes;
revbytes = -1;
while (("readelf -h \"" module "\"" | getline t) > 0) {
if (match(t, /^ Data: *2\047s complement, little endian$/)) {
revbytes = 1;
break;
}
}
return revbytes;
}
function readsect(name, a, t) {
a = "";
while (("readelf -R \"" name "\" \"" module "\"" | getline t) > 0) {
if (match(t, /^ 0x[0-9a-f]{8}/))
a = a substr(t, 14, 8) substr(t, 23, 8) substr(t, 32, 8) substr(t, 41, 8);
}
if (revbytes) { a = gensub(/(..)(..)(..)(..)/, "\\4\\3\\2\\1", "g", a); }
sectdata[name] = a;
}
match($0, /^([0-9a-f]+) [gl]...... (.*) [0-9a-f]+ __crc_(.*)$/, a) {
if (a[2] == "*ABS*") {
printf("%s(%s) = 0x%08x\n", dep_pfx, a[3], strtonum("0x" a[1]));
} else {
if (!(a[2] in sectdata)) { readsect(a[2]) }
printf("%s(%s) = 0x%08s\n", dep_pfx, a[3], substr(sectdata[a[2]], (strtonum("0x" a[1]) * 2) + 1, 8))
}
}'
[ -z "$tmpfile" ] || rm -f -- "$tmpfile"
done \
| LC_ALL=C sort -k1,1 -u
| sort -k1,1 -u
}
# Extract all of the requirements of this module.
@ -67,15 +94,15 @@ all_requires() {
{printf("%s:0x%08x\n", $2, $1)}' \
| sed -r -e 's:$:\t'"$1"':'
done \
| LC_ALL=C sort -k1,1 -u
| sort -k1,1 -u
}
# Filter out requirements fulfilled by the module itself.
mod_requires() {
LC_ALL=C join -t $'\t' -j 1 -v 1 \
join -t $'\t' -j 1 -v 1 \
<(all_requires "$@") \
<(all_provides "$@") \
| LC_ALL=C sort -k1,1 -u
| sort -k1,1 -u
}
if ! [ -e /sbin/modinfo -a -e /sbin/modprobe ]; then
@ -138,23 +165,23 @@ if [ ${#modules[@]} -gt 0 ]; then
{ print $2 ":" $1 }
' \
| sed -r -e 's:$:\t'"$kernel"':' \
| LC_ALL=C sort -k1,1 -u > $symvers
| sort -k1,1 -u > $symvers
# Symbols matching with the kernel get a "kernel" dependency
mod_req=$(mktemp -t mod_req.XXXXX)
mod_requires "${modules[@]}" > "$mod_req"
LC_ALL=C join -t $'\t' -j 1 $symvers "$mod_req" | LC_ALL=C sort -u \
join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "kernel(" $1 ") = " $2 }'
# Symbols from elsewhere get a "ksym" dependency
LC_ALL=C join -t $'\t' -j 1 -v 2 $symvers "$mod_req" | LC_ALL=C sort -u \
join -t $'\t' -j 1 -v 2 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print "ksym(" $1 ") = " $2 }'
os_id=$(sed -nr '/^ID[[:space:]]*=/{ s/ID[[:space:]]*=[[:space:]]*//; s/^"(.*)"$/\1/; p }' /etc/os-release)
if [ "rhel" = "$os_id" ]; then
# Check kABI if the kabi-stablelists package is installed
# Do this last so we can try to output this error at the end
kabi_check_symbols=($(LC_ALL=C join -t $'\t' -j 1 $symvers "$mod_req" | LC_ALL=C sort -u \
kabi_check_symbols=($(join -t $'\t' -j 1 $symvers "$mod_req" | sort -u \
| awk 'BEGIN { FS = "[\t:]" ; OFS = "\t" } { print $1 }'))
check_kabi "${kabi_check_symbols[@]}"
fi

View file

@ -1,2 +1,2 @@
%__kabi_provides %{_rpmconfigdir}/kabi.sh
%__kabi_path ^(/boot/symvers-.*|/lib/modules/[1-9].*/symvers)\.gz$
%__kabi_path ^(/boot/symvers-.*|/lib/modules/[1-9].*/symvers)\.(gz|xz)$

10
kabi.sh
View file

@ -7,10 +7,16 @@
IFS=$'\n'
for symvers in $(grep -E '(/boot/symvers-.*|/lib/modules/[1-9].*/symvers)\.gz') "$@";
for symvers in $(grep -E '(/boot/symvers-.*|/lib/modules/[1-9].*/symvers)\.(gz|xz)') "$@";
do
cat_prog="cat"
case "$symvers" in
*.gz) cat_prog="zcat" ;;
*.xz) cat_prog="xzcat" ;;
esac
# We generate dependencies only for symbols exported by vmlinux itself
# and not for kmods here as they are spread across subpackages,
# so Provides: generation for kmods is handled by find-provides.ksyms.
zcat $symvers | awk '/[^ ]* [^ ]* vmlinux .*/ { print "kernel(" $2 ") = " $1 }'
"$cat_prog" "$symvers" | awk '/[^ ]* [^ ]* vmlinux .*/ { print "kernel(" $2 ") = " $1 }'
done

View file

@ -1,7 +1,7 @@
Name: kernel-srpm-macros
Version: 1.0
# when bumping version and resetting release, don't forget to bump version of kernel-rpm-macros as well
Release: 14%{?dist}
Release: 27%{?dist}
Summary: RPM macros that list arches the full kernel is built on
# This package only exist in Fedora repositories
# The license is the standard (MIT) specified in
@ -56,10 +56,25 @@ The variable to use is kernel_arches.
%package -n kernel-rpm-macros
Version: 205
Summary: Macros and scripts for building kernel module packages
# rpmsort is GPL-2.0-or-later
License: MIT AND GPL-2.0-or-later
Requires: redhat-rpm-config >= 205
# for brp-kmod-set-exec-bit
# for brp-kmod-compress
Requires: %{_bindir}/xz
# for brp-kmod-compress, brp-kmod-set-exec-bit
Requires: %{_bindir}/find
# for find-provides.ksyms, find-requires.ksyms, kmodtool
Requires: %{_bindir}/sed
# for find-provides.ksyms, find-requires.ksyms
Requires: %{_bindir}/awk
Requires: %{_bindir}/grep
Requires: %{_bindir}/nm
Requires: %{_bindir}/objdump
Requires: %{_bindir}/readelf
# for find-requires.ksyms
Requires: %{_sbindir}/modinfo
Requires: %{_sbindir}/modprobe
%description -n kernel-rpm-macros
Macros and scripts for building kernel module packages.
@ -79,7 +94,7 @@ cp -p %{sources} .
mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d
install -p -m 0644 -t %{buildroot}/%{_rpmconfigdir}/macros.d macros.kernel-srpm
%if 0%{?rhel} >= 8
sed -i 's/^%%kernel_arches.*/%%kernel_arches x86_64 s390x ppc64le aarch64/' \
sed -i 's/^%%kernel_arches.*/%%kernel_arches x86_64 s390x ppc64le aarch64 riscv64/' \
%{buildroot}/%{_rpmconfigdir}/macros.d/macros.kernel-srpm
%endif
@ -121,6 +136,56 @@ install -p -m 644 -t "%{buildroot}%{_fileattrsdir}" modalias.attr
%{rrcdir}/rpmsort
%changelog
* Thu Jul 24 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-27
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Tue Apr 01 2025 Andrea Bolognani <abologna@redhat.com> - 1.0-26
- Finish adding riscv64 (thanks Zhengyu He)
* Fri Jan 17 2025 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-25
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Thu Jul 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-24
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Wed Mar 06 2024 David Abdurachmanov <davidlt@rivosinc.com> - 1.0-23
- Add riscv64
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-22
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-21
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Tue May 09 2023 Eugene Syromiatnikov <esyr@redhat.com> - 1.0-19
- Capture local __crc_* symbols for "Provides: kernel()".
- Add support for XZ compression for the symvers file.
- Fix "Provides: kernel()" generation when both __kcrctab and __kcrctab_gpl
are present.
- Fix regression for "Provides:" generation in cases when modversions are stored
in a section that is over 64K in size.
- Speedup and cleanup changes in find-provides.ksyms and find-requires.ksyms.
- Fix regex usage in kmod.attr. (Denys Vlasenko)
- Implement modalias "Provides:" grouping. (Denys Vlasenko)
- Speedup and cleanup changes in modalias.prov and kmod.attr. (Denys Vlasenko)
* Tue Mar 30 2023 Eugene Syromiatnikov <esyr@redhat.com> - 1.0-18
- Avoid triggering debuginfod during elfutils tools usage.
* Tue Jan 31 2023 Eugene Syromiatnikov <esyr@redhat.com> - 1.0-17
- Support storing of __crc_* symbols in sections other than .rodata.
- Work around a change in type of __crc_* symbols for some kmods printed by nm
on ppc64le and s390x.
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-16
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.0-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild

View file

@ -1,31 +1,54 @@
%__kmod_path ^/lib/modules/.*/(modules.builtin|.*\.ko|.*\.ko\.gz|.*\.ko\.bz2|.*\.ko\.xz|.*\.ko\.zst)$
# Notes on Lua:
# The backslash in strings (like "\n" newline) needs to be doubled
# because we are inside rpm macro. Single backslashes before most chars
# disappear (removed by rpm's parser), so "\n" turns into just "n".
# In string.gsub patterns, unlike regexps, backslash has no special meaning.
# It can't escape . and such. (Use one-character set [.] to represent
# literal period, or lua's percent escape: %.)
# Pipe (|) has no special meaning too.
%__kmod_provides() %{lua:
function basename(fn)
return string.gsub(fn, "(.*/)(.*)", "%2")
local b = string.gsub(fn, ".*/", "")
-- the above adjusts gsub() result to 1 value
-- "return f()" construct would return _all_ values, two in case of gsub()
return b
end
function strip_compress_sfx(fn)
return string.gsub(fn, "(.*)(\.gz|\.bz2|\.xz|\.zst)?$", "%1")
local cnt
fn, cnt = string.gsub(fn, "%.gz$", "")
if cnt == 1 then return fn; end
fn, cnt = string.gsub(fn, "%.bz2$", "")
if cnt == 1 then return fn; end
fn, cnt = string.gsub(fn, "%.xz$", "")
if cnt == 1 then return fn; end
fn, cnt = string.gsub(fn, "%.zst$", "")
return fn
end
function printdep(mod)
print("kmod("..mod..") ")
end
local fn = rpm.expand("%{1}")
local fn = rpm.expand("%1")
local bn = basename(fn)
if bn == "modules.builtin" then
for l in io.lines(fn) do
local builtin_mod = basename(l)
printdep(builtin_mod)
if strip_compress_sfx(builtin_mod) ~= builtin_mod then
printdep(strip_compress_sfx(builtin_mod))
local nocompr = strip_compress_sfx(builtin_mod)
if nocompr ~= builtin_mod then
printdep(nocompr)
end
end
else
local mod = string.match(bn, "%g+.ko")
local mod = string.match(bn, "%g+%.ko")
if mod then
printdep(mod)
if strip_compress_sfx(mod) ~= mod then
printdep(strip_compress_sfx(mod))
end
printdep(mod)
local nocompr = strip_compress_sfx(mod)
if nocompr ~= mod then
printdep(nocompr)
end
end
end
}

View file

@ -1,3 +1,3 @@
# kernel_arches lists what arches the full kernel is built for.
%kernel_arches x86_64 s390x ppc64le aarch64 %{arm}
%kernel_arches x86_64 s390x ppc64le aarch64 %{arm} riscv64

View file

@ -59,7 +59,7 @@ redhat_kmp_has_post_hooks 1
%global kmodtool %{-s*}%{!-s:/usr/lib/rpm/redhat/kmodtool} \
%global kmod_version %{-v*}%{!-v:%{version}} \
%global kmod_release %{-r*}%{!-r:%{release}} \
%global latest_kernel %({ rpm -q --qf '%%{VERSION}-%%{RELEASE}.%%{ARCH}\\\\n' `rpm -qa | egrep "^kernel(-rt|-aarch64)?-devel" | /usr/lib/rpm/redhat/rpmsort -r | head -n 1`; echo '%%%%{nil}'; } | head -n 1) \
%global latest_kernel %({ rpm -q --qf '%%{VERSION}-%%{RELEASE}.%%{ARCH}\\\\n' kernel-rt-devel kernel-aarch64-devel kernel-devel | grep -v 'is not installed' | /usr/lib/rpm/redhat/rpmsort -r | head -n 1; echo '%%%%{nil}'; } | head -n 1) \
%{!?kernel_version:%{expand:%%global kernel_version %{latest_kernel}}} \
%global kverrel %(%{kmodtool} verrel %{?kernel_version} 2>/dev/null) \
flavors="default" \

104
modalias.prov Normal file → Executable file
View file

@ -26,13 +26,15 @@ if ! [ -z "$is_kernel_package" ]; then
exit 0
fi
# Check for presence of the commands used
which /sbin/modinfo >/dev/null || exit 0
which sed >/dev/null || exit 0
which sort >/dev/null || exit 0
# Check for presence of the commands used.
# "command" is a builtin, faster to use than fork+execing "which" - see
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html
command -v /sbin/modinfo >/dev/null || exit 1
command -v sed >/dev/null || exit 1
command -v sort >/dev/null || exit 1
print_modaliases() {
declare class=$1 variants=$2 pos=$3
local class="$1" variants="$2" pos="$3"
if [ -n "$variants" ]; then
echo "${class:0:pos}[$variants]${class:pos+1}"
else
@ -40,39 +42,87 @@ print_modaliases() {
fi
}
# Try to make "provides" list a bit smaller:
# find "mergeable" strings a-la
# modalias(pci:v0000168Cd00000023sv*sd*bc*sc*i*)
# modalias(pci:v0000168Cd00000024sv*sd*bc*sc*i*)
# modalias(pci:v0000168Cd00000027sv*sd*bc*sc*i*)
# modalias(pci:v0000168Cd00000029sv*sd*bc*sc*i*)
# replace with
# modalias(pci:v0000168Cd0000002[3479]sv*sd*bc*sc*i*)
combine_modaliases() {
declare tag class variants="" pos="" n
read class
while read tag; do
for ((n=0; n<${#class}; n++)); do
if [ "*" != "${class:n:1}" -a \
"${class:0:n}" = "${tag:0:n}" -a \
"${class:n+1}" = "${tag:n+1}" ] &&
( [ -z "$pos" ] || [ $n = $pos ] ); then
variants="${variants:-${class:n:1}}${tag:n:1}"
pos=$n
local unused_len next prev variants="" pos="" n end xc
# Due to set -e, we can exit with exitcode 1 on read EOF
# and this makes our caller think we failed. "|| return 0" prevents this:
IFS=' ' read unused_len prev || return 0
# For each line after the first...
while IFS=' ' read unused_len next; do
if [ -z "$pos" ]; then
# 2nd line: after "modalias(" prefix, for each char in prev line...
n=9
end=${#prev}
# TODO speedup? if [ $end != ${#next} ]; then line is not mergeable
else
# 3rd+ lines: only check the char at the same position
n=$pos
end=$((pos + 1))
fi
# Search for aaaNbbb,aaaMbbb line pair, where N and M chars differ.
# sort -u guarantees there are no identical line pairs.
# We assume that lines will not differ only in " = version" suffix.
for ((; n < $end; n++)); do
if [ "${prev:0:n}" != "${next:0:n}" ]; then
# the prefixes already aren't the same: break
n=$end
break
fi
# If suffixes differ, go to next char
[ x"${prev:n+1}" != x"${next:n+1}" ] && continue
# Found aaaNbbb,aaaMbbb. If N and M aren't special...
xc=x"${prev:n:1}"
[ x"[" = "$xc" -o x"]" = "$xc" ] && continue
[ x"?" = "$xc" -o x"*" = "$xc" ] && continue
xc=x"${next:n:1}"
[ x"[" = "$xc" -o x"]" = "$xc" ] && continue
[ x"?" = "$xc" -o x"*" = "$xc" ] && continue
# Add M (and maybe N) to $variants, go to next line
variants="${variants:-${prev:n:1}}${next:n:1}"
pos=$n
break
done
if [ $n -eq ${#class} ]; then
print_modaliases "$class" "$variants" "$pos"
variants=
pos=
class=$tag
if [ $n -eq $end ]; then
# This line is not mergeable with the previous one(s),
# print collected merged line and reset the state
print_modaliases "$prev" "$variants" "$pos"
variants=""
pos=""
prev=$next
fi
done
print_modaliases "$class" "$variants" "$pos"
# Print last collected merged line
print_modaliases "$prev" "$variants" "$pos"
}
for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
# | head -n1 because some modules have *two* version tags. *cough*b44*cough*
modver=$(/sbin/modinfo -F version "$module"| head -n1)
modver=${modver//[^0-9a-zA-Z._]/_}
# only add version tag if it has a version
modver=$(/sbin/modinfo -F version "$module")
# delete possible extra lines because some modules have *two* version tags. *cough*b44*cough*
modver=${modver%%$'\n'*} # using $'' bashism, avoid running "head -n1" process
# replace any strange chars with underscores.
# [!...] is glob's "match any char not in set" pattern
# (although bash supports [^...] too, it is not standard)
modver=${modver//[!0-9a-zA-Z._]/_}
# only add version tag if it indeed has a version
[ -z "$modver" ] || modver=" = $modver"
/sbin/modinfo -F alias "$module" \
| sed -nre "s,[^][0-9a-zA-Z._:*?/-],_,g; s,(.+),modalias(\\1)$modver,p"
| sed -E "s,[^][0-9a-zA-Z._:*?/-],_,g; s,(.+),modalias(\\1)$modver,"
# Below: combining code can only possibly combine lines of equal length.
# Prepend line lengths before sort, so that same-length lines end up next
# to each other. (The lengths are discarded by combine_modaliases).
done \
| sort -u \
| { while read line; do echo "${#line} $line"; done } \
| LC_ALL=C sort -u \
| combine_modaliases

31
tests/modalias.prov.collect Executable file
View file

@ -0,0 +1,31 @@
#! /bin/bash -efu
# This fetches test data from current system's /lib/modules
# to /tmp/COLLECT
IFS=$'\n'
find /lib/modules | grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$' \
| while IFS='' read -r module; do
modver=$(/sbin/modinfo -F version "$module")
# delete possible extra lines because some modules have *two* version tags. *cough*b44*cough*
modver=${modver%%$'\n'*} # using $'' bashism, avoid running "head -n1" process
# replace any strange chars with underscores.
# [!...] is glob's "match any char not in set" pattern
# (although bash supports [^...] too, it is not standard)
modver=${modver//[!0-9a-zA-Z._]/_}
# only add version tag if it has a version
[ -z "$modver" ] || modver=" = $modver"
d="/tmp/COLLECT$module"
d="${d%/*}"
mkdir -p "$d"
out=`/sbin/modinfo -F alias "$module" \
| sed -E "s,[^][0-9a-zA-Z._:*?/-],_,g; s,(.+),modalias(\\1)$modver,"`
[ "$out" ] || continue
echo "/tmp/COLLECT$module.modalias$modver" >&2
printf '%s\n' "$out" >"/tmp/COLLECT$module.modalias"
done

42
tests/modalias.prov.runtest Executable file
View file

@ -0,0 +1,42 @@
#!/bin/sh
function die()
{
printf '%s\n' "$*" >&2
exit 1
}
set -e
cd modalias.prov.testdata
test -x ../../modalias.prov || die "No ../../modalias.prov"
# Copy and add -t option to modalias.prov
cp ../../modalias.prov modalias.prov
patch -p1 <<"EOF"
--- a/modalias.prov
+++ b/modalias.prov
@@ -105,6 +105,17 @@ combine_modaliases() {
print_modaliases "$prev" "$variants" "$pos"
}
+if [ "$#" = 2 ] && [ "$1" = "-t" ]; then
+ cat -- "$2" \
+ | { while read line; do echo "${#line} $line"; done } \
+ | LC_ALL=C sort -u \
+ | combine_modaliases \
+ >"$2.test"
+ echo "Comparing results for $2"
+ diff -u "$2.right" "$2.test" && rm -- "$2.test"
+ exit
+fi
+
for module in $(grep -E '/lib/modules/.+\.ko(\.gz|\.bz2|\.xz|\.zst)?$') "$@"; do
modver=$(/sbin/modinfo -F version "$module")
# delete possible extra lines because some modules have *two* version tags. *cough*b44*cough*
EOF
find | grep '\.ko.*\.modalias$' | xargs -n1 ./modalias.prov -t
# Rename newly generated .test as .right
#find | grep '\.ko.*\.modalias$' | xargs -I'{}' mv '{}'.test '{}'.right

Binary file not shown.