Linux: Reclaim unused spl_kmem_cache_reclaim
[zfs.git] / scripts / kmodtool
blob0d6af2c7f1d1abff0284779fce704af077567ff7
1 #!/usr/bin/env bash
2 # shellcheck disable=SC2086,SC2295
4 # kmodtool - Helper script for building kernel module RPMs
5 # Copyright (c) 2003-2012 Ville Skyttä <ville.skytta@iki.fi>,
6 # Thorsten Leemhuis <fedora@leemhuis.info>
7 # Nicolas Chauvet <kwizart@gmail.com>
9 # Permission is hereby granted, free of charge, to any person obtaining
10 # a copy of this software and associated documentation files (the
11 # "Software"), to deal in the Software without restriction, including
12 # without limitation the rights to use, copy, modify, merge, publish,
13 # distribute, sublicense, and/or sell copies of the Software, and to
14 # permit persons to whom the Software is furnished to do so, subject to
15 # the following conditions:
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 shopt -s extglob
30 myprog="kmodtool-${repo}"
31 myver="0.12.1"
33 kmodname=
34 build_kernels="current"
35 kernels_known_variants=
36 kernel_versions=
37 kernel_versions_to_build_for=
38 prefix=
39 filterfile=
40 target=
41 buildroot=
42 dashvariant=
44 error_out()
46 local errorlevel=${1}
47 shift
48 echo "Error: $*" >&2
49 # the next line is not multi-line safe -- not needed *yet*
50 echo "%global kmodtool_check echo \"kmodtool error: $*\"; exit ${errorlevel};"
51 exit "${errorlevel}"
54 print_rpmtemplate_header()
56 echo
57 echo "%global kmodinstdir_prefix ${prefix}/lib/modules/"
58 echo "%global kmodinstdir_postfix /extra/${kmodname}/"
59 echo "%global kernel_versions ${kernel_versions}"
60 echo
63 print_akmodtemplate ()
65 echo
66 cat <<EOF
68 %global akmod_install mkdir -p \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/; \\\
69 LANG=C rpmbuild --define "_sourcedir %{_sourcedir}" \\\
70 --define "_srcrpmdir \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/" \\\
71 -bs --nodeps %{_specdir}/%{name}.spec ; \\\
72 ln -s \$(ls \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/) \$RPM_BUILD_ROOT/%{_usrsrc}/akmods/${kmodname}-kmod.latest
74 %package -n akmod-${kmodname}
75 Summary: Akmod package for ${kmodname} kernel module(s)
76 Group: System Environment/Kernel
77 Requires: kmodtool
78 Requires: akmods
79 %{?AkmodsBuildRequires:Requires: %{AkmodsBuildRequires}}
80 # same requires and provides as a kmods package would have
81 Requires: ${kmodname}-kmod-common >= %{?epoch:%{epoch}:}%{version}
82 Provides: ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
83 EOF
85 cat <<EOF
87 %description -n akmod-${kmodname}
88 This package provides the akmod package for the ${kmodname} kernel modules.
90 %posttrans -n akmod-${kmodname}
91 nohup ${prefix}/sbin/akmods --from-akmod-posttrans --akmod ${kmodname} &> /dev/null &
93 %files -n akmod-${kmodname}
94 %defattr(-,root,root,-)
95 %{_usrsrc}/akmods/*
97 EOF
100 print_akmodmeta ()
102 cat <<EOF
103 %package -n kmod-${kmodname}
104 Summary: Metapackage which tracks in ${kmodname} kernel module for newest kernel${dashvariant}
105 Group: System Environment/Kernel
107 Provides: ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
108 Provides: kmod-${kmodname}-xen = %{?epoch:%{epoch}:}%{version}-%{release}
109 Provides: kmod-${kmodname}-smp = %{?epoch:%{epoch}:}%{version}-%{release}
110 Provides: kmod-${kmodname}-PAE = %{?epoch:%{epoch}:}%{version}-%{release}
111 Requires: akmod-${kmodname} = %{?epoch:%{epoch}:}%{version}-%{release}
114 cat <<EOF
116 %description -n kmod-${kmodname}${dashvariant}
117 This is a meta-package without payload which sole purpose is to require the
118 ${kmodname} kernel module(s) for the newest kernel${dashvariant},
119 to make sure you get it together with a new kernel.
121 %files -n kmod-${kmodname}${dashvariant}
122 %defattr(644,root,root,755)
126 print_rpmtemplate_per_kmodpkg ()
128 if [[ "${1}" = "--custom" ]]; then
129 shift
130 local customkernel=true
131 elif [[ "${1}" = "--redhat" ]]; then
132 # this is needed for akmods
133 shift
134 local redhatkernel=true
137 local kernel_uname_r=${1}
138 local kernel_variant="${2:+-${2}}"
140 # Detect depmod install location
141 local depmod_path=/sbin/depmod
142 if [[ ! -f "${depmod_path}" ]]; then
143 depmod_path=/usr/sbin/depmod
146 # first part
147 cat <<EOF
148 %package -n kmod-${kmodname}-${kernel_uname_r}
149 Summary: ${kmodname} kernel module(s) for ${kernel_uname_r}
150 Group: System Environment/Kernel
151 Provides: kernel-modules-for-kernel = ${kernel_uname_r}
152 Provides: kmod-${kmodname}-uname-r = ${kernel_uname_r}
153 Provides: ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
154 Requires: ${kmodname}-kmod-common >= %{?epoch:%{epoch}:}%{version}
156 %if 0%{?rhel} == 6 || 0%{?centos} == 6
157 Requires(post): module-init-tools
158 Requires(postun): module-init-tools
159 %else
160 Requires(post): kmod
161 Requires(postun): kmod
162 %endif
165 # second part
166 if [[ -z "${customkernel}" ]]; then
167 cat <<EOF
168 Requires: kernel-uname-r = ${kernel_uname_r}
169 BuildRequires: kernel-devel-uname-r = ${kernel_uname_r}
170 %{?KmodsRequires:Requires: %{KmodsRequires}-uname-r = ${kernel_uname_r}}
171 %{?KmodsRequires:BuildRequires: %{KmodsRequires}-uname-r = ${kernel_uname_r}}
172 %post -n kmod-${kmodname}-${kernel_uname_r}
173 if [[ -f "/boot/System.map-${kernel_uname_r}" ]]; then
174 ${prefix}${depmod_path} -aeF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} > /dev/null || :
175 elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then
176 ${prefix}${depmod_path} -aeF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} > /dev/null || :
177 else
178 ${prefix}${depmod_path} -ae ${kernel_uname_r} &> /dev/null || :
180 %postun -n kmod-${kmodname}-${kernel_uname_r}
181 if [[ -f "/boot/System.map-${kernel_uname_r}" ]]; then
182 ${prefix}${depmod_path} -aF /boot/System.map-${kernel_uname_r} ${kernel_uname_r} &> /dev/null || :
183 elif [[ -f "/lib/modules/${kernel_uname_r}/System.map" ]]; then
184 ${prefix}${depmod_path} -aF /lib/modules/${kernel_uname_r}/System.map ${kernel_uname_r} &> /dev/null || :
185 else
186 ${prefix}${depmod_path} -a ${kernel_uname_r} &> /dev/null || :
190 else
191 cat <<EOF
192 %post -n kmod-${kmodname}-${kernel_uname_r}
193 [ "\$(uname -r)" = "${kernel_uname_r}" ] && ${prefix}${depmod_path} -a > /dev/null || :
194 %postun -n kmod-${kmodname}-${kernel_uname_r}
195 [ "\$(uname -r)" = "${kernel_uname_r}" ] && ${prefix}${depmod_path} -a > /dev/null || :
200 # third part
201 cat <<EOF
202 %description -n kmod-${kmodname}-${kernel_uname_r}
203 This package provides the ${kmodname} kernel modules built for the Linux
204 kernel ${kernel_uname_r} for the %{_target_cpu} family of processors.
205 %files -n kmod-${kmodname}-${kernel_uname_r}
206 %defattr(644,root,root,755)
207 %dir $prefix/lib/modules/${kernel_uname_r}/extra
208 ${prefix}/lib/modules/${kernel_uname_r}/extra/${kmodname}/
214 print_rpmtemplate_kmoddevelpkg ()
216 if [[ "${1}" = "--custom" ]]; then
217 shift
218 local customkernel=true
219 elif [[ "${1}" = "--redhat" ]]; then
220 shift
221 local redhatkernel=true
224 local kernel_uname_r=${1}
226 cat <<EOF
227 %package -n kmod-${kmodname}-devel
228 Summary: ${kmodname} kernel module(s) devel common
229 Group: System Environment/Kernel
230 Provides: ${kmodname}-devel-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
233 if [[ -z "${customkernel}" ]] && [[ -z "${redhatkernel}" ]]; then
234 echo "Requires: kmod-${kmodname}-devel-${kernel_uname_r} >= %{?epoch:%{epoch}:}%{version}-%{release}"
237 cat <<EOF
238 %description -n kmod-${kmodname}-devel
239 This package provides the common header files to build kernel modules
240 which depend on the ${kmodname} kernel module. It may optionally require
241 the ${kmodname}-devel-<kernel> objects for the newest kernel.
243 %files -n kmod-${kmodname}-devel
244 %defattr(644,root,root,755)
245 %{_usrsrc}/${kmodname}-%{version}
248 for kernel in ${1}; do
249 local kernel_uname_r=${kernel}
250 echo "%exclude %{_usrsrc}/${kmodname}-%{version}/${kernel_uname_r}"
251 done
253 echo
254 echo
257 print_rpmtemplate_per_kmoddevelpkg ()
259 if [[ "${1}" = "--custom" ]]; then
260 shift
261 local customkernel=true
262 elif [[ "${1}" = "--redhat" ]]; then
263 # this is needed for akmods
264 shift
265 local redhatkernel=true
268 local kernel_uname_r=${1}
269 local kernel_variant="${2:+-${2}}"
271 # first part
272 cat <<EOF
273 %package -n kmod-${kmodname}-devel-${kernel_uname_r}
274 Summary: ${kmodname} kernel module(s) devel for ${kernel_uname_r}
275 Group: System Environment/Kernel
276 Provides: kernel-objects-for-kernel = ${kernel_uname_r}
277 Provides: ${kmodname}-devel-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
278 Provides: kmod-${kmodname}-devel-uname-r = ${kernel_uname_r}
281 # second part
282 if [[ -z "${customkernel}" ]]; then
283 cat <<EOF
284 Requires: kernel-devel-uname-r = ${kernel_uname_r}
285 BuildRequires: kernel-devel-uname-r = ${kernel_uname_r}
286 %{?KmodsDevelRequires:Requires: %{KmodsDevelRequires}-uname-r = ${kernel_uname_r}}
287 %{?KmodsDevelRequires:BuildRequires: %{KmodsDevelRequires}-uname-r = ${kernel_uname_r}}
291 # third part
292 cat <<EOF
293 %description -n kmod-${kmodname}-devel-${kernel_uname_r}
294 This package provides objects and symbols required to build kernel modules
295 which depend on the ${kmodname} kernel modules built for the Linux
296 kernel ${kernel_uname_r} for the %{_target_cpu} family of processors.
297 %files -n kmod-${kmodname}-devel-${kernel_uname_r}
298 %defattr(644,root,root,755)
299 %{_usrsrc}/${kmodname}-%{version}/${kernel_uname_r}
303 print_rpmtemplate_kmodmetapkg ()
305 local kernel_uname_r=${1}
306 local kernel_variant="${2:+-${2}}"
308 cat <<EOF
309 %package -n kmod-${kmodname}${kernel_variant}
310 Summary: Metapackage which tracks in ${kmodname} kernel module for newest kernel${kernel_variant}
311 Group: System Environment/Kernel
313 Provides: ${kmodname}-kmod = %{?epoch:%{epoch}:}%{version}-%{release}
314 Requires: kmod-${kmodname}-${kernel_uname_r} >= %{?epoch:%{epoch}:}%{version}-%{release}
315 %{?KmodsMetaRequires:Requires: %{?KmodsMetaRequires}}
318 cat <<EOF
320 %description -n kmod-${kmodname}${kernel_variant}
321 This is a meta-package without payload which sole purpose is to require the
322 ${kmodname} kernel module(s) for the newest kernel${kernel_variant}.
323 to make sure you get it together with a new kernel.
325 %files -n kmod-${kmodname}${kernel_variant}
326 %defattr(644,root,root,755)
332 print_customrpmtemplate ()
334 for kernel in ${1}
336 if [[ -e "${prefix}/lib/modules/${kernel}/build/Makefile" ]]; then
337 # likely a user-build-kernel with available buildfiles
338 # fixme: we should check if uname from Makefile is the same as ${kernel}
340 kernel_versions="${kernel_versions}${kernel}___${prefix}/lib/modules/${kernel}/build/ "
341 print_rpmtemplate_per_kmodpkg --custom "${kernel}"
343 # create development package
344 if [[ -n "${devel}" ]]; then
345 # create devel package including common headers
346 print_rpmtemplate_kmoddevelpkg --custom "${kernel}"
348 # create devel package
349 print_rpmtemplate_per_kmoddevelpkg --custom "${kernel}"
351 elif [[ -e "${buildroot}/usr/src/kernels/${kernel}" ]]; then
352 # this looks like a Fedora/RH kernel -- print a normal template (which includes the proper BR) and be happy :)
353 kernel_versions="${kernel_versions}${kernel}___${buildroot}%{_usrsrc}/kernels/${kernel} "
355 # parse kernel versions string and print template
356 local kernel_verrelarch=${kernel%%${kernels_known_variants}}
357 print_rpmtemplate_per_kmodpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
359 # create development package
360 if [[ -n "${devel}" ]]; then
361 # create devel package including common headers
362 print_rpmtemplate_kmoddevelpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
364 # create devel package
365 print_rpmtemplate_per_kmoddevelpkg --redhat ${kernel} ${kernel##${kernel_verrelarch}}
367 else
368 error_out 2 "Don't know how to handle ${kernel} -- ${prefix}/lib/modules/${kernel}/build/Makefile not found"
370 done
372 # well, it's no header anymore, but who cares ;-)
373 print_rpmtemplate_header
377 print_rpmtemplate ()
379 # create kernel_versions var
380 for kernel_version in ${kernel_versions_to_build_for}
382 kernel_versions="${kernel_versions}${kernel_version}___%{_usrsrc}/kernels/${kernel_version} "
383 done
385 # and print it and some other required stuff as macro
386 print_rpmtemplate_header
388 # now print the packages
389 for kernel in ${kernel_versions_to_build_for} ; do
391 local kernel_verrelarch=${kernel%%${kernels_known_variants}}
393 # create metapackage
394 print_rpmtemplate_kmodmetapkg "${kernel}" "${kernel##${kernel_verrelarch}}"
396 # create package
397 print_rpmtemplate_per_kmodpkg "${kernel}" "${kernel##${kernel_verrelarch}}"
399 if [[ -n "${devel}" ]]; then
400 # create devel package including common headers
401 print_rpmtemplate_kmoddevelpkg "${kernel}" "${kernel##${kernel_verrelarch}}"
403 # create devel package
404 print_rpmtemplate_per_kmoddevelpkg "${kernel}" "${kernel##${kernel_verrelarch}}"
406 done
409 myprog_help ()
411 echo "Usage: ${0##*/} [OPTIONS]"
412 echo
413 echo "Creates a template to be used during kmod building"
414 echo
415 echo "Available options:"
416 echo " --filterfile <file> -- filter the results with grep --file <file>"
417 echo " --for-kernels <list> -- created templates only for these kernels"
418 echo " --kmodname <file> -- name of the kmod (required)"
419 echo " --devel -- make kmod-devel package"
420 echo " --noakmod -- no akmod package"
421 echo " --repo <name> -- use buildsys-build-<name>-kerneldevpkgs"
422 echo " --target <arch> -- target-arch (required)"
423 echo " --buildroot <dir> -- Build root (place to look for build files)"
426 while [[ -n "${1}" ]] ; do
427 case "${1}" in
428 --filterfile)
429 shift
430 if [[ -z "${1}" ]] ; then
431 error_out 2 "Please provide path to a filter-file together with --filterfile" >&2
432 elif [[ ! -e "${1}" ]]; then
433 error_out 2 "Filterfile ${1} not found" >&2
435 filterfile="${1}"
436 shift
438 --kmodname)
439 shift
440 if [[ -z "${1}" ]] ; then
441 error_out 2 "Please provide the name of the kmod together with --kmodname" >&2
443 # strip pending -kmod
444 kmodname="${1%%-kmod}"
445 shift
447 --devel)
448 shift
449 devel="true"
451 --prefix)
452 shift
453 if [[ -z "${1}" ]] ; then
454 error_out 2 "Please provide a prefix with --prefix" >&2
456 prefix="${1}"
457 shift
459 --repo)
460 shift
461 if [[ -z "${1}" ]] ; then
462 error_out 2 "Please provide the name of the repo together with --repo" >&2
464 repo=${1}
465 shift
467 --for-kernels)
468 shift
469 if [[ -z "${1}" ]] ; then
470 error_out 2 "Please provide the name of the kmod together with --kmodname" >&2
472 for_kernels="${1}"
473 shift
475 --noakmod)
476 shift
477 noakmod="true"
479 --target)
480 shift
481 target="${1}"
482 shift
484 --akmod)
485 shift
486 build_kernels="akmod"
488 --newest)
489 shift
490 build_kernels="newest"
492 --current)
493 shift
494 build_kernels="current"
496 --buildroot)
497 shift
498 buildroot="${1}"
499 shift
501 --help)
502 myprog_help
503 exit 0
505 --version)
506 echo "${myprog} ${myver}"
507 exit 0
510 echo "Error: Unknown option '${1}'." >&2
511 usage >&2
512 exit 2
514 esac
515 done
517 if [[ -e ./kmodtool-kernel-variants ]]; then
518 kernels_known_variants="$(cat ./kmodtool-kernel-variants)"
519 elif [[ -e /usr/share/kmodtool/kernel-variants ]] ; then
520 kernels_known_variants="$(cat /usr/share/kmodtool/kernel-variants)"
521 else
522 kernels_known_variants="@(smp?(-debug)|PAE?(-debug)|debug|kdump|xen|kirkwood|highbank|imx|omap|tegra)"
525 # general sanity checks
526 if [[ -z "${target}" ]]; then
527 error_out 2 "please pass target arch with --target"
528 elif [[ -z "${kmodname}" ]]; then
529 error_out 2 "please pass kmodname with --kmodname"
530 elif [[ -z "${kernels_known_variants}" ]] ; then
531 error_out 2 "could not determine known variants"
534 # go
535 if [[ -n "${for_kernels}" ]]; then
536 # this is easy:
537 print_customrpmtemplate "${for_kernels}"
538 elif [[ "${build_kernels}" = "akmod" ]]; then
539 # do only a akmod package
540 print_akmodtemplate
541 print_akmodmeta
542 else
543 # seems we are on out own to decide for which kernels to build
545 # we need more sanity checks in this case
546 if [[ -z "${repo}" ]]; then
547 error_out 2 "please provide repo name with --repo"
548 elif ! command -v "buildsys-build-${repo}-kerneldevpkgs" > /dev/null 2>&1; then
549 error_out 2 "buildsys-build-${repo}-kerneldevpkgs not found"
552 # call buildsys-build-${repo}-kerneldevpkgs to get the list of kernels
553 cmdoptions="--target ${target}"
555 # filterfile to filter list of kernels?
556 if [[ -n "${filterfile}" ]] ; then
557 cmdoptions="${cmdoptions} --filterfile ${filterfile}"
560 kernel_versions_to_build_for=$(buildsys-build-${repo}-kerneldevpkgs "--${build_kernels}" ${cmdoptions}) ||
561 error_out 2 "buildsys-build-${repo}-kerneldevpkgs failed: ${kernel_versions_to_build_for}"
563 if [[ "${build_kernels}" = "current" ]] && [[ -z "${noakmod}" ]]; then
564 print_akmodtemplate
567 print_rpmtemplate