Date: Fri, 8 Feb 2008 18:02:54 -0500 From: John Baldwin <jhb@freebsd.org> To: arch@freebsd.org Subject: [PATCH] Automatic kernel version module dependencies.. Message-ID: <200802081802.54313.jhb@freebsd.org>
next in thread | raw e-mail | index | archive | help
So one of the things that people run into periodically are problems with mismatched kernels and modules. My understanding of our kernel module ABI compatibility is that if you build a module on in a X.Y build environment the module should work fine for all kernels with version X.Z where Z >= Y. In concrete terms, a module built on a 6.2 system is not guaranteed to work on a 6.1 kernel, a 5.2 kernel, or a 7.0 kernel. However, it should work fine on 6.2, 6.3, etc. The patch below implements this policy by create a 'kernel' module version based on __FreeBSD_version. It then adds a version dependency on 'kernel' in every kernel module that requires a version range starting with the current __FreeBSD_version and ending with the maximum __FreeBSD_version value for the current branch. This does seem to work in that a kernel module compiled with artificial values of __FreeBSD_version refuses to load when it violates the rule above (too old or wrong branch). One thing this doesn't fix is that right now the error from the kernel linker is simply that "kernel could not be found" or some such. It might be nicer if the error could be "module requires kernel version X to Y, but only Z was found", but that would be a separate patch. --- //depot/vendor/freebsd/src/sys/kern/kern_module.c 2007/12/06 23:12:58 +++ //depot/user/jhb/acpipci/kern/kern_module.c 2008/02/07 18:59:28 @@ -414,6 +414,8 @@ return (error); } +MODULE_VERSION(kernel, __FreeBSD_version); + #ifdef COMPAT_IA32 #include <sys/mount.h> #include <sys/socket.h> --- //depot/vendor/freebsd/src/sys/sys/module.h 2006/04/17 19:46:13 +++ //depot/user/jhb/acpipci/sys/module.h 2008/02/07 22:11:55 @@ -114,7 +114,20 @@ MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND, \ &_##module##_depend_on_##mdepend, #mdepend) +/* + * Every kernel has a 'kernel' module with the version set to + * __FreeBSD_version. We embed a MODULE_DEPEND() inside every module + * that depends on the 'kernel' module. It uses the current value of + * __FreeBSD_version as the minimum and preferred versions. For the + * maximum version it rounds the version up to the end of its branch + * (i.e. M99999 for M.x). This allows a module built on M.x to work + * on M.y systems where y >= x, but fail on M.z systems where z < x. + */ +#define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1) + #define DECLARE_MODULE(name, data, sub, order) \ + MODULE_DEPEND(name, kernel, __FreeBSD_version, \ + __FreeBSD_version, MODULE_KERNEL_MAXVER); \ MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name); \ SYSINIT(name##module, sub, order, module_register_init, &data) \ struct __hack -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802081802.54313.jhb>