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: <linux-hotplug@xxxxxxxxxxxxxxx> Cc: <systemd-devel@xxxxxxxxxxxxxxxxxxxxx> --- 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 <kay@xxxxxxxx> + * Copyright (C) 2011-2013 ProFUSION embedded systems + * Copyright (C) 2013 Tom Gundersen <teg@xxxxxxx> + * + * 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 -- To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html