module: support reading coresize from /sys if supported

Linux 3.3 introduced the coresize attribute in /sys/module/*. When
available, use this instead of parsing some portion of /proc/modules.
This commit is contained in:
Dave Reisner 2012-06-28 09:09:48 -04:00
parent 2588e3dff5
commit 486f901392
1 changed files with 27 additions and 3 deletions

View File

@ -1679,22 +1679,43 @@ KMOD_EXPORT int kmod_module_get_initstate(const struct kmod_module *mod)
* kmod_module_get_size:
* @mod: kmod module
*
* Get the size of this kmod module as returned by Linux kernel. It reads the
* file /proc/modules to search for this module and get its size.
* Get the size of this kmod module as returned by Linux kernel. If supported,
* the size is read from the coresize attribute in /sys/module. For older
* kernels, this falls back on /proc/modules and searches for the specified
* module to get its size.
*
* Returns: the size of this kmod module.
*/
KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
{
// FIXME TODO: this should be available from /sys/module/foo
FILE *fp;
char line[4096];
int lineno = 0;
long size = -ENOENT;
int dfd, cfd;
if (mod == NULL)
return -ENOENT;
/* try to open the module dir in /sys. If this fails, don't
* bother trying to find the size as we know the module isn't
* loaded.
*/
snprintf(line, sizeof(line), "/sys/module/%s", mod->name);
dfd = open(line, O_RDONLY);
if (dfd < 0)
return -errno;
/* available as of linux 3.3.x */
cfd = openat(dfd, "coresize", O_RDONLY|O_CLOEXEC);
if (cfd >= 0) {
if (read_str_long(cfd, &size, 10) < 0)
ERR(mod->ctx, "failed to read coresize from %s\n", line);
close(cfd);
goto done;
}
/* fall back on parsing /proc/modules */
fp = fopen("/proc/modules", "re");
if (fp == NULL) {
int err = -errno;
@ -1729,6 +1750,9 @@ KMOD_EXPORT long kmod_module_get_size(const struct kmod_module *mod)
break;
}
fclose(fp);
done:
close(dfd);
return size;
}