summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2013-06-14 22:56:39 +0200
committerTom Gundersen <teg@jklm.no>2013-07-08 21:26:24 +0200
commitedeb68c53f1cdc452016b4c8512586a70b1262e3 (patch)
tree66e5e1f5048756b501d5642dc1eb57c8745bd1a8
parentfec79699da51a0815ff01e14abcc94b1f6d3926a (diff)
static-nodes: move creation of static nodes from udevd to tmpfiles
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)
-rw-r--r--Makefile.am11
-rw-r--r--TODO4
-rw-r--r--configure.ac4
-rw-r--r--src/udev/udevd.c72
-rw-r--r--units/.gitignore1
-rw-r--r--units/kmod-static-nodes.service.in16
-rw-r--r--units/systemd-tmpfiles-setup-dev.service.in2
-rw-r--r--units/systemd-udevd.service.in4
8 files changed, 33 insertions, 81 deletions
diff --git a/Makefile.am b/Makefile.am
index 290ec1eb60..aa7e830222 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 d428fda5f7..0498809ea0 100644
--- 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
diff --git a/configure.ac b/configure.ac
index 6fd5307c7f..be867079c2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 7d13b4f532..c4127cd03b 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -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) {
diff --git a/units/.gitignore b/units/.gitignore
index 0bcbb00951..9aee00f2a4 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -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
index 0000000000..f8a2d474ef
--- /dev/null
+++ b/units/kmod-static-nodes.service.in
@@ -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
diff --git a/units/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in
index f029285bc0..8073b1229d 100644
--- a/units/systemd-tmpfiles-setup-dev.service.in
+++ b/units/systemd-tmpfiles-setup-dev.service.in
@@ -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]
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index ddef423625..99f51304e4 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -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