xref: /OK3568_Linux_fs/yocto/poky/meta/classes/kernel-module-split.bbclass (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyunpkg_postinst:modules () {
2*4882a593Smuzhiyunif [ -z "$D" ]; then
3*4882a593Smuzhiyun	depmod -a ${KERNEL_VERSION}
4*4882a593Smuzhiyunelse
5*4882a593Smuzhiyun	# image.bbclass will call depmodwrapper after everything is installed,
6*4882a593Smuzhiyun	# no need to do it here as well
7*4882a593Smuzhiyun	:
8*4882a593Smuzhiyunfi
9*4882a593Smuzhiyun}
10*4882a593Smuzhiyun
11*4882a593Smuzhiyunpkg_postrm:modules () {
12*4882a593Smuzhiyunif [ -z "$D" ]; then
13*4882a593Smuzhiyun	depmod -a ${KERNEL_VERSION}
14*4882a593Smuzhiyunelse
15*4882a593Smuzhiyun	depmodwrapper -a -b $D ${KERNEL_VERSION}
16*4882a593Smuzhiyunfi
17*4882a593Smuzhiyun}
18*4882a593Smuzhiyun
19*4882a593Smuzhiyunautoload_postinst_fragment() {
20*4882a593Smuzhiyunif [ x"$D" = "x" ]; then
21*4882a593Smuzhiyun	modprobe %s || true
22*4882a593Smuzhiyunfi
23*4882a593Smuzhiyun}
24*4882a593Smuzhiyun
25*4882a593SmuzhiyunPACKAGE_WRITE_DEPS += "kmod-native depmodwrapper-cross"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyundo_install:append() {
28*4882a593Smuzhiyun	install -d ${D}${sysconfdir}/modules-load.d/ ${D}${sysconfdir}/modprobe.d/
29*4882a593Smuzhiyun}
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunKERNEL_SPLIT_MODULES ?= "1"
32*4882a593SmuzhiyunPACKAGESPLITFUNCS:prepend = "split_kernel_module_packages "
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunKERNEL_MODULES_META_PACKAGE ?= "${@ d.getVar("KERNEL_PACKAGE_NAME") or "kernel" }-modules"
35*4882a593Smuzhiyun
36*4882a593SmuzhiyunKERNEL_MODULE_PACKAGE_PREFIX ?= ""
37*4882a593SmuzhiyunKERNEL_MODULE_PACKAGE_SUFFIX ?= "-${KERNEL_VERSION}"
38*4882a593SmuzhiyunKERNEL_MODULE_PROVIDE_VIRTUAL ?= "1"
39*4882a593Smuzhiyun
40*4882a593Smuzhiyunpython split_kernel_module_packages () {
41*4882a593Smuzhiyun    import re
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun    modinfoexp = re.compile("([^=]+)=(.*)")
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun    def extract_modinfo(file):
46*4882a593Smuzhiyun        import tempfile, subprocess
47*4882a593Smuzhiyun        tempfile.tempdir = d.getVar("WORKDIR")
48*4882a593Smuzhiyun        compressed = re.match( r'.*\.(gz|xz|zst)$', file)
49*4882a593Smuzhiyun        tf = tempfile.mkstemp()
50*4882a593Smuzhiyun        tmpfile = tf[1]
51*4882a593Smuzhiyun        if compressed:
52*4882a593Smuzhiyun            tmpkofile = tmpfile + ".ko"
53*4882a593Smuzhiyun            if compressed.group(1) == 'gz':
54*4882a593Smuzhiyun                cmd = "gunzip -dc %s > %s" % (file, tmpkofile)
55*4882a593Smuzhiyun                subprocess.check_call(cmd, shell=True)
56*4882a593Smuzhiyun            elif compressed.group(1) == 'xz':
57*4882a593Smuzhiyun                cmd = "xz -dc %s > %s" % (file, tmpkofile)
58*4882a593Smuzhiyun                subprocess.check_call(cmd, shell=True)
59*4882a593Smuzhiyun            elif compressed.group(1) == 'zst':
60*4882a593Smuzhiyun                cmd = "zstd -dc %s > %s" % (file, tmpkofile)
61*4882a593Smuzhiyun                subprocess.check_call(cmd, shell=True)
62*4882a593Smuzhiyun            else:
63*4882a593Smuzhiyun                msg = "Cannot decompress '%s'" % file
64*4882a593Smuzhiyun                raise msg
65*4882a593Smuzhiyun            cmd = "%sobjcopy -j .modinfo -O binary %s %s" % (d.getVar("HOST_PREFIX") or "", tmpkofile, tmpfile)
66*4882a593Smuzhiyun        else:
67*4882a593Smuzhiyun            cmd = "%sobjcopy -j .modinfo -O binary %s %s" % (d.getVar("HOST_PREFIX") or "", file, tmpfile)
68*4882a593Smuzhiyun        subprocess.check_call(cmd, shell=True)
69*4882a593Smuzhiyun        # errors='replace': Some old kernel versions contain invalid utf-8 characters in mod descriptions (like 0xf6, 'ö')
70*4882a593Smuzhiyun        f = open(tmpfile, errors='replace')
71*4882a593Smuzhiyun        l = f.read().split("\000")
72*4882a593Smuzhiyun        f.close()
73*4882a593Smuzhiyun        os.close(tf[0])
74*4882a593Smuzhiyun        os.unlink(tmpfile)
75*4882a593Smuzhiyun        if compressed:
76*4882a593Smuzhiyun            os.unlink(tmpkofile)
77*4882a593Smuzhiyun        vals = {}
78*4882a593Smuzhiyun        for i in l:
79*4882a593Smuzhiyun            m = modinfoexp.match(i)
80*4882a593Smuzhiyun            if not m:
81*4882a593Smuzhiyun                continue
82*4882a593Smuzhiyun            vals[m.group(1)] = m.group(2)
83*4882a593Smuzhiyun        return vals
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun    def frob_metadata(file, pkg, pattern, format, basename):
86*4882a593Smuzhiyun        vals = extract_modinfo(file)
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun        dvar = d.getVar('PKGD')
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun        # If autoloading is requested, output /etc/modules-load.d/<name>.conf and append
91*4882a593Smuzhiyun        # appropriate modprobe commands to the postinst
92*4882a593Smuzhiyun        autoloadlist = (d.getVar("KERNEL_MODULE_AUTOLOAD") or "").split()
93*4882a593Smuzhiyun        autoload = d.getVar('module_autoload_%s' % basename)
94*4882a593Smuzhiyun        if autoload and autoload == basename:
95*4882a593Smuzhiyun            bb.warn("module_autoload_%s was replaced by KERNEL_MODULE_AUTOLOAD for cases where basename == module name, please drop it" % basename)
96*4882a593Smuzhiyun        if autoload and basename not in autoloadlist:
97*4882a593Smuzhiyun            bb.warn("module_autoload_%s is defined but '%s' isn't included in KERNEL_MODULE_AUTOLOAD, please add it there" % (basename, basename))
98*4882a593Smuzhiyun        if basename in autoloadlist:
99*4882a593Smuzhiyun            name = '%s/etc/modules-load.d/%s.conf' % (dvar, basename)
100*4882a593Smuzhiyun            f = open(name, 'w')
101*4882a593Smuzhiyun            if autoload:
102*4882a593Smuzhiyun                for m in autoload.split():
103*4882a593Smuzhiyun                    f.write('%s\n' % m)
104*4882a593Smuzhiyun            else:
105*4882a593Smuzhiyun                f.write('%s\n' % basename)
106*4882a593Smuzhiyun            f.close()
107*4882a593Smuzhiyun            postinst = d.getVar('pkg_postinst:%s' % pkg)
108*4882a593Smuzhiyun            if not postinst:
109*4882a593Smuzhiyun                bb.fatal("pkg_postinst:%s not defined" % pkg)
110*4882a593Smuzhiyun            postinst += d.getVar('autoload_postinst_fragment') % (autoload or basename)
111*4882a593Smuzhiyun            d.setVar('pkg_postinst:%s' % pkg, postinst)
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun        # Write out any modconf fragment
114*4882a593Smuzhiyun        modconflist = (d.getVar("KERNEL_MODULE_PROBECONF") or "").split()
115*4882a593Smuzhiyun        modconf = d.getVar('module_conf_%s' % basename)
116*4882a593Smuzhiyun        if modconf and basename in modconflist:
117*4882a593Smuzhiyun            name = '%s/etc/modprobe.d/%s.conf' % (dvar, basename)
118*4882a593Smuzhiyun            f = open(name, 'w')
119*4882a593Smuzhiyun            f.write("%s\n" % modconf)
120*4882a593Smuzhiyun            f.close()
121*4882a593Smuzhiyun        elif modconf:
122*4882a593Smuzhiyun            bb.error("Please ensure module %s is listed in KERNEL_MODULE_PROBECONF since module_conf_%s is set" % (basename, basename))
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun        files = d.getVar('FILES:%s' % pkg)
125*4882a593Smuzhiyun        files = "%s /etc/modules-load.d/%s.conf /etc/modprobe.d/%s.conf" % (files, basename, basename)
126*4882a593Smuzhiyun        d.setVar('FILES:%s' % pkg, files)
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun        conffiles = d.getVar('CONFFILES:%s' % pkg)
129*4882a593Smuzhiyun        conffiles = "%s /etc/modules-load.d/%s.conf /etc/modprobe.d/%s.conf" % (conffiles, basename, basename)
130*4882a593Smuzhiyun        d.setVar('CONFFILES:%s' % pkg, conffiles)
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun        if "description" in vals:
133*4882a593Smuzhiyun            old_desc = d.getVar('DESCRIPTION:' + pkg) or ""
134*4882a593Smuzhiyun            d.setVar('DESCRIPTION:' + pkg, old_desc + "; " + vals["description"])
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun        rdepends = bb.utils.explode_dep_versions2(d.getVar('RDEPENDS:' + pkg) or "")
137*4882a593Smuzhiyun        modinfo_deps = []
138*4882a593Smuzhiyun        if "depends" in vals and vals["depends"] != "":
139*4882a593Smuzhiyun            for dep in vals["depends"].split(","):
140*4882a593Smuzhiyun                on = legitimize_package_name(dep)
141*4882a593Smuzhiyun                dependency_pkg = format % on
142*4882a593Smuzhiyun                modinfo_deps.append(dependency_pkg)
143*4882a593Smuzhiyun        for dep in modinfo_deps:
144*4882a593Smuzhiyun            if not dep in rdepends:
145*4882a593Smuzhiyun                rdepends[dep] = []
146*4882a593Smuzhiyun        d.setVar('RDEPENDS:' + pkg, bb.utils.join_deps(rdepends, commasep=False))
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun        # Avoid automatic -dev recommendations for modules ending with -dev.
149*4882a593Smuzhiyun        d.setVarFlag('RRECOMMENDS:' + pkg, 'nodeprrecs', 1)
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun        # Provide virtual package without postfix
152*4882a593Smuzhiyun        providevirt = d.getVar('KERNEL_MODULE_PROVIDE_VIRTUAL')
153*4882a593Smuzhiyun        if providevirt == "1":
154*4882a593Smuzhiyun           postfix = format.split('%s')[1]
155*4882a593Smuzhiyun           d.setVar('RPROVIDES:' + pkg, pkg.replace(postfix, ''))
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun    kernel_package_name = d.getVar("KERNEL_PACKAGE_NAME") or "kernel"
158*4882a593Smuzhiyun    kernel_version = d.getVar("KERNEL_VERSION")
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun    metapkg = d.getVar('KERNEL_MODULES_META_PACKAGE')
161*4882a593Smuzhiyun    splitmods = d.getVar('KERNEL_SPLIT_MODULES')
162*4882a593Smuzhiyun    postinst = d.getVar('pkg_postinst:modules')
163*4882a593Smuzhiyun    postrm = d.getVar('pkg_postrm:modules')
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun    if splitmods != '1':
166*4882a593Smuzhiyun        etcdir = d.getVar('sysconfdir')
167*4882a593Smuzhiyun        d.appendVar('FILES:' + metapkg, '%s/modules-load.d/ %s/modprobe.d/ %s/modules/' % (etcdir, etcdir, d.getVar("nonarch_base_libdir")))
168*4882a593Smuzhiyun        d.appendVar('pkg_postinst:%s' % metapkg, postinst)
169*4882a593Smuzhiyun        d.prependVar('pkg_postrm:%s' % metapkg, postrm);
170*4882a593Smuzhiyun        return
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun    module_regex = r'^(.*)\.k?o(?:\.(gz|xz|zst))?$'
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun    module_pattern_prefix = d.getVar('KERNEL_MODULE_PACKAGE_PREFIX')
175*4882a593Smuzhiyun    module_pattern_suffix = d.getVar('KERNEL_MODULE_PACKAGE_SUFFIX')
176*4882a593Smuzhiyun    module_pattern = module_pattern_prefix + kernel_package_name + '-module-%s' + module_pattern_suffix
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun    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))
179*4882a593Smuzhiyun    if modules:
180*4882a593Smuzhiyun        d.appendVar('RDEPENDS:' + metapkg, ' '+' '.join(modules))
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun    # If modules-load.d and modprobe.d are empty at this point, remove them to
183*4882a593Smuzhiyun    # avoid warnings. removedirs only raises an OSError if an empty
184*4882a593Smuzhiyun    # directory cannot be removed.
185*4882a593Smuzhiyun    dvar = d.getVar('PKGD')
186*4882a593Smuzhiyun    for dir in ["%s/etc/modprobe.d" % (dvar), "%s/etc/modules-load.d" % (dvar), "%s/etc" % (dvar)]:
187*4882a593Smuzhiyun        if len(os.listdir(dir)) == 0:
188*4882a593Smuzhiyun            os.rmdir(dir)
189*4882a593Smuzhiyun}
190*4882a593Smuzhiyun
191*4882a593Smuzhiyundo_package[vardeps] += '${@" ".join(map(lambda s: "module_conf_" + s, (d.getVar("KERNEL_MODULE_PROBECONF") or "").split()))}'
192