From b2423f1f436f847d9fc96a63679be2b5552b6baf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 19 Aug 2010 02:03:03 +0200 Subject: [PATCH] modules-load: add systemd-modules-load tool that can load a configured list of modules in /etc/modules.d/ on boot, replacing distro-dependent shell hacks for this --- .gitignore | 1 + Makefile.am | 15 ++- fixme | 4 +- src/modules-load.c | 167 ++++++++++++++++++++++++++ units/.gitignore | 1 + units/systemd-modules-load.service.in | 19 +++ 6 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 src/modules-load.c create mode 100644 units/systemd-modules-load.service.in diff --git a/.gitignore b/.gitignore index 7a205054..7e7b6260 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-modules-load systemd-auto-console-getty systemd-shutdownd systemd-random-seed diff --git a/Makefile.am b/Makefile.am index 4905f2da..a2f7e172 100644 --- a/Makefile.am +++ b/Makefile.am @@ -73,7 +73,8 @@ rootlibexec_PROGRAMS = \ systemd-update-utmp \ systemd-random-seed \ systemd-shutdownd \ - systemd-auto-console-getty + systemd-auto-console-getty \ + systemd-modules-load noinst_PROGRAMS = \ test-engine \ @@ -140,7 +141,6 @@ dist_systemunit_DATA = \ units/systemd-initctl.socket \ units/systemd-logger.socket \ units/systemd-shutdownd.socket \ - units/systemd-auto-console-getty.service \ units/dev-hugepages.automount \ units/dev-hugepages.mount \ units/dev-mqueue.automount \ @@ -173,6 +173,7 @@ nodist_systemunit_DATA = \ units/systemd-logger.service \ units/systemd-shutdownd.service \ units/systemd-auto-console-getty.service \ + units/systemd-modules-load.service \ units/systemd-update-utmp-runlevel.service \ units/systemd-update-utmp-shutdown.service \ units/systemd-random-seed-save.service \ @@ -196,6 +197,7 @@ EXTRA_DIST = \ units/systemd-logger.service.in \ units/systemd-shutdownd.service.in \ units/systemd-auto-console-getty.service.in \ + units/systemd-modules-load.service.in \ units/systemd-update-utmp-runlevel.service.in \ units/systemd-update-utmp-shutdown.service.in \ units/systemd-random-seed-save.service.in \ @@ -566,6 +568,15 @@ systemd_auto_console_getty_LDADD = \ libsystemd-basic.la \ $(DBUS_LIBS) +systemd_modules_load_SOURCES = \ + src/modules-load.c + +systemd_modules_load_CFLAGS = \ + $(AM_CFLAGS) + +systemd_modules_load_LDADD = \ + libsystemd-basic.la + systemd_cgroups_agent_SOURCES = \ src/cgroups-agent.c \ src/dbus-common.c diff --git a/fixme b/fixme index b55f6e6d..4cfa1339 100644 --- a/fixme +++ b/fixme @@ -63,12 +63,12 @@ * systemctl: ln -s output muss abschaltbar sein, und warning wenn [Install] leer ist. -* /etc/modules.d/*.modules in systemd-modules-load - * X-Interactive is kaputt * universal fallback for hostname +* bash completion a la gdbus + External: * procps, psmisc, sysvinit-tools, hostname → util-linux-ng diff --git a/src/modules-load.c b/src/modules-load.c new file mode 100644 index 00000000..44ff02e7 --- /dev/null +++ b/src/modules-load.c @@ -0,0 +1,167 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd 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 systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "strv.h" + +/* This reads all module names listed in /etc/modules.d/?*.modules and + * loads them into the kernel. This follows roughly Debian's way to + * handle modules, but uses a directory of fragments instead of a + * single /etc/modules file. */ + +static int scandir_filter(const struct dirent *d) { + assert(d); + + if (ignore_file(d->d_name)) + return 0; + + if (d->d_type != DT_REG && + d->d_type != DT_LNK) + return 0; + + return endswith(d->d_name, ".modules"); +} + +int main(int argc, char *argv[]) { + struct dirent **de = NULL; + int r = 1, n, i; + char **arguments = NULL; + unsigned n_arguments = 0, n_allocated = 0; + + if (argc > 1) { + log_error("This program takes no argument."); + return 1; + } + + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_parse_environment(); + log_open(); + + if (!(arguments = strv_new("/sbin/modprobe", "-sab", "--", NULL))) { + log_error("Failed to allocate string array"); + goto finish; + } + + n_arguments = n_allocated = 3; + + if ((n = scandir("/etc/modules.d/", &de, scandir_filter, alphasort)) < 0) { + + if (errno == ENOENT) + r = 0; + else + log_error("Failed to enumerate /etc/modules.d/ files: %m"); + + goto finish; + } + + r = 0; + + for (i = 0; i < n; i++) { + int k; + char *fn; + FILE *f; + + k = asprintf(&fn, "/etc/modules.d/%s", de[i]->d_name); + free(de[i]); + + if (k < 0) { + log_error("Failed to allocate file name."); + r = 1; + continue; + } + + f = fopen(fn, "re"); + free(fn); + + if (!f) { + log_error("Failed to open %s: %m", fn); + r = 1; + continue; + } + + for (;;) { + char line[LINE_MAX], *l, *t; + + if (!(fgets(line, sizeof(line), f))) + break; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + if (!(t = strdup(l))) { + log_error("Failed to allocate module name."); + continue; + } + + if (n_arguments >= n_allocated) { + char **a; + unsigned m; + + m = MAX(16U, n_arguments*2); + + if (!(a = realloc(arguments, sizeof(char*) * (m+1)))) { + log_error("Failed to increase module array size."); + free(t); + r = 1; + continue; + } + + arguments = a; + n_allocated = m; + } + + arguments[n_arguments++] = t; + } + + if (ferror(f)) { + r = 1; + log_error("Failed to read from file: %m"); + } + + fclose(f); + } + + free(de); + +finish: + + if (n_arguments > 3) { + arguments[n_arguments] = NULL; + execv("/sbin/modprobe", arguments); + + log_error("Failed to execute /sbin/modprobe: %m"); + r = 1; + } + + strv_free(arguments); + + return r; +} diff --git a/units/.gitignore b/units/.gitignore index 2a5e24d3..23857d23 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,3 +1,4 @@ +systemd-modules-load.service systemd-auto-console-getty.service systemd-shutdownd.service systemd-random-seed-load.service diff --git a/units/systemd-modules-load.service.in b/units/systemd-modules-load.service.in new file mode 100644 index 00000000..2390e02b --- /dev/null +++ b/units/systemd-modules-load.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Load Kernel Modules +DefaultDependencies=no +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-modules-load + +[Install] +WantedBy=sysinit.target -- 2.39.5