]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
module: support reading coresize from /sys if supported
authorDave Reisner <dreisner@archlinux.org>
Thu, 28 Jun 2012 13:09:48 +0000 (09:09 -0400)
committerDave Reisner <dreisner@archlinux.org>
Fri, 29 Jun 2012 17:04:41 +0000 (13:04 -0400)
Linux 3.3 introduced the coresize attribute in /sys/module/*. When
available, use this instead of parsing some portion of /proc/modules.

libkmod/libkmod-module.c

index fb3a64e1f19a6a69b05a410db6253b005c632e00..1271c70b6c56ac2d8cb50c92425f67fb092c5a02 100644 (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;
 }