Show version information for built-in modules in sysfs
Subsystems (2)
PATCH 1/1 Show version information for built-in modules in sysfs
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might also be useful for built-in drivers as well. This especially important for drivers that do not define any parameters - such drivers, if built-in, are completely invisible from userspace.
This patch changes MODULE_VERSION() macro so that in case when we are compiling built-in module, version information is stored in a separate section. Kernel then uses this data to create 'version' sysfs attribute in the same fashion it creates attributes for module parameters.
---
This change is driven by our desire to detect whether vmw_balloon driver is built-in into the kernel when we installing our tool package in the guest and avoid installing our own version of the driver.
Since vmw_balloon does not have any module parameter nor registers any driver core devices, without this patch it is completely invisible from userspace when built into the kernel.
Thanks,
Dmitry
include/asm-generic/vmlinux.lds.h | 7 ++++ include/linux/module.h | 27 +++++++++++++++ kernel/params.c | 65 ++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 11 deletions(-)
include/asm-generic/vmlinux.lds.h +7 -0
@@ -355,6 +355,13 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param ) \ VMLINUX_SYMBOL(__stop___param) = .; \ + } \ + \ +/* Built-in module versions. */ \ + __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___modver) = .; \ + *(__modver ) \ + VMLINUX_SYMBOL(__stop___modver) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \
include/linux/module.h +27 -0
@@ -58,6 +58,12 @@ struct module_attribute {void (*free)(struct module *); }; +struct module_version_attribute { +struct module_attribute mattr; +const char *module_name; +const char *version; +}; +struct module_kobject {struct kobject kobj;
@@ -161,7 +167,28 @@ extern struct module __this_module;Using this automatically adds a checksum of the .c files and the local headers in "srcversion". */ + +#ifdef MODULE #define MODULE_VERSION (_version) MODULE_INFO(version, _version) +#else +#define MODULE_VERSION (_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \ + = { \ + .mattr = { \ + .attr = { \ + .name = "version", \ + .mode = S_IRUGO, \ + }, \ + .show = __modver_version_show, \ + }, \ + .module_name = KBUILD_MODNAME, \ + .version = _version, \ + } +#endif /* Optional firmware file (or files) needed by the module * format is simply firmware file name. Multiple firmware
kernel/params.c +54 -11
100 lines not on this page · raw message
Signature · 1 line
1.7.3.2
Quoted 2 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might
Can you create just /sys/module/x?
Module version info is quite useless by itself.
Quoted 6 lines · Alexey Dobriyan
Quoted 2 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might
Can you create just
/sys/module/x?
Module version info is quite useless by itself.
It is as useful as in the case where driver is built as a module. I am just trying to unify the behavior a bit.
Code-wise it is almost as cheap to add /sys/module/x/version as adding just the directory.
Thanks,
Dmitry
Quoted 5 lines · Dmitry Torokhov
Quoted 4 lines · Alexey Dobriyan
Quoted 2 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might
Quoted 8 lines
Quoted 2 lines
Can you create just
/sys/module/x?
Module version info is quite useless by itself.It is as useful as in the case where driver is built as a module. I am just trying to unify the behavior a bit.
Code-wise it is almost as cheap to add
/sys/module/x/versionas adding just the directory.
OK.
Still, people are using /sys/module/x presence as indicator of modular built (unsurprisingly).
Quoted 15 lines · Alexey Dobriyan
Quoted 5 lines · Dmitry Torokhov
Quoted 4 lines · Alexey Dobriyan
Quoted 2 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might
Quoted 8 lines
Quoted 2 lines
Can you create just
/sys/module/x?
Module version info is quite useless by itself.It is as useful as in the case where driver is built as a module. I am just trying to unify the behavior a bit.
Code-wise it is almost as cheap to add
/sys/module/x/versionas adding just the directory.
Quoted 6 lines
OK.
Still, people are using
/sys/module/xpresence as indicator of modular built (unsurprisingly).
Yeah, I hate to disappoint them but it will break as soon as someone adds a module_param() to one of the objects... That's even without my changes.
Signature · 1 line
Dmitry
Quoted 18 lines · Dmitry Torokhov
Quoted 17 lines · Alexey Dobriyan
Quoted 5 lines · Dmitry Torokhov
Quoted 4 lines · Alexey Dobriyan
Quoted 2 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might
Quoted 8 lines
Quoted 2 lines
Can you create just
/sys/module/x?
Module version info is quite useless by itself.It is as useful as in the case where driver is built as a module. I am just trying to unify the behavior a bit.
Code-wise it is almost as cheap to add
/sys/module/x/versionas adding just the directory.OK.
Quoted 8 lines
Quoted 4 lines
Still, people are using
/sys/module/xpresence as indicator of modular built (unsurprisingly).Yeah, I hate to disappoint them but it will break as soon as someone adds a
module_param()to one of the objects... That's even without my changes.
Looking at this some more they are concerned whether bluetooth is present in the kernel, not whether it is loaded: if you care about power consumption you need to shut off BT interface whether BT core is a module or built-in. In this regard I'd say my change will make that code behave better ;)
Signature · 1 line
Dmitry
Quoted 3 lines · Dmitry Torokhov
Yeah, I hate to disappoint them but it will break as soon as someone adds a
module_param()to one of the objects... That's even without my changes.
Yeah, it should have been renamed to /sys/tristate :-\
Quoted 6 lines · Alexey Dobriyan
Quoted 3 lines · Dmitry Torokhov
Yeah, I hate to disappoint them but it will break as soon as someone adds a
module_param()to one of the objects... That's even without my changes.Yeah, it should have been renamed to
/sys/tristate:-\
Anyway, I've appled the patch.
Thanks,
Rusty.
Quoted 69 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might also be useful for built-in drivers as well. This especially important for drivers that do not define any parameters - such drivers, if built-in, are completely invisible from userspace.
This patch changes
MODULE_VERSION()macro so that in case when we are compiling built-in module, version information is stored in a separate section. Kernel then uses this data to create 'version' sysfs attribute in the same fashion it creates attributes for module parameters.Signed-off-by Dmitry Torokhov <[email protected]>---
This change is driven by our desire to detect whether
vmw_balloondriver is built-in into the kernel when we installing our tool package in the guest and avoid installing our own version of the driver.Since
vmw_balloondoes not have any module parameter nor registers any driver core devices, without this patch it is completely invisible from userspace when built into the kernel.Thanks,
Dmitryinclude/asm-generic/vmlinux.lds.h | 7 ++++ include/linux/module.h | 27 +++++++++++++++ kernel/params.c | 65 ++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 11 deletions(-)include/asm-generic/vmlinux.lds.h +7
-0@@ -355,6 +355,13 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param ) \ VMLINUX_SYMBOL(__stop___param) = .; \ + } \ + \ +/* Built-in module versions. */ \ + __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___modver) = .; \ + *(__modver ) \ + VMLINUX_SYMBOL(__stop___modver) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \include/linux/module.h +6
-0@@ -58,6 +58,12 @@ struct module_attribute {void (*free)(struct module *); }; +struct module_version_attribute { +struct module_attribute mattr; +const char *module_name; +const char *version; +}; +struct module_kobject {struct kobject kobj;@@ -161,7 +167,28 @@ extern struct module __this_module;Using this automatically adds a checksum of the .c files and the local headers in "srcversion". */
include/linux/module.h extern struct module __this_module; · line 179
Quoted 10 lines
include/linux/module.h +9
-0+ +#ifdef MODULE #define MODULE_VERSION (_version) MODULE_INFO(version, _version) +#else +#define MODULE_VERSION (_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \
__used and unused seems overkill, and confused.
Removed unused.
Cheers,
Rusty.
Quoted 74 lines · Rusty Russell
Quoted 73 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might also be useful for built-in drivers as well. This especially important for drivers that do not define any parameters - such drivers, if built-in, are completely invisible from userspace.
This patch changes
MODULE_VERSION()macro so that in case when we are compiling built-in module, version information is stored in a separate section. Kernel then uses this data to create 'version' sysfs attribute in the same fashion it creates attributes for module parameters.Signed-off-by Dmitry Torokhov <[email protected]>---
This change is driven by our desire to detect whether
vmw_balloondriver is built-in into the kernel when we installing our tool package in the guest and avoid installing our own version of the driver.Since
vmw_balloondoes not have any module parameter nor registers any driver core devices, without this patch it is completely invisible from userspace when built into the kernel.Thanks,
Dmitryinclude/asm-generic/vmlinux.lds.h | 7 ++++ include/linux/module.h | 27 +++++++++++++++ kernel/params.c | 65 ++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 11 deletions(-)include/asm-generic/vmlinux.lds.h +7
-0@@ -355,6 +355,13 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param ) \ VMLINUX_SYMBOL(__stop___param) = .; \ + } \ + \ +/* Built-in module versions. */ \ + __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___modver) = .; \ + *(__modver ) \ + VMLINUX_SYMBOL(__stop___modver) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \include/linux/module.h +9
-0@@ -58,6 +58,12 @@ struct module_attribute {void (*free)(struct module *); }; +struct module_version_attribute { +struct module_attribute mattr; +const char *module_name; +const char *version; +}; +struct module_kobject {struct kobject kobj;@@ -161,7 +167,28 @@ extern struct module __this_module;Using this automatically adds a checksum of the .c files and the local headers in "srcversion". */ + +#ifdef MODULE #define MODULE_VERSION (_version) MODULE_INFO(version, _version) +#else
Quoted 9 lines
include/linux/module.h extern struct module __this_module; · line 179
Quoted 6 lines
include/linux/module.h +6
-0+#define MODULE_VERSION (_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \
__usedand unused seems overkill, and confused.
Must admit that I copied used/unused verbatim from linux/moduleparam.h:
/* This is the fundamental function for registering boot/module
parameters. */
#define __module_param_call(prefix, name, ops, arg, isbool, perm) \
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
+ BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \
static const char __param_str_##name[] = prefix #name; \
static struct kernel_param __moduleparam_const __param_##name \
__used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \
{ arg } }So should it be removed from here as well?
Thanks,
Dmitry
Quoted 102 lines · Dmitry Torokhov
Quoted 74 lines · Rusty Russell
Quoted 73 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might also be useful for built-in drivers as well. This especially important for drivers that do not define any parameters - such drivers, if built-in, are completely invisible from userspace.
This patch changes
MODULE_VERSION()macro so that in case when we are compiling built-in module, version information is stored in a separate section. Kernel then uses this data to create 'version' sysfs attribute in the same fashion it creates attributes for module parameters.Signed-off-by Dmitry Torokhov <[email protected]>---
This change is driven by our desire to detect whether
vmw_balloondriver is built-in into the kernel when we installing our tool package in the guest and avoid installing our own version of the driver.Since
vmw_balloondoes not have any module parameter nor registers any driver core devices, without this patch it is completely invisible from userspace when built into the kernel.Thanks,
Dmitryinclude/asm-generic/vmlinux.lds.h | 7 ++++ include/linux/module.h | 27 +++++++++++++++ kernel/params.c | 65 ++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 11 deletions(-)include/asm-generic/vmlinux.lds.h +7
-0@@ -355,6 +355,13 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param ) \ VMLINUX_SYMBOL(__stop___param) = .; \ + } \ + \ +/* Built-in module versions. */ \ + __modver : AT(ADDR(__modver) - LOAD_OFFSET) { \ + VMLINUX_SYMBOL(__start___modver) = .; \ + *(__modver ) \ + VMLINUX_SYMBOL(__stop___modver) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \include/linux/module.h +9
-0@@ -58,6 +58,12 @@ struct module_attribute {void (*free)(struct module *); }; +struct module_version_attribute { +struct module_attribute mattr; +const char *module_name; +const char *version; +}; +struct module_kobject {struct kobject kobj;@@ -161,7 +167,28 @@ extern struct module __this_module;Using this automatically adds a checksum of the .c files and the local headers in "srcversion". */ + +#ifdef MODULE #define MODULE_VERSION (_version) MODULE_INFO(version, _version) +#else Quoted 9 lines
include/linux/module.h extern struct module __this_module; · line 179
Quoted 6 lines
include/linux/module.h +6
-0+#define MODULE_VERSION (_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \
__usedand unused seems overkill, and confused.Must admit that I copied used/unused verbatim from
linux/moduleparam.h:/* This is the fundamental function for registering boot/module
parameters. */#define __module_param_call(prefix, name, ops, arg, isbool, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ { arg } }
Quoted 1 line
So should it be removed from here as well?
I think so, but (as always!) check git blame.
Patch welcome!
Rusty.
Quoted 34 lines · Rusty Russell
Quoted 33 lines · Dmitry Torokhov
Quoted 14 lines · Rusty Russell
Review
Quoted 10 lines · Dmitry Torokhov
(quoted diff) +9
-0+ +#ifdef MODULE #define MODULE_VERSION(_version) MODULE_INFO(version, _version) +#else +#define MODULE_VERSION(_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \
__usedand unused seems overkill, and confused.Must admit that I copied used/unused verbatim from
linux/moduleparam.h:/* This is the fundamental function for registering boot/module
parameters. */#define __module_param_call(prefix, name, ops, arg, isbool, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ { arg } }
Quoted 4 lines
Quoted 1 line
So should it be removed from here as well?
I think so, but (as always!) check git blame.
Whew, found it:
commit 4d62364652499ef106d1c0737968a879ef077bd4
Author: akpm <akpm> Date: Tue Jan 20 05:13:24 2004 +0000
[PATCH] make gcc 3.4 compilation work
From: David Mosberger <[email protected]>
With gcc-3.4 we need "attribute((used))" declarations to get "make modules_install" to work.
Otherwise these sections get dropped from the final image (I assume).
BKrev: 400cb8f4ByHxZCElstAaZ3mBZ2oflQ
...
include/linux/moduleparam.h +1 -0
@@ -52,6 +52,7 @@ struct kparam_array#define __module_param_call (prefix, name, set, get, arg, perm) \ static char __param_str_##name[] __initdata = prefix #name; \ static struct kernel_param const __param_##name \ + __attribute_used__ \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, arg }
Since we still claim to support GCC 3.4 I guess __used is still needed...
Thanks,
Dmitry
Quoted 72 lines · Dmitry Torokhov
Quoted 34 lines · Rusty Russell
Quoted 33 lines · Dmitry Torokhov
Quoted 14 lines · Rusty Russell
Review
Quoted 10 lines · Dmitry Torokhov
(quoted diff) +9
-0+ +#ifdef MODULE #define MODULE_VERSION(_version) MODULE_INFO(version, _version) +#else +#define MODULE_VERSION(_version) \ + extern ssize_t __modver_version_show(struct module_attribute *, \ + struct module *, char *); \ + static struct module_version_attribute __modver_version_attr \ + __used \ + __attribute__ ((unused,__section__ ("__modver"),aligned(sizeof(void *)))) \
__usedand unused seems overkill, and confused.Must admit that I copied used/unused verbatim from
linux/moduleparam.h:/* This is the fundamental function for registering boot/module
parameters. */#define __module_param_call(prefix, name, ops, arg, isbool, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \ { arg } }Quoted 4 lines
Quoted 1 line
So should it be removed from here as well?
I think so, but (as always!) check git blame.
Whew, found it:
commit
4d62364652499ef106d1c0737968a879ef077bd4Author: akpm <akpm> Date: Tue Jan 20 05:13:24 2004 +0000[PATCH] make gcc 3.4 compilation work
From: David Mosberger <[email protected]>
With gcc-3.4 we need "attribute((used))" declarations to get "make
modules_install" to work.Otherwise these sections get dropped from the final image (I assume).
BKrev: 400cb8f4ByHxZCElstAaZ3mBZ2oflQ
...
include/linux/moduleparam.h +1
-0@@ -52,6 +52,7 @@ struct kparam_array#define __module_param_call (prefix, name, set, get, arg, perm) \ static char __param_str_##name[] __initdata = prefix #name; \ static struct kernel_param const __param_##name \ + __attribute_used__ \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, arg }
Quoted 2 lines
Since we still claim to support GCC 3.4 I guess
__usedis still needed...
Well, __used is correct. But this unused should have been removed at the same time.
Cheers,
Rusty.
Quoted 12 lines · Rusty Russell
Quoted 11 lines · Dmitry Torokhov
Currently only drivers that are built as modules have their versions shown in /sys/module/<module_name>/version, but this information might also be useful for built-in drivers as well. This especially important for drivers that do not define any parameters - such drivers, if built-in, are completely invisible from userspace.
This patch changes
MODULE_VERSION()macro so that in case when we are compiling built-in module, version information is stored in a separate section. Kernel then uses this data to create 'version' sysfs attribute in the same fashion it creates attributes for module parameters.
...
Quoted 5 lines
__usedand unused seems overkill, and confused.Removed unused.
Rusty,
What is the status of the patch? It woudl be nice if it coudl make it into .38.
Thanks!
Signature · 1 line
Dmitry