summaryrefslogtreecommitdiffstats
path: root/meta/classes-recipe/kernel-module-split.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta/classes-recipe/kernel-module-split.bbclass')
-rw-r--r--meta/classes-recipe/kernel-module-split.bbclass245
1 files changed, 0 insertions, 245 deletions
diff --git a/meta/classes-recipe/kernel-module-split.bbclass b/meta/classes-recipe/kernel-module-split.bbclass
deleted file mode 100644
index 75ed696b72..0000000000
--- a/meta/classes-recipe/kernel-module-split.bbclass
+++ /dev/null
@@ -1,245 +0,0 @@
1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7pkg_postinst:modules () {
8if [ -z "$D" ]; then
9 depmod -a ${KERNEL_VERSION}
10else
11 # image.bbclass will call depmodwrapper after everything is installed,
12 # no need to do it here as well
13 :
14fi
15}
16
17pkg_postrm:modules () {
18if [ -z "$D" ]; then
19 depmod -a ${KERNEL_VERSION}
20else
21 depmodwrapper -a -b $D ${KERNEL_VERSION} ${KERNEL_PACKAGE_NAME}
22fi
23}
24
25autoload_postinst_fragment() {
26if [ x"$D" = "x" ]; then
27 modprobe %s || true
28fi
29}
30
31PACKAGE_WRITE_DEPS += "kmod-native depmodwrapper-cross"
32
33modulesloaddir ??= "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${nonarch_libdir}', '${sysconfdir}', d)}/modules-load.d"
34modprobedir ??= "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', '${nonarch_base_libdir}', '${sysconfdir}', d)}/modprobe.d"
35
36KERNEL_SPLIT_MODULES ?= "1"
37PACKAGESPLITFUNCS =+ "split_kernel_module_packages"
38
39KERNEL_MODULES_META_PACKAGE ?= "${@ d.getVar("KERNEL_PACKAGE_NAME") or "kernel" }-modules"
40
41KERNEL_MODULE_PACKAGE_PREFIX ?= ""
42KERNEL_MODULE_PACKAGE_SUFFIX ?= "-${KERNEL_VERSION}"
43KERNEL_MODULE_PROVIDE_VIRTUAL ?= "1"
44
45python split_kernel_module_packages () {
46 import re
47
48 modinfoexp = re.compile("([^=]+)=(.*)")
49
50 def extract_modinfo(file):
51 import tempfile, subprocess
52 tempfile.tempdir = d.getVar("WORKDIR")
53 compressed = re.match( r'.*\.(gz|xz|zst)$', file)
54 tf = tempfile.mkstemp()
55 tmpfile = tf[1]
56 if compressed:
57 tmpkofile = tmpfile + ".ko"
58 if compressed.group(1) == 'gz':
59 cmd = "gunzip -dc %s > %s" % (file, tmpkofile)
60 subprocess.check_call(cmd, shell=True)
61 elif compressed.group(1) == 'xz':
62 cmd = "xz -dc %s > %s" % (file, tmpkofile)
63 subprocess.check_call(cmd, shell=True)
64 elif compressed.group(1) == 'zst':
65 cmd = "zstd -dc %s > %s" % (file, tmpkofile)
66 subprocess.check_call(cmd, shell=True)
67 else:
68 msg = "Cannot decompress '%s'" % file
69 raise msg
70 cmd = "%s -j .modinfo -O binary %s %s" % (d.getVar("OBJCOPY"), tmpkofile, tmpfile)
71 else:
72 cmd = "%s -j .modinfo -O binary %s %s" % (d.getVar("OBJCOPY"), file, tmpfile)
73 subprocess.check_call(cmd, shell=True)
74 # errors='replace': Some old kernel versions contain invalid utf-8 characters in mod descriptions (like 0xf6, 'รถ')
75 with open(tmpfile, errors='replace') as f:
76 l = f.read().split("\000")
77 os.close(tf[0])
78 os.unlink(tmpfile)
79 if compressed:
80 os.unlink(tmpkofile)
81 vals = {}
82 for i in l:
83 m = modinfoexp.match(i)
84 if not m:
85 continue
86 vals[m.group(1)] = m.group(2)
87 return vals
88
89 def handle_conf_files(d, basename, pkg):
90 # If autoloading is requested, output ${modulesloaddir}/<name>.conf and append
91 # appropriate modprobe commands to the postinst
92 autoloadlist = (d.getVar("KERNEL_MODULE_AUTOLOAD") or "").split()
93 autoload = d.getVar('module_autoload_%s' % basename)
94 if autoload and autoload == basename:
95 bb.warn("module_autoload_%s was replaced by KERNEL_MODULE_AUTOLOAD for cases where basename == module name, please drop it" % basename)
96 if autoload and basename not in autoloadlist:
97 bb.warn("module_autoload_%s is defined but '%s' isn't included in KERNEL_MODULE_AUTOLOAD, please add it there" % (basename, basename))
98
99 # The .conf file can either be installed by a recipe or generated from module_autoload_*
100 conf = '%s/%s.conf' % (d.getVar('modulesloaddir'), basename)
101 name = '%s%s' % (d.getVar('PKGD'), conf)
102 # If module name is in KERNEL_MODULE_AUTOLOAD, then generate the .conf file and write to `name`.
103 if basename in autoloadlist:
104 os.makedirs(os.path.dirname(name), exist_ok=True)
105 with open(name, 'w') as f:
106 if autoload:
107 for m in autoload.split():
108 f.write('%s\n' % m)
109 else:
110 f.write('%s\n' % basename)
111 # If the .conf file exits, then add it to FILES:* and CONFFILES:* and add postinstall hook.
112 # It doesn't matter if it was generated from module_autoload_* or installed by the recipe.
113 if os.path.exists(name):
114 conf2append = ' %s' % conf
115 d.appendVar('FILES:%s' % pkg, conf2append)
116 d.appendVar('CONFFILES:%s' % pkg, conf2append)
117 postinst = d.getVar('pkg_postinst:%s' % pkg)
118 if not postinst:
119 postinst = d.getVar('pkg_postinst:modules')
120 postinst += d.getVar('autoload_postinst_fragment') % (autoload or basename)
121 d.setVar('pkg_postinst:%s' % pkg, postinst)
122
123 # Write out any modconf fragment
124 modconflist = (d.getVar("KERNEL_MODULE_PROBECONF") or "").split()
125 modconf = d.getVar('module_conf_%s' % basename)
126
127 # The .conf file can either be installed by a recipe or generated from module_conf_*
128 conf = '%s/%s.conf' % (d.getVar('modprobedir'), basename)
129 name = '%s%s' % (d.getVar('PKGD'), conf)
130 # If module name is in KERNEL_MODULE_PROBECONF, then generate the .conf file and write to `name`.
131 if modconf and basename in modconflist:
132 os.makedirs(os.path.dirname(name), exist_ok=True)
133 with open(name, 'w') as f:
134 f.write("%s\n" % modconf)
135 elif modconf:
136 bb.error("Please ensure module %s is listed in KERNEL_MODULE_PROBECONF since module_conf_%s is set" % (basename, basename))
137 # If the .conf file exits, then add it to FILES:* and CONFFILES:*.
138 # It doesn't matter if it was generated from module_conf_* or installed by the recipe.
139 if os.path.exists(name):
140 conf2append = ' %s' % conf
141 d.appendVar('FILES:%s' % pkg, conf2append)
142 d.appendVar('CONFFILES:%s' % pkg, conf2append)
143
144 def generate_conf_files(d, root, file_regex, output_pattern):
145 """
146 Arguments:
147 root -- the path in which to search. Contains system lib path
148 so needs expansion.
149 file_regex -- regular expression to match searched files. Use
150 parentheses () to mark the part of this expression
151 that should be used to derive the module name (to be
152 substituted where %s is used in other function
153 arguments as noted below)
154 output_pattern -- pattern to use for the package names. Must include %s.
155 """
156 import re, stat
157
158 dvar = d.getVar('PKGD')
159 root = d.expand(root)
160
161 # if the root directory doesn't exist, it's fatal - exit from the current execution.
162 if not os.path.exists(dvar + root):
163 bb.fatal("kernel module root directory path does not exist")
164
165 # walk through kernel module directory. for each entry in the directory, check if it
166 # matches the desired regex pattern and file type. if it fullfills, process it to generate
167 # it's conf file based on its package name.
168 for walkroot, dirs, files in os.walk(dvar + root):
169 for file in files:
170 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
171 if not relpath:
172 continue
173 m = re.match(file_regex, os.path.basename(relpath))
174 if not m:
175 continue
176 file_f = os.path.join(dvar + root, relpath)
177 mode = os.lstat(file_f).st_mode
178 if not (stat.S_ISREG(mode) or (allow_links and stat.S_ISLNK(mode)) or (allow_dirs and stat.S_ISDIR(mode))):
179 continue
180
181 basename = m.group(1)
182 on = legitimize_package_name(basename)
183 pkg = output_pattern % on
184 handle_conf_files(d, basename, pkg)
185
186
187 def frob_metadata(file, pkg, pattern, format, basename):
188 vals = extract_modinfo(file)
189 dvar = d.getVar('PKGD')
190
191 handle_conf_files(d, basename, pkg)
192
193 if "description" in vals:
194 old_desc = d.getVar('DESCRIPTION:' + pkg) or ""
195 d.setVar('DESCRIPTION:' + pkg, old_desc + "; " + vals["description"])
196
197 rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
198 modinfo_deps = []
199 if "depends" in vals and vals["depends"] != "":
200 for dep in vals["depends"].split(","):
201 on = legitimize_package_name(dep)
202 dependency_pkg = format % on
203 modinfo_deps.append(dependency_pkg)
204 for dep in modinfo_deps:
205 if not dep in rdepends:
206 rdepends[dep] = []
207 d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
208
209 # Avoid automatic -dev recommendations for modules ending with -dev.
210 d.setVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs', 1)
211
212 # Provide virtual package without postfix
213 providevirt = d.getVar('KERNEL_MODULE_PROVIDE_VIRTUAL')
214 if providevirt == "1":
215 postfix = format.split('%s')[1]
216 d.setVar('RPROVIDES:' + pkg, pkg.replace(postfix, ''))
217
218 kernel_package_name = d.getVar("KERNEL_PACKAGE_NAME") or "kernel"
219 kernel_version = d.getVar("KERNEL_VERSION")
220
221 metapkg = d.getVar('KERNEL_MODULES_META_PACKAGE')
222 splitmods = d.getVar('KERNEL_SPLIT_MODULES')
223 postinst = d.getVar('pkg_postinst:modules')
224 postrm = d.getVar('pkg_postrm:modules')
225
226 module_regex = r'^(.*)\.k?o(?:\.(gz|xz|zst))?$'
227
228 module_pattern_prefix = d.getVar('KERNEL_MODULE_PACKAGE_PREFIX')
229 module_pattern_suffix = d.getVar('KERNEL_MODULE_PACKAGE_SUFFIX')
230 module_pattern = module_pattern_prefix + kernel_package_name + '-module-%s' + module_pattern_suffix
231
232 if splitmods != '1':
233 d.appendVar('FILES:' + metapkg, '%s %s %s/modules' %
234 (d.getVar('modulesloaddir'), d.getVar('modprobedir'), d.getVar("nonarch_base_libdir")))
235 d.appendVar('pkg_postinst:%s' % metapkg, postinst)
236 d.prependVar('pkg_postrm:%s' % metapkg, postrm)
237 generate_conf_files(d, root='${nonarch_base_libdir}/modules', file_regex=module_regex, output_pattern=module_pattern)
238 return
239
240 modules = do_split_packages(d, root='${nonarch_base_libdir}/modules', file_regex=module_regex, output_pattern=module_pattern, description='%s kernel module', postinst=postinst, postrm=postrm, recursive=True, hook=frob_metadata, extra_depends='%s-%s' % (kernel_package_name, kernel_version))
241 if modules:
242 d.appendVar('RDEPENDS:' + metapkg, ' '+' '.join(modules))
243}
244
245do_package[vardeps] += '${@" ".join(map(lambda s: "module_conf_" + s, (d.getVar("KERNEL_MODULE_PROBECONF") or "").split()))}'