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