sysctl.d, binfmt.d, modules-load.d: switch to stacked config dirs in /lib, /etc, /run

This commit is contained in:
Kay Sievers
2011-04-25 20:41:47 +02:00
parent 3a90ae0482
commit db1413d738
11 changed files with 222 additions and 169 deletions
+23 -55
View File
@@ -25,8 +25,11 @@
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <stdarg.h>
#include "log.h"
#include "hashmap.h"
#include "strv.h"
#include "util.h"
static int delete_rule(const char *rule) {
@@ -80,6 +83,7 @@ static int apply_file(const char *path, bool ignore_enoent) {
return -errno;
}
log_debug("apply: %s\n", path);
while (!feof(f)) {
char l[LINE_MAX], *p;
int k;
@@ -111,57 +115,6 @@ finish:
return r;
}
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 &&
d->d_type != DT_UNKNOWN)
return 0;
return endswith(d->d_name, ".conf");
}
static int apply_tree(const char *path) {
struct dirent **de = NULL;
int n, i, r = 0;
if ((n = scandir(path, &de, scandir_filter, alphasort)) < 0) {
if (errno == ENOENT)
return 0;
log_error("Failed to enumerate %s files: %m", path);
return -errno;
}
for (i = 0; i < n; i++) {
char *fn;
int k;
k = asprintf(&fn, "%s/%s", path, de[i]->d_name);
free(de[i]);
if (k < 0) {
log_error("Failed to allocate file name.");
if (r == 0)
r = -ENOMEM;
continue;
}
if ((k = apply_file(fn, true)) < 0 && r == 0)
r = k;
}
free(de);
return r;
}
int main(int argc, char *argv[]) {
int r = 0;
@@ -174,14 +127,29 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
if (argc > 1)
if (argc > 1) {
r = apply_file(argv[1], false);
else {
} else {
char **files, **f;
/* Flush out all rules */
write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1");
r = apply_tree("/etc/binfmt.d");
}
files = conf_files_list(".conf",
"/run/binfmt.d",
"/etc/binfmt.d",
"/usr/lib/binfmt.d",
NULL);
STRV_FOREACH(f, files) {
int k;
k = apply_file(*f, true);
if (k < 0 && r == 0)
r = k;
}
strv_free(files);
}
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
+18
View File
@@ -592,3 +592,21 @@ Hashmap *hashmap_copy(Hashmap *h) {
return copy;
}
char **hashmap_get_strv(Hashmap *h) {
char **sv;
Iterator it;
char *path;
int n;
sv = malloc((h->n_entries+1) * sizeof(char *));
if (sv == NULL)
return NULL;
n = 0;
HASHMAP_FOREACH(path, h, it)
sv[n++] = path;
sv[n] = NULL;
return sv;
}
+2
View File
@@ -76,6 +76,8 @@ void *hashmap_steal_first_key(Hashmap *h);
void* hashmap_first(Hashmap *h);
void* hashmap_last(Hashmap *h);
char **hashmap_get_strv(Hashmap *h);
#define HASHMAP_FOREACH(e, h, i) \
for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); (e); (e) = hashmap_iterate((h), &(i), NULL))
+15 -50
View File
@@ -31,30 +31,11 @@
#include "util.h"
#include "strv.h"
/* This reads all module names listed in /etc/modules-load.d/?*.conf 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 &&
d->d_type != DT_UNKNOWN)
return 0;
return endswith(d->d_name, ".conf");
}
int main(int argc, char *argv[]) {
struct dirent **de = NULL;
int r = EXIT_FAILURE, n, i;
int r = EXIT_FAILURE;
char **arguments = NULL;
unsigned n_arguments = 0, n_allocated = 0;
char **files, **fn;
if (argc > 1) {
log_error("This program takes no argument.");
@@ -72,48 +53,33 @@ int main(int argc, char *argv[]) {
n_arguments = n_allocated = 3;
if ((n = scandir("/etc/modules-load.d/", &de, scandir_filter, alphasort)) < 0) {
if (errno == ENOENT)
r = EXIT_SUCCESS;
else
log_error("Failed to enumerate /etc/modules-load.d/ files: %m");
files = conf_files_list(".conf",
"/run/modules-load.d",
"/etc/modules-load.d",
"/usr/lib/modules-load.d",
NULL);
if (files == NULL) {
log_error("Failed to enumerate modules-load.d files: %m");
goto finish;
}
r = EXIT_SUCCESS;
for (i = 0; i < n; i++) {
int k;
char *fn;
STRV_FOREACH(fn, files) {
FILE *f;
k = asprintf(&fn, "/etc/modules-load.d/%s", de[i]->d_name);
free(de[i]);
if (k < 0) {
log_error("Failed to allocate file name.");
r = EXIT_FAILURE;
continue;
}
f = fopen(fn, "re");
f = fopen(*fn, "re");
if (!f) {
if (errno == ENOENT) {
free(fn);
if (errno == ENOENT)
continue;
}
log_error("Failed to open %s: %m", fn);
log_error("Failed to open %s: %m", *fn);
free(fn);
r = EXIT_FAILURE;
continue;
}
free(fn);
log_debug("apply: %s\n", *fn);
for (;;) {
char line[LINE_MAX], *l, *t;
@@ -157,8 +123,7 @@ int main(int argc, char *argv[]) {
fclose(f);
}
free(de);
strv_free(files);
finish:
if (n_arguments > 3) {
+18 -54
View File
@@ -27,6 +27,7 @@
#include <limits.h>
#include "log.h"
#include "strv.h"
#include "util.h"
#define PROC_SYS_PREFIX "/proc/sys/"
@@ -77,6 +78,7 @@ static int apply_file(const char *path, bool ignore_enoent) {
return -errno;
}
log_debug("apply: %s\n", path);
while (!feof(f)) {
char l[LINE_MAX], *p, *value;
int k;
@@ -119,57 +121,6 @@ finish:
return r;
}
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 &&
d->d_type != DT_UNKNOWN)
return 0;
return endswith(d->d_name, ".conf");
}
static int apply_tree(const char *path) {
struct dirent **de = NULL;
int n, i, r = 0;
if ((n = scandir(path, &de, scandir_filter, alphasort)) < 0) {
if (errno == ENOENT)
return 0;
log_error("Failed to enumerate %s files: %m", path);
return -errno;
}
for (i = 0; i < n; i++) {
char *fn;
int k;
k = asprintf(&fn, "%s/%s", path, de[i]->d_name);
free(de[i]);
if (k < 0) {
log_error("Failed to allocate file name.");
if (r == 0)
r = -ENOMEM;
continue;
}
if ((k = apply_file(fn, true)) < 0 && r == 0)
r = k;
}
free(de);
return r;
}
int main(int argc, char *argv[]) {
int r = 0;
@@ -185,12 +136,25 @@ int main(int argc, char *argv[]) {
if (argc > 1)
r = apply_file(argv[1], false);
else {
int k;
char **files, **f;
r = apply_file("/etc/sysctl.conf", true);
if ((k = apply_tree("/etc/sysctl.d")) < 0 && r == 0)
r = k;
files = conf_files_list(".conf",
"/run/sysctl.d",
"/etc/sysctl.d",
"/usr/lib/sysctl.d",
NULL);
STRV_FOREACH(f, files) {
int k;
k = apply_file(*f, true);
if (k < 0 && r == 0)
r = k;
}
strv_free(files);
}
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+94
View File
@@ -4528,3 +4528,97 @@ static const char *const signal_table[] = {
};
DEFINE_STRING_TABLE_LOOKUP(signal, int);
static int file_is_conf(const struct dirent *d, const char *suffix) {
assert(d);
if (ignore_file(d->d_name))
return 0;
if (d->d_type != DT_REG &&
d->d_type != DT_LNK &&
d->d_type != DT_UNKNOWN)
return 0;
return endswith(d->d_name, suffix);
}
static int files_add(Hashmap *h, const char *path, const char *suffix) {
DIR *dir;
struct dirent *de;
int r = 0;
dir = opendir(path);
if (!dir) {
if (errno == ENOENT)
return 0;
return -errno;
}
for (de = readdir(dir); de; de = readdir(dir)) {
char *f;
const char *base;
if (!file_is_conf(de, suffix))
continue;
if (asprintf(&f, "%s/%s", path, de->d_name) < 0) {
r = -ENOMEM;
goto finish;
}
log_debug("found: %s\n", f);
base = f + strlen(path) + 1;
if (hashmap_put(h, base, f) <= 0)
free(f);
}
finish:
closedir(dir);
return r;
}
static int base_cmp(const void *a, const void *b) {
const char *s1, *s2;
s1 = *(char * const *)a;
s2 = *(char * const *)b;
return strcmp(file_name_from_path(s1), file_name_from_path(s2));
}
char **conf_files_list(const char *suffix, const char *dir, ...) {
Hashmap *fh;
char **files = NULL;
va_list ap;
int e = 0;
fh = hashmap_new(string_hash_func, string_compare_func);
if (!fh) {
e = ENOMEM;
goto finish;
}
va_start(ap, dir);
while (dir) {
if (files_add(fh, dir, suffix) < 0) {
log_error("Failed to search for files.");
e = EINVAL;
goto finish;
}
dir = va_arg(ap, const char *);
}
va_end(ap);
files = hashmap_get_strv(fh);
if (files == NULL) {
log_error("Failed to compose list of files.");
e = ENOMEM;
goto finish;
}
qsort(files, hashmap_size(fh), sizeof(char *), base_cmp);
finish:
hashmap_free(fh);
errno = e;
return files;
}
+1
View File
@@ -441,4 +441,5 @@ int signal_from_string(const char *s);
int signal_from_string_try_harder(const char *s);
char **conf_files_list(const char *suffix, const char *dir, ...);
#endif