11__author__ = "desultory"
2- __version__ = "3.5 .0"
2+ __version__ = "3.6 .0"
33
44from pathlib import Path
55from platform import uname
6+ from re import search
67from struct import error as StructError
78from struct import unpack
89from subprocess import run
910from typing import Union
1011
1112from ugrd .exceptions import AutodetectError , ValidationError
12- from ugrd .kmod import (
13- BuiltinModuleError ,
14- DependencyResolutionError ,
15- IgnoredModuleError ,
16- MissingModuleError ,
17- )
13+ from ugrd .kmod import BuiltinModuleError , DependencyResolutionError , IgnoredModuleError , MissingModuleError
1814from zenlib .util import colorize as c_
1915from zenlib .util import contains , unset
2016
17+ _KMOD_ALIASES = {}
2118MODULE_METADATA_FILES = ["modules.order" , "modules.builtin" , "modules.builtin.modinfo" ]
2219
20+
2321def _normalize_kmod_name (self , module : Union [str , list ]) -> str :
2422 """Replaces -'s with _'s in a kernel module name.
2523 ignores modules defined in kmod_no_normalize.
@@ -34,6 +32,43 @@ def _normalize_kmod_name(self, module: Union[str, list]) -> str:
3432 return module .replace ("-" , "_" )
3533
3634
35+ def _get_kmod_aliases (self ):
36+ """Returns a processed dictionary of kernel module aliases."""
37+ if _KMOD_ALIASES :
38+ return _KMOD_ALIASES
39+
40+ if not self .get ("kernel_version" ):
41+ raise AutodetectError ("Kernel version is not set, cannot resolve kernel module aliases." )
42+
43+ alias_file = Path ("/lib/modules" ) / self ["kernel_version" ] / "modules.alias"
44+ if not alias_file .exists ():
45+ raise FileNotFoundError (f"Kernel module alias file does not exist: { c_ (alias_file , 'red' , bold = True )} " )
46+
47+ for line in alias_file .read_text ().splitlines ():
48+ _ , alias , module = line .strip ().split (" " , 2 )
49+ # Strip bus type
50+ alias = alias .split (":" , 1 )[- 1 ]
51+ alias = alias .split ("," , 1 )[- 1 ]
52+ _KMOD_ALIASES [alias ] = _normalize_kmod_name (self , module )
53+ return _KMOD_ALIASES
54+
55+
56+ def _resolve_kmod_alias (self , module : str ) -> str :
57+ """Attempts to resolve a kernel module alias to a module name.
58+ Uses /lib/modules/<kernel_version>/modules.alias to find the module name.
59+ normalizes - to _ then replaces _ with [_-] to allow for both _ and - in the module name.
60+ """
61+ module = module .replace ("-" , "_" )
62+ module = module .replace ("_" , "[_-]" ) # Allow for both _ and - in the module name
63+ aliases = _get_kmod_aliases (self )
64+ for alias , kmod in aliases .items ():
65+ if search (module , alias ):
66+ self .logger .debug (f"Resolved kernel module alias: { c_ (alias , 'green' )} -> { c_ (kmod , 'cyan' )} " )
67+ return kmod
68+
69+ raise MissingModuleError (f"Failed to resolve kernel module alias: { module } " )
70+
71+
3772def _process_kernel_modules_multi (self , module : str ) -> None :
3873 """Adds kernel modules to self['kernel_modules']."""
3974 module = _normalize_kmod_name (self , module )
@@ -98,7 +133,13 @@ def _get_kmod_info(self, module: str):
98133 raise DependencyResolutionError ("[%s] Failed to run modinfo command: %s" % (module , " " .join (args ))) from e
99134
100135 if not cmd .stdout and cmd .stderr :
101- raise DependencyResolutionError ("[%s] Modinfo returned no output." % module )
136+ try :
137+ resolved_module = _resolve_kmod_alias (self , module )
138+ return _get_kmod_info (self , resolved_module )
139+ except MissingModuleError :
140+ raise DependencyResolutionError (
141+ "[%s] Modinfo returned no output and alias name could no be resolved." % module
142+ )
102143
103144 module_info = {}
104145 for line in cmd .stdout .decode ().split ("\n " ):
@@ -159,7 +200,9 @@ def _autodetect_modules_lsmod(self) -> None:
159200 modules = [line .split ()[0 ] for line in f .readlines ()]
160201
161202 if len (modules ) > 25 :
162- self .logger .warning (f"[{ len (modules )} ] More than 25 kernel modules were autodetected from the running kernel. If lsmod detection is required for your use case, please file a bug report so more appropriate detection methods can be implemented." )
203+ self .logger .warning (
204+ f"[{ len (modules )} ] More than 25 kernel modules were autodetected from the running kernel. If lsmod detection is required for your use case, please file a bug report so more appropriate detection methods can be implemented."
205+ )
163206 for module in modules :
164207 self ["_kmod_auto" ] = module .split ()[0 ]
165208
@@ -477,7 +520,9 @@ def _process_optional_modules(self) -> None:
477520 self .logger .debug (f"Optional kmod_init module is built-in, skipping: { c_ (kmod , 'yellow' )} " )
478521 continue
479522 except DependencyResolutionError as e :
480- self .logger .warning (f"[{ c_ (kmod , 'yellow' , bold = True )} ] Failed to process optional kernel module dependencies: { e } " )
523+ self .logger .warning (
524+ f"[{ c_ (kmod , 'yellow' , bold = True )} ] Failed to process optional kernel module dependencies: { e } "
525+ )
481526
482527
483528@unset ("no_kmod" , "no_kmod is enabled, skipping." , log_level = 30 )
@@ -486,6 +531,11 @@ def process_modules(self) -> None:
486531 _process_optional_modules (self )
487532 self .logger .debug ("Processing kernel modules: %s" % self ["kernel_modules" ])
488533 for kmod in self ["kernel_modules" ].copy ():
534+ """ Process all kernel modules
535+ for kmod_init modules, log an error if info can't be retreived, but continue processing.
536+ in successful cases, continue, if he module processing fails, add to the ignore list.
537+ Later, when ignored modules are processed, an exception is raised if the module is required.
538+ """
489539 self .logger .debug ("Processing kernel module: %s" % kmod )
490540 try :
491541 _process_kmod_dependencies (self , kmod )
@@ -507,6 +557,7 @@ def process_modules(self) -> None:
507557 self ["kmod_ignore" ] = kmod
508558
509559 for kmod in self ["_kmod_auto" ]:
560+ """ Do similar for automatic modules, but log warnings insead of errors if dependencies are missing. """
510561 if kmod in self ["kernel_modules" ]:
511562 self .logger .debug ("Autodetected module is already in kernel_modules: %s" % kmod )
512563 continue
0 commit comments