mirror of
https://github.com/systemd/systemd.git
synced 2025-01-25 10:04:04 +03:00
Merge pull request #8199 from keszybz/small-things
Sundry small cleanups
This commit is contained in:
commit
30663b6c25
@ -554,6 +554,17 @@ int tmp_dir(const char **ret) {
|
||||
return tmp_dir_internal("/tmp", ret);
|
||||
}
|
||||
|
||||
int unlink_or_warn(const char *filename) {
|
||||
if (unlink(filename) < 0 && errno != ENOENT)
|
||||
/* If the file doesn't exist and the fs simply was read-only (in which
|
||||
* case unlink() returns EROFS even if the file doesn't exist), don't
|
||||
* complain */
|
||||
if (errno != EROFS || access(filename, F_OK) >= 0)
|
||||
return log_error_errno(errno, "Failed to remove \"%s\": %m", filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
|
||||
char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
|
||||
int r;
|
||||
|
@ -64,6 +64,8 @@ int get_files_in_directory(const char *path, char ***list);
|
||||
int tmp_dir(const char **ret);
|
||||
int var_tmp_dir(const char **ret);
|
||||
|
||||
int unlink_or_warn(const char *filename);
|
||||
|
||||
#define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
|
||||
|
||||
#define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
|
||||
|
@ -179,6 +179,7 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i
|
||||
}
|
||||
|
||||
char ***strv_free_free(char ***l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free);
|
||||
|
||||
char **strv_skip(char **l, size_t n);
|
||||
|
||||
|
@ -387,8 +387,8 @@ int acquire_terminal(
|
||||
*
|
||||
* Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
|
||||
* whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
|
||||
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
|
||||
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
|
||||
* *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure to
|
||||
* not configure any service on the same tty as an untrusted user this should not be a problem. (Which they
|
||||
* probably should not do anyway.) */
|
||||
|
||||
if ((flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_WAIT) {
|
||||
@ -731,7 +731,7 @@ int get_kernel_consoles(char ***ret) {
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* If we /sys is mounted read-only this means we are running in some kind of container environment. In that
|
||||
/* If /sys is mounted read-only this means we are running in some kind of container environment. In that
|
||||
* case /sys would reflect the host system, not us, hence ignore the data we can read from it. */
|
||||
if (path_is_read_only_fs("/sys") > 0)
|
||||
goto fallback;
|
||||
@ -1242,7 +1242,7 @@ bool terminal_is_dumb(void) {
|
||||
bool colors_enabled(void) {
|
||||
|
||||
/* Returns true if colors are considered supported on our stdout. For that we check $SYSTEMD_COLORS first
|
||||
* (which is the explicit way to turn off/on colors). If that didn't work we turn off colors unless we are on a
|
||||
* (which is the explicit way to turn colors on/off). If that didn't work we turn colors off unless we are on a
|
||||
* TTY. And if we are on a TTY we turn it off if $TERM is set to "dumb". There's one special tweak though: if
|
||||
* we are PID 1 then we do not check whether we are connected to a TTY, because we don't keep /dev/console open
|
||||
* continously due to fear of SAK, and hence things are a bit weird. */
|
||||
@ -1270,8 +1270,8 @@ bool dev_console_colors_enabled(void) {
|
||||
/* Returns true if we assume that color is supported on /dev/console.
|
||||
*
|
||||
* For that we first check if we explicitly got told to use colors or not, by checking $SYSTEMD_COLORS. If that
|
||||
* didn't tell us anything we check whether PID 1 has $TERM set, and if not whether $TERM is set on the kernel
|
||||
* command line. If we find $TERM set we assume color if it's not set to "dumb", similar to regular
|
||||
* isn't set we check whether PID 1 has $TERM set, and if not, whether TERM is set on the kernel command
|
||||
* line. If we find $TERM set we assume color if it's not set to "dumb", similarly to how regular
|
||||
* colors_enabled() operates. */
|
||||
|
||||
b = getenv_bool("SYSTEMD_COLORS");
|
||||
|
133
src/core/main.c
133
src/core/main.c
@ -652,107 +652,6 @@ static int config_parse_crash_chvt(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_parse_join_controllers(const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
const char *whole_rvalue = rvalue;
|
||||
unsigned n = 0;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
|
||||
arg_join_controllers = strv_free_free(arg_join_controllers);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char **l;
|
||||
int r;
|
||||
|
||||
r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
|
||||
return r;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
l = strv_split(word, ",");
|
||||
if (!l)
|
||||
return log_oom();
|
||||
strv_uniq(l);
|
||||
|
||||
if (strv_length(l) <= 1) {
|
||||
strv_free(l);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!arg_join_controllers) {
|
||||
arg_join_controllers = new(char**, 2);
|
||||
if (!arg_join_controllers) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
arg_join_controllers[0] = l;
|
||||
arg_join_controllers[1] = NULL;
|
||||
|
||||
n = 1;
|
||||
} else {
|
||||
char ***a;
|
||||
char ***t;
|
||||
|
||||
t = new0(char**, n+2);
|
||||
if (!t) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
for (a = arg_join_controllers; *a; a++) {
|
||||
|
||||
if (strv_overlap(*a, l)) {
|
||||
if (strv_extend_strv(&l, *a, false) < 0) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else {
|
||||
char **c;
|
||||
|
||||
c = strv_copy(*a);
|
||||
if (!c) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
t[n++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
t[n++] = strv_uniq(l);
|
||||
|
||||
strv_free_free(arg_join_controllers);
|
||||
arg_join_controllers = t;
|
||||
}
|
||||
}
|
||||
if (!isempty(rvalue))
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_config_file(void) {
|
||||
|
||||
const ConfigTableItem items[] = {
|
||||
@ -1314,32 +1213,6 @@ static void test_usr(void) {
|
||||
"Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
|
||||
}
|
||||
|
||||
static int initialize_join_controllers(void) {
|
||||
/* By default, mount "cpu" + "cpuacct" together, and "net_cls"
|
||||
* + "net_prio". We'd like to add "cpuset" to the mix, but
|
||||
* "cpuset" doesn't really work for groups with no initialized
|
||||
* attributes. */
|
||||
|
||||
arg_join_controllers = new(char**, 3);
|
||||
if (!arg_join_controllers)
|
||||
return -ENOMEM;
|
||||
|
||||
arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
|
||||
if (!arg_join_controllers[0])
|
||||
goto oom;
|
||||
|
||||
arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
|
||||
if (!arg_join_controllers[1])
|
||||
goto oom;
|
||||
|
||||
arg_join_controllers[2] = NULL;
|
||||
return 0;
|
||||
|
||||
oom:
|
||||
arg_join_controllers = strv_free_free(arg_join_controllers);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int enforce_syscall_archs(Set *archs) {
|
||||
#if HAVE_SECCOMP
|
||||
int r;
|
||||
@ -2094,12 +1967,6 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess
|
||||
|
||||
assert(ret_error_message);
|
||||
|
||||
r = initialize_join_controllers();
|
||||
if (r < 0) {
|
||||
*ret_error_message = "Failed to initialize cgroup controller joining table";
|
||||
return r;
|
||||
}
|
||||
|
||||
arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
|
||||
|
||||
r = parse_config_file();
|
||||
|
@ -2725,7 +2725,6 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
|
||||
}
|
||||
|
||||
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0) {
|
||||
|
||||
if (!IN_SET(errno, EPIPE, EAGAIN, ENOENT, ECONNREFUSED, ECONNRESET, ECONNABORTED))
|
||||
log_error_errno(errno, "connect() failed: %m");
|
||||
return;
|
||||
|
@ -253,6 +253,19 @@ int mount_cgroup_controllers(char ***join_controllers) {
|
||||
|
||||
/* Mount all available cgroup controllers that are built into the kernel. */
|
||||
|
||||
if (!join_controllers)
|
||||
/* The defaults:
|
||||
* mount "cpu" + "cpuacct" together, and "net_cls" + "net_prio".
|
||||
*
|
||||
* We'd like to add "cpuset" to the mix, but "cpuset" doesn't really
|
||||
* work for groups with no initialized attributes.
|
||||
*/
|
||||
join_controllers = (char**[]) {
|
||||
STRV_MAKE("cpu", "cpuacct"),
|
||||
STRV_MAKE("net_cls", "net_prio"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
r = cg_kernel_controllers(&controllers);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to enumerate cgroup controllers: %m");
|
||||
@ -271,10 +284,9 @@ int mount_cgroup_controllers(char ***join_controllers) {
|
||||
if (!controller)
|
||||
break;
|
||||
|
||||
if (join_controllers)
|
||||
for (k = join_controllers; *k; k++)
|
||||
if (strv_find(*k, controller))
|
||||
break;
|
||||
for (k = join_controllers; *k; k++)
|
||||
if (strv_find(*k, controller))
|
||||
break;
|
||||
|
||||
if (k && *k) {
|
||||
char **i, **j;
|
||||
|
@ -2458,7 +2458,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
|
||||
}
|
||||
}
|
||||
|
||||
/* Some names are special */
|
||||
if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
|
||||
|
||||
if (u->type == UNIT_SERVICE &&
|
||||
|
@ -778,7 +778,9 @@ int server_restore_streams(Server *s, FDSet *fds) {
|
||||
if (!found) {
|
||||
/* No file descriptor? Then let's delete the state file */
|
||||
log_debug("Cannot restore stream file %s", de->d_name);
|
||||
unlinkat(dirfd(d), de->d_name, 0);
|
||||
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
|
||||
log_warning("Failed to remove /run/systemd/journal/streams/%s: %m",
|
||||
de->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2010,7 +2010,7 @@ static void reset_scheduled_shutdown(Manager *m) {
|
||||
m->shutdown_dry_run = false;
|
||||
|
||||
if (m->unlink_nologin) {
|
||||
(void) unlink("/run/nologin");
|
||||
(void) unlink_or_warn("/run/nologin");
|
||||
m->unlink_nologin = false;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "logind.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-util.h"
|
||||
@ -183,7 +184,7 @@ static void manager_free(Manager *m) {
|
||||
udev_unref(m->udev);
|
||||
|
||||
if (m->unlink_nologin)
|
||||
(void) unlink("/run/nologin");
|
||||
(void) unlink_or_warn("/run/nologin");
|
||||
|
||||
bus_verify_polkit_async_registry_free(m->polkit_registry);
|
||||
|
||||
@ -322,7 +323,9 @@ static int manager_enumerate_seats(Manager *m) {
|
||||
|
||||
s = hashmap_get(m->seats, de->d_name);
|
||||
if (!s) {
|
||||
unlinkat(dirfd(d), de->d_name, 0);
|
||||
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
|
||||
log_warning("Failed to remove /run/systemd/seats/%s: %m",
|
||||
de->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ static void backspace_string(int ttyfd, const char *str) {
|
||||
if (ttyfd < 0)
|
||||
return;
|
||||
|
||||
/* Backspaces back for enough characters to entirely undo printing of the specified string. */
|
||||
/* Backspaces through enough characters to entirely undo printing of the specified string. */
|
||||
|
||||
m = utf8_n_codepoints(str);
|
||||
if (m == (size_t) -1)
|
||||
|
@ -1021,3 +1021,119 @@ int config_parse_ip_port(
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_join_controllers(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
char ****ret = data;
|
||||
const char *whole_rvalue = rvalue;
|
||||
unsigned n = 0;
|
||||
_cleanup_(strv_free_freep) char ***controllers = NULL;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(ret);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char **l;
|
||||
int r;
|
||||
|
||||
r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
|
||||
return r;
|
||||
}
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
l = strv_split(word, ",");
|
||||
if (!l)
|
||||
return log_oom();
|
||||
strv_uniq(l);
|
||||
|
||||
if (strv_length(l) <= 1) {
|
||||
strv_free(l);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!controllers) {
|
||||
controllers = new(char**, 2);
|
||||
if (!controllers) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
controllers[0] = l;
|
||||
controllers[1] = NULL;
|
||||
|
||||
n = 1;
|
||||
} else {
|
||||
char ***a;
|
||||
char ***t;
|
||||
|
||||
t = new0(char**, n+2);
|
||||
if (!t) {
|
||||
strv_free(l);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
for (a = controllers; *a; a++)
|
||||
if (strv_overlap(*a, l)) {
|
||||
if (strv_extend_strv(&l, *a, false) < 0) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
} else {
|
||||
char **c;
|
||||
|
||||
c = strv_copy(*a);
|
||||
if (!c) {
|
||||
strv_free(l);
|
||||
strv_free_free(t);
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
t[n++] = c;
|
||||
}
|
||||
|
||||
t[n++] = strv_uniq(l);
|
||||
|
||||
strv_free_free(controllers);
|
||||
controllers = t;
|
||||
}
|
||||
}
|
||||
if (!isempty(rvalue))
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
|
||||
|
||||
/* As a special case, return a single empty strv, to override the default */
|
||||
if (!controllers) {
|
||||
controllers = new(char**, 2);
|
||||
if (!controllers)
|
||||
return log_oom();
|
||||
controllers[0] = strv_new(NULL, NULL);
|
||||
if (!controllers[0])
|
||||
return log_oom();
|
||||
controllers[1] = NULL;
|
||||
}
|
||||
|
||||
strv_free_free(*ret);
|
||||
*ret = controllers;
|
||||
controllers = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -121,44 +121,46 @@ int config_parse_many(
|
||||
void *userdata);
|
||||
|
||||
/* Generic parsers */
|
||||
int config_parse_int(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_unsigned(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_long(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_uint8(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_uint16(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_uint32(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_double(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_iec_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_si_size(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_iec_uint64(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_bool(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_tristate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_signal(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_personality(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_ifname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
int config_parse_ip_port(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
||||
#define GENERIC_PARSER_ARGS \
|
||||
const char *unit, \
|
||||
const char *filename, \
|
||||
unsigned line, \
|
||||
const char *section, \
|
||||
unsigned section_line, \
|
||||
const char *lvalue, \
|
||||
int ltype, \
|
||||
const char *rvalue, \
|
||||
void *data, \
|
||||
void *userdata
|
||||
int config_parse_int(GENERIC_PARSER_ARGS);
|
||||
int config_parse_unsigned(GENERIC_PARSER_ARGS);
|
||||
int config_parse_long(GENERIC_PARSER_ARGS);
|
||||
int config_parse_uint8(GENERIC_PARSER_ARGS);
|
||||
int config_parse_uint16(GENERIC_PARSER_ARGS);
|
||||
int config_parse_uint32(GENERIC_PARSER_ARGS);
|
||||
int config_parse_uint64(GENERIC_PARSER_ARGS);
|
||||
int config_parse_double(GENERIC_PARSER_ARGS);
|
||||
int config_parse_iec_size(GENERIC_PARSER_ARGS);
|
||||
int config_parse_si_size(GENERIC_PARSER_ARGS);
|
||||
int config_parse_iec_uint64(GENERIC_PARSER_ARGS);
|
||||
int config_parse_bool(GENERIC_PARSER_ARGS);
|
||||
int config_parse_tristate(GENERIC_PARSER_ARGS);
|
||||
int config_parse_string(GENERIC_PARSER_ARGS);
|
||||
int config_parse_path(GENERIC_PARSER_ARGS);
|
||||
int config_parse_strv(GENERIC_PARSER_ARGS);
|
||||
int config_parse_sec(GENERIC_PARSER_ARGS);
|
||||
int config_parse_nsec(GENERIC_PARSER_ARGS);
|
||||
int config_parse_mode(GENERIC_PARSER_ARGS);
|
||||
int config_parse_log_facility(GENERIC_PARSER_ARGS);
|
||||
int config_parse_log_level(GENERIC_PARSER_ARGS);
|
||||
int config_parse_signal(GENERIC_PARSER_ARGS);
|
||||
int config_parse_personality(GENERIC_PARSER_ARGS);
|
||||
int config_parse_ifname(GENERIC_PARSER_ARGS);
|
||||
int config_parse_ip_port(GENERIC_PARSER_ARGS);
|
||||
int config_parse_join_controllers(GENERIC_PARSER_ARGS);
|
||||
|
||||
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
|
||||
int function(const char *unit, \
|
||||
const char *filename, \
|
||||
unsigned line, \
|
||||
const char *section, \
|
||||
unsigned section_line, \
|
||||
const char *lvalue, \
|
||||
int ltype, \
|
||||
const char *rvalue, \
|
||||
void *data, \
|
||||
void *userdata) { \
|
||||
\
|
||||
int function(GENERIC_PARSER_ARGS) { \
|
||||
type *i = data, x; \
|
||||
\
|
||||
assert(filename); \
|
||||
@ -177,17 +179,7 @@ int config_parse_ip_port(const char *unit, const char *filename, unsigned line,
|
||||
}
|
||||
|
||||
#define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg) \
|
||||
int function(const char *unit, \
|
||||
const char *filename, \
|
||||
unsigned line, \
|
||||
const char *section, \
|
||||
unsigned section_line, \
|
||||
const char *lvalue, \
|
||||
int ltype, \
|
||||
const char *rvalue, \
|
||||
void *data, \
|
||||
void *userdata) { \
|
||||
\
|
||||
int function(GENERIC_PARSER_ARGS) { \
|
||||
type **enums = data, x, *ys; \
|
||||
_cleanup_free_ type *xs = NULL; \
|
||||
const char *word, *state; \
|
||||
|
@ -226,6 +226,45 @@ static void test_config_parse_iec_uint64(void) {
|
||||
assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
|
||||
}
|
||||
|
||||
static void test_config_parse_join_controllers(void) {
|
||||
int r;
|
||||
_cleanup_(strv_free_freep) char ***c = NULL;
|
||||
char ***c2;
|
||||
|
||||
/* Test normal operation */
|
||||
r = config_parse_join_controllers(NULL, "example.conf", 11, "Section", 10, "JoinControllers", 0, "cpu,cpuacct net_cls,netprio", &c, NULL);
|
||||
assert_se(r == 0);
|
||||
assert_se(c);
|
||||
assert_se(strv_length(c[0]) == 2);
|
||||
assert_se(strv_equal(c[0], STRV_MAKE("cpu", "cpuacct")));
|
||||
assert_se(strv_length(c[1]) == 2);
|
||||
assert_se(strv_equal(c[1], STRV_MAKE("net_cls", "netprio")));
|
||||
assert_se(c[2] == NULL);
|
||||
|
||||
/* Test special case of no mounted controllers */
|
||||
r = config_parse_join_controllers(NULL, "example.conf", 12, "Section", 10, "JoinControllers", 0, "", &c, NULL);
|
||||
assert_se(r == 0);
|
||||
assert_se(c);
|
||||
assert_se(strv_equal(c[0], STRV_MAKE_EMPTY));
|
||||
assert_se(c[1] == NULL);
|
||||
|
||||
/* Test merging of overlapping lists */
|
||||
r = config_parse_join_controllers(NULL, "example.conf", 13, "Section", 10, "JoinControllers", 0, "a,b b,c", &c, NULL);
|
||||
assert_se(r == 0);
|
||||
assert_se(c);
|
||||
assert_se(strv_length(c[0]) == 3);
|
||||
assert_se(strv_contains(c[0], "a"));
|
||||
assert_se(strv_contains(c[0], "b"));
|
||||
assert_se(strv_contains(c[0], "c"));
|
||||
assert_se(c[1] == NULL);
|
||||
|
||||
/* Test ignoring of bad lines */
|
||||
c2 = c;
|
||||
r = config_parse_join_controllers(NULL, "example.conf", 14, "Section", 10, "JoinControllers", 0, "a,\"b ", &c, NULL);
|
||||
assert_se(r < 0);
|
||||
assert_se(c == c2);
|
||||
}
|
||||
|
||||
#define x10(x) x x x x x x x x x x
|
||||
#define x100(x) x10(x10(x))
|
||||
#define x1000(x) x10(x100(x))
|
||||
@ -365,6 +404,7 @@ int main(int argc, char **argv) {
|
||||
test_config_parse_sec();
|
||||
test_config_parse_nsec();
|
||||
test_config_parse_iec_uint64();
|
||||
test_config_parse_join_controllers();
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(config_file); i++)
|
||||
test_config_parse(i, config_file[i]);
|
||||
|
@ -100,7 +100,7 @@ static void test_get_process_comm(pid_t pid) {
|
||||
if (!detect_container())
|
||||
assert_se(get_ctty_devnr(pid, &h) == -ENXIO || pid != 1);
|
||||
|
||||
getenv_for_pid(pid, "PATH", &i);
|
||||
(void) getenv_for_pid(pid, "PATH", &i);
|
||||
log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,15 @@ static void test_utf16_to_utf8(void) {
|
||||
free(a);
|
||||
}
|
||||
|
||||
static void test_utf8_n_codepoints(void) {
|
||||
assert_se(utf8_n_codepoints("abc") == 3);
|
||||
assert_se(utf8_n_codepoints("zażółcić gęślą jaźń") == 19);
|
||||
assert_se(utf8_n_codepoints("串") == 1);
|
||||
assert_se(utf8_n_codepoints("") == 0);
|
||||
assert_se(utf8_n_codepoints("…👊🔪💐…") == 5);
|
||||
assert_se(utf8_n_codepoints("\xF1") == (size_t) -1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_utf8_is_valid();
|
||||
test_utf8_is_printable();
|
||||
@ -114,6 +123,7 @@ int main(int argc, char *argv[]) {
|
||||
test_utf8_escaping();
|
||||
test_utf8_escaping_printable();
|
||||
test_utf16_to_utf8();
|
||||
test_utf8_n_codepoints();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ void udev_watch_restore(struct udev *udev) {
|
||||
udev_watch_begin(udev, dev);
|
||||
udev_device_unref(dev);
|
||||
unlink:
|
||||
unlinkat(dirfd(dir), ent->d_name, 0);
|
||||
(void) unlinkat(dirfd(dir), ent->d_name, 0);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
@ -23,12 +23,14 @@
|
||||
|
||||
#include "fileio.h"
|
||||
#include "fileio-label.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "selinux-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char*argv[]) {
|
||||
int r, k;
|
||||
|
||||
if (argc != 2) {
|
||||
log_error("This program requires one argument.");
|
||||
@ -44,30 +46,12 @@ int main(int argc, char*argv[]) {
|
||||
mac_selinux_init();
|
||||
|
||||
if (streq(argv[1], "start")) {
|
||||
int r = 0;
|
||||
|
||||
if (unlink("/run/nologin") < 0 && errno != ENOENT)
|
||||
r = log_error_errno(errno,
|
||||
"Failed to remove /run/nologin file: %m");
|
||||
|
||||
if (unlink("/etc/nologin") < 0 && errno != ENOENT) {
|
||||
/* If the file doesn't exist and /etc simply
|
||||
* was read-only (in which case unlink()
|
||||
* returns EROFS even if the file doesn't
|
||||
* exist), don't complain */
|
||||
|
||||
if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) {
|
||||
log_error_errno(errno, "Failed to remove /etc/nologin file: %m");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
r = unlink_or_warn("/run/nologin");
|
||||
k = unlink_or_warn("/etc/nologin");
|
||||
if (r < 0 || k < 0)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
} else if (streq(argv[1], "stop")) {
|
||||
int r;
|
||||
|
||||
r = write_string_file_atomic_label("/run/nologin", "System is going down.");
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to create /run/nologin: %m");
|
||||
|
Loading…
x
Reference in New Issue
Block a user