[PATCH] [WIP]tools: add devname2tmpfile

Tom Gundersen <[email protected]>
Newsgroups gmane.linux.kernel.modules,gmane.linux.hotplug.devel,gmane.comp.sysutils.systemd.devel
Message-ID <[email protected]>
This tool reads modules.devname from the current kernel directory and writes the information
out in the tmpfiles format so that systemd-tmpfiles can use this to create the required device
nodes before systemd-udevd is started on boot.

This makes sure nothing but kmod reads the private files under
/usr/lib/modules/.

Cc: <[email protected]>
Cc: <[email protected]>
---
 Makefile.am             |   3 +-
 tools/devname2tmpfile.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++
 tools/kmod.c            |   1 +
 tools/kmod.h            |   1 +
 4 files changed, 130 insertions(+), 1 deletion(-)
 create mode 100644 tools/devname2tmpfile.c

diff --git a/Makefile.am b/Makefile.am
index 9feaf96..50cd380 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -109,7 +109,8 @@ noinst_SCRIPTS = tools/insmod tools/rmmod tools/lsmod \
 tools_kmod_SOURCES = tools/kmod.c tools/kmod.h tools/lsmod.c \
 		     tools/rmmod.c tools/insmod.c \
 		     tools/modinfo.c tools/modprobe.c \
-		     tools/depmod.c tools/log.h tools/log.c
+		     tools/depmod.c tools/log.h tools/log.c \
+		     tools/devname2tmpfile.c
 tools_kmod_LDADD = libkmod/libkmod-util.la \
 		   libkmod/libkmod.la
 
diff --git a/tools/devname2tmpfile.c b/tools/devname2tmpfile.c
new file mode 100644
index 0000000..05a2b4e
--- /dev/null
+++ b/tools/devname2tmpfile.c
@@ -0,0 +1,126 @@
+/*
+ * kmod-devname2tmpfile - write devnames of current kernel in tmpfiles.d format
+ *
+ * Copyright (C) 2004-2012 Kay Sievers <[email protected]>
+ * Copyright (C) 2011-2013  ProFUSION embedded systems
+ * Copyright (C) 2013 Tom Gundersen <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "libkmod.h"
+
+#include "kmod.h"
+
+static int do_devname2tmpfile(int argc, char *argv[])
+{
+        struct kmod_ctx *ctx;
+        struct utsname kernel;
+        const char *null_config = NULL;
+        char modules[PATH_MAX];
+        char buf[4096];
+        FILE *f, *out;
+
+	if (argc != 1) {
+		fprintf(stderr, "Usage: %s\n", argv[0]);
+		return EXIT_FAILURE;
+	}
+
+	ctx = kmod_new(NULL, &null_config);
+	if (ctx == NULL) {
+		fputs("Error: kmod_new() failed!\n", stderr);
+		return EXIT_FAILURE;
+	}
+
+        if (uname(&kernel) < 0) {
+                fputs("Error: uname failed!\n", stderr);
+                return EXIT_FAILURE;
+        }
+        snprintf(modules, sizeof(modules), "/lib/modules/%s/modules.devname", kernel.release);
+        f = fopen(modules, "re");
+        if (f == NULL) {
+		fprintf(stderr, "Error: could not open %s/modules.devname!\n", kernel.release);
+                return EXIT_FAILURE;
+        }
+
+        if (mkdir("/run/tmpfiles.d/", 755) != 0 && errno != EEXIST) {
+		fputs("Error: /run/tmpfiles.d does not exist and could not be created!\n", stderr);
+                return EXIT_FAILURE;
+        }
+
+        out = fopen("/run/tmpfiles.d/kmod.conf", "we");
+        if (out == NULL) {
+		fputs("Error: could not create /run/tmpfiles.d/kmod.conf!\n", stderr);
+                return EXIT_FAILURE;
+        }
+
+        while (fgets(buf, sizeof(buf), f) != NULL) {
+                char *s;
+                const char *modname;
+                const char *devname;
+                const char *devno;
+                int maj, min;
+                char type;
+
+                if (buf[0] == '#')
+                        continue;
+
+                modname = buf;
+                s = strchr(modname, ' ');
+                if (s == NULL)
+                        continue;
+                s[0] = '\0';
+
+                devname = &s[1];
+                s = strchr(devname, ' ');
+                if (s == NULL)
+                        continue;
+                s[0] = '\0';
+
+                devno = &s[1];
+                s = strchr(devno, ' ');
+                if (s == NULL)
+                        s = strchr(devno, '\n');
+                if (s != NULL)
+                        s[0] = '\0';
+                if (sscanf(devno, "%c%u:%u", &type, &maj, &min) != 3)
+                        continue;
+
+                if (type != 'c' && type != 'b')
+                    continue;
+
+                fprintf(out, "%c /dev/%s 0600 - - - %u:%u\n", type, devname, maj, min);
+        }
+
+        fclose(f);
+	kmod_unref(ctx);
+
+        return EXIT_SUCCESS;
+}
+
+const struct kmod_cmd kmod_cmd_devname2tmpfile = {
+	.name = "devname2tmpfile",
+	.cmd = do_devname2tmpfile,
+	.help = "write devnames of current kernel in tmpfiles.d format",
+};
diff --git a/tools/kmod.c b/tools/kmod.c
index ebb8875..ff6518c 100644
--- a/tools/kmod.c
+++ b/tools/kmod.c
@@ -37,6 +37,7 @@ static const struct kmod_cmd kmod_cmd_help;
 static const struct kmod_cmd *kmod_cmds[] = {
 	&kmod_cmd_help,
 	&kmod_cmd_list,
+	&kmod_cmd_devname2tmpfile,
 };
 
 static const struct kmod_cmd *kmod_compat_cmds[] = {
diff --git a/tools/kmod.h b/tools/kmod.h
index 80fa4c2..6410ed5 100644
--- a/tools/kmod.h
+++ b/tools/kmod.h
@@ -35,5 +35,6 @@ extern const struct kmod_cmd kmod_cmd_compat_modprobe;
 extern const struct kmod_cmd kmod_cmd_compat_depmod;
 
 extern const struct kmod_cmd kmod_cmd_list;
+extern const struct kmod_cmd kmod_cmd_devname2tmpfile;
 
 #include "log.h"
-- 
1.8.2.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.