From 8e1bd70d4ce6d3881c1df6a6482643a2b3a69bb1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Nov 2010 21:52:26 +0100 Subject: [PATCH] sysctl: implement native sysctl tool to support Debian-style /etc/sysctl.d --- .gitignore | 1 + Makefile.am | 19 ++- TODO | 2 +- src/sysctl.c | 148 ++++++++++++++++++ src/util.c | 3 + units/.gitignore | 1 + ...sctl.service => systemd-sysctl.service.in} | 4 +- 7 files changed, 171 insertions(+), 7 deletions(-) create mode 100644 src/sysctl.c rename units/{sysctl.service => systemd-sysctl.service.in} (87%) diff --git a/.gitignore b/.gitignore index d5c667ab1..1bb184f87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +systemd-sysctl test-strv systemd-ac-power systemd-timestamp diff --git a/Makefile.am b/Makefile.am index a45f333ac..dd475acf7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,7 +119,8 @@ rootlibexec_PROGRAMS = \ systemd-fsck \ systemd-quotacheck \ systemd-timestamp \ - systemd-ac-power + systemd-ac-power \ + systemd-sysctl if HAVE_LIBCRYPTSETUP rootlibexec_PROGRAMS += \ @@ -223,7 +224,6 @@ dist_systemunit_DATA = \ units/var-run.mount \ units/hwclock-load.service \ units/hwclock-save.service \ - units/sysctl.service \ units/remount-rootfs.service \ units/printer.target \ units/bluetooth.target \ @@ -261,6 +261,7 @@ nodist_systemunit_DATA = \ units/systemd-ask-password-wall.service \ units/systemd-ask-password-plymouth.service \ units/systemd-ask-password-console.service \ + units/systemd-sysctl.service \ units/syslog.target \ units/halt.service \ units/poweroff.service \ @@ -306,6 +307,7 @@ EXTRA_DIST = \ units/systemd-ask-password-wall.service.in \ units/systemd-ask-password-plymouth.service.in \ units/systemd-ask-password-console.service.in \ + units/systemd-sysctl.service.in \ units/syslog.target.in \ units/halt.service.in \ units/poweroff.service.in \ @@ -713,6 +715,15 @@ systemd_tmpfiles_CFLAGS = \ systemd_tmpfiles_LDADD = \ libsystemd-basic.la +systemd_sysctl_SOURCES = \ + src/sysctl.c + +systemd_sysctl_CFLAGS = \ + $(AM_CFLAGS) + +systemd_sysctl_LDADD = \ + libsystemd-basic.la + systemd_fsck_SOURCES = \ src/fsck.c \ src/dbus-common.c @@ -1227,7 +1238,7 @@ install-data-hook: systemd-modules-load.service \ systemd-random-seed-load.service \ systemd-tmpfiles-setup.service \ - sysctl.service \ + systemd-sysctl.service \ systemd-ask-password-console.path && \ $(LN_S) ../dev-hugepages.automount dev-hugepages.automount && \ $(LN_S) ../dev-mqueue.automount dev-mqueue.automount && \ @@ -1238,7 +1249,7 @@ install-data-hook: $(LN_S) ../systemd-modules-load.service systemd-modules-load.service && \ $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service && \ $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ - $(LN_S) ../sysctl.service sysctl.service && \ + $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \ $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path ) ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \ rm -f systemd-tmpfiles-clean.timer && \ diff --git a/TODO b/TODO index 17e12de1b..73d6c36a3 100644 --- a/TODO +++ b/TODO @@ -75,7 +75,7 @@ * isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target -* add to cpu cgroup by default +* read description string from device in crypttsetup External: diff --git a/src/sysctl.c b/src/sysctl.c new file mode 100644 index 000000000..c57210e28 --- /dev/null +++ b/src/sysctl.c @@ -0,0 +1,148 @@ +/*-*- 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" + +#define PROC_SYS_PREFIX "/proc/sys/" + +static int exit_code = 0; + +static void apply_sysctl(const char *property, const char *value) { + char *p, *n; + int r; + + log_debug("Setting '%s' to '%s'", property, value); + + if (!(p = new(char, sizeof(PROC_SYS_PREFIX) + strlen(property)))) { + log_error("Out of memory"); + exit_code = -ENOMEM; + } + + n = stpcpy(p, PROC_SYS_PREFIX); + strcpy(n, property); + + for (; *n; n++) + if (*n == '.') + *n = '/'; + + if ((r = write_one_line_file(p, value)) < 0) { + log_warning("Failed to write '%s' to '%s': %s", value, p, strerror(-r)); + exit_code = r; + } + + free(p); +} + +static void apply_file(const char *path) { + FILE *f; + + assert(path); + + if (!(f = fopen(path, "re"))) { + log_error("Failed to open file '%s', ignoring: %m", path); + exit_code = -errno; + return; + } + + while (!feof(f)) { + char l[LINE_MAX], *p, *value; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + exit_code = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if (!(value = strchr(p, '='))) { + log_error("Line is not an assignment in file '%s': %s", path, value); + exit_code = -EINVAL; + continue; + } + + *value = 0; + value++; + + apply_sysctl(strstrip(p), strstrip(value)); + } + +finish: + fclose(f); +} + +static int nftw_cb( + const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) { + + if (tflag != FTW_F) + return 0; + + if (ignore_file(fpath + ftwbuf->base)) + return 0; + + if (!endswith(fpath, ".conf")) + return 0; + + apply_file(fpath); + return 0; +}; + +int main(int argc, char *argv[]) { + + if (argc > 2) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc > 1) + nftw(argv[1], nftw_cb, 64, FTW_MOUNT|FTW_PHYS); + else { + nftw("/etc/sysctl.conf", nftw_cb, 64, FTW_MOUNT|FTW_PHYS); + nftw("/etc/sysctl.d", nftw_cb, 64, FTW_MOUNT|FTW_PHYS); + } + + return exit_code < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/util.c b/src/util.c index 861f9eaa4..0cd78f656 100644 --- a/src/util.c +++ b/src/util.c @@ -495,6 +495,9 @@ int write_one_line_file(const char *fn, const char *line) { goto finish; } + if (!endswith(line, "\n")) + fputc('\n', f); + r = 0; finish: fclose(f); diff --git a/units/.gitignore b/units/.gitignore index 419838b67..008446d4b 100644 --- a/units/.gitignore +++ b/units/.gitignore @@ -1,3 +1,4 @@ +systemd-sysctl.service systemd-ask-password-console.service rescue.service systemd-ask-password-plymouth.service diff --git a/units/sysctl.service b/units/systemd-sysctl.service.in similarity index 87% rename from units/sysctl.service rename to units/systemd-sysctl.service.in index ba5626a3a..af3ba88e2 100644 --- a/units/sysctl.service +++ b/units/systemd-sysctl.service.in @@ -12,9 +12,9 @@ Conflicts=shutdown.target After=systemd-readahead-collect.service systemd-readahead-replay.service Before=basic.target shutdown.target ConditionPathExists=/etc/sysctl.conf +ConditionDirectoryNotEmpty=/etc/sysctl.d [Service] Type=oneshot RemainAfterExit=yes -ExecStart=/sbin/sysctl -e -q -p /etc/sysctl.conf -StandardOutput=syslog +ExecStart=@rootlibexecdir@/systemd-sysctl -- 2.30.2