1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
35 #define PROC_SYS_PREFIX "/proc/sys/"
37 static char **arg_prefixes
= NULL
;
39 static int apply_sysctl(const char *property
, const char *value
) {
43 log_debug("Setting '%s' to '%s'", property
, value
);
45 p
= new(char, sizeof(PROC_SYS_PREFIX
) + strlen(property
));
47 log_error("Out of memory");
51 n
= stpcpy(p
, PROC_SYS_PREFIX
);
58 if (!strv_isempty(arg_prefixes
)) {
62 STRV_FOREACH(i
, arg_prefixes
)
63 if (path_startswith(p
, *i
)) {
69 log_debug("Skipping %s", p
);
75 k
= write_one_line_file(p
, value
);
78 log_full(k
== -ENOENT
? LOG_DEBUG
: LOG_WARNING
,
79 "Failed to write '%s' to '%s': %s", value
, p
, strerror(-k
));
81 if (k
!= -ENOENT
&& r
== 0)
90 static int apply_file(const char *path
, bool ignore_enoent
) {
96 if (!(f
= fopen(path
, "re"))) {
97 if (ignore_enoent
&& errno
== ENOENT
)
100 log_error("Failed to open file '%s', ignoring: %m", path
);
104 log_debug("apply: %s\n", path
);
106 char l
[LINE_MAX
], *p
, *value
;
109 if (!fgets(l
, sizeof(l
), f
)) {
113 log_error("Failed to read file '%s', ignoring: %m", path
);
123 if (strchr(COMMENTS
, *p
))
126 if (!(value
= strchr(p
, '='))) {
127 log_error("Line is not an assignment in file '%s': %s", path
, value
);
137 if ((k
= apply_sysctl(strstrip(p
), strstrip(value
))) < 0 && r
== 0)
147 static int help(void) {
149 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
150 "Applies kernel sysctl settings.\n\n"
151 " -h --help Show this help\n"
152 " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n",
153 program_invocation_short_name
);
158 static int parse_argv(int argc
, char *argv
[]) {
164 static const struct option options
[] = {
165 { "help", no_argument
, NULL
, 'h' },
166 { "prefix", required_argument
, NULL
, ARG_PREFIX
},
175 while ((c
= getopt_long(argc
, argv
, "h", options
, NULL
)) >= 0) {
187 for (p
= optarg
; *p
; p
++)
191 l
= strv_append(arg_prefixes
, optarg
);
193 log_error("Out of memory");
197 strv_free(arg_prefixes
);
207 log_error("Unknown option code %c", c
);
215 int main(int argc
, char *argv
[]) {
218 r
= parse_argv(argc
, argv
);
220 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;
222 if (argc
-optind
> 1) {
223 log_error("This program expects one or no arguments.");
227 log_set_target(LOG_TARGET_AUTO
);
228 log_parse_environment();
234 r
= apply_file(argv
[optind
], false);
238 r
= conf_files_list(&files
, ".conf",
241 "/usr/local/lib/sysctl.d",
246 log_error("Failed to enumerate sysctl.d files: %s", strerror(-r
));
250 STRV_FOREACH(f
, files
) {
253 k
= apply_file(*f
, true);
258 apply_file("/etc/sysctl.conf", true);
263 strv_free(arg_prefixes
);
265 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;