[PATCH] Automatic kernel version module dependencies..
John Baldwin
jhb at freebsd.org
Fri Feb 8 15:33:20 PST 2008
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
More information about the freebsd-arch
mailing list