chiark / gitweb /
static-nodes: move creation of static nodes from udevd to tmpfiles
authorTom Gundersen <teg@jklm.no>
Fri, 14 Jun 2013 20:56:39 +0000 (22:56 +0200)
committerTom Gundersen <teg@jklm.no>
Mon, 8 Jul 2013 19:26:24 +0000 (21:26 +0200)
As of kmod v14, it is possible to export the static node information from
/lib/modules/`uname -r`/modules.devname in tmpfiles.d(5) format.

Use this functionality to let systemd-tmpfilesd create the static device nodes
at boot, and drop the functionality from systemd-udevd.

As an effect of this we can move from systemd-udevd to systemd-tmpfiles-setup-dev:

 * the conditional CAP_MKNOD (replaced by checking if /sys is mounted rw)
 * ordering before local-fs-pre.target (see 89d09e1b5c65a2d97840f682e0932c8bb499f166)

Makefile.am
TODO
configure.ac
src/udev/udevd.c
units/.gitignore
units/kmod-static-nodes.service.in [new file with mode: 0644]
units/systemd-tmpfiles-setup-dev.service.in
units/systemd-udevd.service.in

index 290ec1e..aa7e830 100644 (file)
@@ -1464,10 +1464,18 @@ nodist_systemunit_DATA += \
 SYSINIT_TARGET_WANTS += \
        systemd-modules-load.service
 
+if ENABLE_TMPFILES
+nodist_systemunit_DATA += \
+       units/kmod-static-nodes.service
+
+SYSINIT_TARGET_WANTS += \
+       kmod-static-nodes.service
+endif
 endif
 
 EXTRA_DIST += \
-       units/systemd-modules-load.service.in
+        units/systemd-modules-load.service.in \
+        units/kmod-static-nodes.service.in
 
 # ------------------------------------------------------------------------------
 if ENABLE_TMPFILES
@@ -4137,6 +4145,7 @@ substitutions = \
        '|SUSHELL=$(SUSHELL)|' \
        '|DEBUGTTY=$(DEBUGTTY)|' \
        '|KILL=$(KILL)|' \
+       '|KMOD=$(KMOD)|' \
        '|QUOTAON=$(QUOTAON)|' \
        '|QUOTACHECK=$(QUOTACHECK)|' \
        '|SYSTEM_SYSVINIT_PATH=$(sysvinitdir)|' \
diff --git a/TODO b/TODO
index d428fda..0498809 100644 (file)
--- a/TODO
+++ b/TODO
@@ -186,10 +186,6 @@ Features:
   so that the coredump is properly written to the user's own journal
   file.
 
-* move /usr/lib/modules/$(uname -r)/modules.devname parsing from udevd to
-   kmod static-nodes
-  call kmod as an early service, and drop CAP_MKNOD from udevd.service
-
 * seems that when we follow symlinks to units we prefer the symlink
   destination path over /etc and /usr. We shouldn't do that. Instead
   /etc should always override /run+/usr and also any symlink
index 6fd5307..be86707 100644 (file)
@@ -74,6 +74,8 @@ AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap])
 
 AC_PATH_PROG([KILL], [kill], [/usr/bin/kill])
 
+AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod])
+
 # gtkdocize greps for '^GTK_DOC_CHECK', so it needs to be on its own line
 m4_ifdef([GTK_DOC_CHECK], [
 GTK_DOC_CHECK([1.18],[--flavour no-tmpl])],
@@ -216,7 +218,7 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2])
 have_kmod=no
 AC_ARG_ENABLE(kmod, AS_HELP_STRING([--disable-kmod], [disable loadable modules support]))
 if test "x$enable_kmod" != "xno"; then
-        PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ],
+        PKG_CHECK_MODULES(KMOD, [ libkmod >= 14 ],
                 [AC_DEFINE(HAVE_KMOD, 1, [Define if kmod is available]) have_kmod=yes], have_kmod=no)
         if test "x$have_kmod" = xno -a "x$enable_kmod" = xyes; then
                 AC_MSG_ERROR([*** kmod support requested but libraries not found])
index 7d13b4f..c4127cd 100644 (file)
@@ -812,77 +812,6 @@ static void handle_signal(struct udev *udev, int signo)
         }
 }
 
-static void static_dev_create_from_modules(struct udev *udev)
-{
-        struct utsname kernel;
-        char modules[UTIL_PATH_SIZE];
-        char buf[4096];
-        FILE *f;
-
-        if (uname(&kernel) < 0) {
-                log_error("uname failed: %m");
-                return;
-        }
-
-        strscpyl(modules, sizeof(modules), ROOTPREFIX "/lib/modules/", kernel.release, "/modules.devname", NULL);
-        f = fopen(modules, "re");
-        if (f == NULL)
-                return;
-
-        while (fgets(buf, sizeof(buf), f) != NULL) {
-                char *s;
-                const char *modname;
-                const char *devname;
-                const char *devno;
-                int maj, min;
-                char type;
-                mode_t mode;
-                char filename[UTIL_PATH_SIZE];
-
-                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;
-
-                mode  = 0600;
-                if (type == 'c')
-                        mode |= S_IFCHR;
-                else if (type == 'b')
-                        mode |= S_IFBLK;
-                else
-                        continue;
-
-                strscpyl(filename, sizeof(filename), "/dev/", devname, NULL);
-                mkdir_parents_label(filename, 0755);
-                label_context_set(filename, mode);
-                log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min);
-                if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST)
-                        utimensat(AT_FDCWD, filename, NULL, 0);
-                label_context_clear();
-        }
-
-        fclose(f);
-}
-
 static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
 {
         int ctrl = -1, netlink = -1;
@@ -1067,7 +996,6 @@ int main(int argc, char *argv[])
         mkdir("/run/udev", 0755);
 
         dev_setup(NULL);
-        static_dev_create_from_modules(udev);
 
         /* before opening new files, make sure std{in,out,err} fds are in a sane state */
         if (daemonize) {
index 0bcbb00..9aee00f 100644 (file)
@@ -58,3 +58,4 @@
 /initrd-udevadm-cleanup-db.service
 /systemd-nspawn@.service
 /systemd-machined.service
+/kmod-static-nodes.service
diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in
new file mode 100644 (file)
index 0000000..f8a2d47
--- /dev/null
@@ -0,0 +1,16 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Create list of required static device nodes for the current kernel
+DefaultDependencies=no
+Before=sysinit.target systemd-tmpfiles-setup-dev.service
+
+[Service]
+Type=oneshot
+ExecStartPre=/usr/bin/mkdir -p /run/tmpfiles.d
+ExecStart=@KMOD@ static-nodes --format=tmpfiles --output=/run/tmpfiles.d/kmod.conf
index f029285..8073b12 100644 (file)
@@ -9,7 +9,7 @@
 Description=Create static device nodes in /dev
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Before=sysinit.target systemd-udevd.service
+Before=sysinit.target local-fs-pre.target systemd-udevd.service
 ConditionCapability=CAP_MKNOD
 
 [Service]
index ddef423..99f5130 100644 (file)
@@ -11,8 +11,8 @@ Documentation=man:systemd-udevd.service(8) man:udev(7)
 DefaultDependencies=no
 Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket
 After=systemd-udevd-control.socket systemd-udevd-kernel.socket
-Before=sysinit.target local-fs-pre.target
-ConditionCapability=CAP_MKNOD
+Before=sysinit.target
+ConditionPathIsReadWrite=/sys
 
 [Service]
 Type=notify