1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-08 11:27:32 +03:00

Merge pull request #1417 from poettering/nspawn-and-more

Various fixes, primarily for nspawn, but other stuff too
This commit is contained in:
Daniel Mack 2015-09-30 15:55:26 +02:00
commit 1115d41706
9 changed files with 137 additions and 53 deletions

5
TODO
View File

@ -26,13 +26,8 @@ External:
Features: Features:
* add "requires=" deps on slices from services, not just "wants="
* add a concept of RemainAfterExit= to scope units * add a concept of RemainAfterExit= to scope units
* add sd_booted() check into "systemctl is-system-running", and return
a new state "foreign" or so if we are not running on systemd.
* add journal vacuum by max number of files * add journal vacuum by max number of files
* add a new command "systemctl revert" or so, that removes all dropin * add a new command "systemctl revert" or so, that removes all dropin

View File

@ -168,6 +168,13 @@
<option>--log-level=</option> described in <option>--log-level=</option> described in
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para> <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
<para><command>systemd-analyze set-log-target
<replaceable>TARGET</replaceable></command> changes the current log
target of the <command>systemd</command> daemon to
<replaceable>TARGET</replaceable> (accepts the same values as
<option>--log-target=</option> described in
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
<para><command>systemd-analyze verify</command> will load unit <para><command>systemd-analyze verify</command> will load unit
files and print warnings if any errors are detected. Files files and print warnings if any errors are detected. Files
specified on the command line will be loaded, but also any other specified on the command line will be loaded, but also any other

View File

@ -1217,10 +1217,8 @@ static int dump(sd_bus *bus, char **args) {
&error, &error,
&reply, &reply,
""); "");
if (r < 0) { if (r < 0)
log_error("Failed issue method call: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed issue method call: %s", bus_error_message(&error, r));
return r;
}
r = sd_bus_message_read(reply, "s", &text); r = sd_bus_message_read(reply, "s", &text);
if (r < 0) if (r < 0)
@ -1251,11 +1249,36 @@ static int set_log_level(sd_bus *bus, char **args) {
&error, &error,
"s", "s",
args[0]); args[0]);
if (r < 0) { if (r < 0)
log_error("Failed to issue method call: %s", bus_error_message(&error, -r)); return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
return -EIO;
return 0;
}
static int set_log_target(sd_bus *bus, char **args) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
assert(bus);
assert(args);
if (strv_length(args) != 1) {
log_error("This command expects one argument only.");
return -E2BIG;
} }
r = sd_bus_set_property(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"LogTarget",
&error,
"s",
args[0]);
if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
return 0; return 0;
} }
@ -1285,7 +1308,8 @@ static void help(void) {
" critical-chain Print a tree of the time critical chain of units\n" " critical-chain Print a tree of the time critical chain of units\n"
" plot Output SVG graphic showing service initialization\n" " plot Output SVG graphic showing service initialization\n"
" dot Output dependency graph in dot(1) format\n" " dot Output dependency graph in dot(1) format\n"
" set-log-level LEVEL Set logging threshold for systemd\n" " set-log-level LEVEL Set logging threshold for manager\n"
" set-log-target TARGET Set logging target for manager\n"
" dump Output state serialization of service manager\n" " dump Output state serialization of service manager\n"
" verify FILE... Check unit files for correctness\n" " verify FILE... Check unit files for correctness\n"
, program_invocation_short_name); , program_invocation_short_name);
@ -1452,6 +1476,8 @@ int main(int argc, char *argv[]) {
r = dump(bus, argv+optind+1); r = dump(bus, argv+optind+1);
else if (streq(argv[optind], "set-log-level")) else if (streq(argv[optind], "set-log-level"))
r = set_log_level(bus, argv+optind+1); r = set_log_level(bus, argv+optind+1);
else if (streq(argv[optind], "set-log-target"))
r = set_log_target(bus, argv+optind+1);
else else
log_error("Unknown operation '%s'.", argv[optind]); log_error("Unknown operation '%s'.", argv[optind]);
} }

View File

@ -922,7 +922,7 @@ int log_set_max_level_from_string(const char *e) {
t = log_level_from_string(e); t = log_level_from_string(e);
if (t < 0) if (t < 0)
return t; return -EINVAL;
log_set_max_level(t); log_set_max_level(t);
return 0; return 0;

View File

@ -216,8 +216,55 @@ static int tmpfs_patch_options(
return !!buf; return !!buf;
} }
int mount_sysfs(const char *dest) {
const char *full, *top, *x;
top = prefix_roota(dest, "/sys");
full = prefix_roota(top, "/full");
(void) mkdir(full, 0755);
if (mount("sysfs", full, "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) < 0)
return log_error_errno(errno, "Failed to mount sysfs to %s: %m", full);
FOREACH_STRING(x, "block", "bus", "class", "dev", "devices", "kernel") {
_cleanup_free_ char *from = NULL, *to = NULL;
from = prefix_root(full, x);
if (!from)
return log_oom();
to = prefix_root(top, x);
if (!to)
return log_oom();
(void) mkdir(to, 0755);
if (mount(from, to, NULL, MS_BIND, NULL) < 0)
return log_error_errno(errno, "Failed to mount /sys/%s into place: %m", x);
if (mount(NULL, to, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
return log_error_errno(errno, "Failed to mount /sys/%s read-only: %m", x);
}
if (umount(full) < 0)
return log_error_errno(errno, "Failed to unmount %s: %m", full);
if (rmdir(full) < 0)
return log_error_errno(errno, "Failed to remove %s: %m", full);
x = prefix_roota(top, "/fs/kdbus");
(void) mkdir(x, 0755);
if (mount(NULL, top, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, NULL) < 0)
return log_error_errno(errno, "Failed to make %s read-only: %m", top);
return 0;
}
int mount_all(const char *dest, int mount_all(const char *dest,
bool userns, uid_t uid_shift, uid_t uid_range, bool use_userns, bool in_userns,
uid_t uid_shift, uid_t uid_range,
const char *selinux_apifs_context) { const char *selinux_apifs_context) {
typedef struct MountPoint { typedef struct MountPoint {
@ -234,7 +281,7 @@ int mount_all(const char *dest,
{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true }, { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true },
{ "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true }, /* Bind mount first */ { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true }, /* Bind mount first */
{ NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true, true }, /* Then, make it r/o */ { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true, true }, /* Then, make it r/o */
{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false }, { "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false },
{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false }, { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false },
{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false },
{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false },
@ -252,7 +299,7 @@ int mount_all(const char *dest,
_cleanup_free_ char *where = NULL, *options = NULL; _cleanup_free_ char *where = NULL, *options = NULL;
const char *o; const char *o;
if (userns != mount_table[k].userns) if (in_userns != mount_table[k].userns)
continue; continue;
where = prefix_root(dest, mount_table[k].where); where = prefix_root(dest, mount_table[k].where);
@ -278,7 +325,7 @@ int mount_all(const char *dest,
o = mount_table[k].options; o = mount_table[k].options;
if (streq_ptr(mount_table[k].type, "tmpfs")) { if (streq_ptr(mount_table[k].type, "tmpfs")) {
r = tmpfs_patch_options(o, userns, uid_shift, uid_range, selinux_apifs_context, &options); r = tmpfs_patch_options(o, use_userns, uid_shift, uid_range, selinux_apifs_context, &options);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
if (r > 0) if (r > 0)
@ -534,7 +581,7 @@ static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controlle
char *to; char *to;
int r; int r;
to = strjoina(dest, "/sys/fs/cgroup/", hierarchy); to = strjoina(strempty(dest), "/sys/fs/cgroup/", hierarchy);
r = path_is_mount_point(to, 0); r = path_is_mount_point(to, 0);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
@ -569,6 +616,8 @@ static int mount_legacy_cgroups(
cgroup_root = prefix_roota(dest, "/sys/fs/cgroup"); cgroup_root = prefix_roota(dest, "/sys/fs/cgroup");
(void) mkdir_p(cgroup_root, 0755);
/* Mount a tmpfs to /sys/fs/cgroup if it's not mounted there yet. */ /* Mount a tmpfs to /sys/fs/cgroup if it's not mounted there yet. */
r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW); r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW);
if (r < 0) if (r < 0)

View File

@ -57,7 +57,8 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
int custom_mount_compare(const void *a, const void *b); int custom_mount_compare(const void *a, const void *b);
int mount_all(const char *dest, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context); int mount_all(const char *dest, bool use_userns, bool in_userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
int mount_sysfs(const char *dest);
int mount_cgroups(const char *dest, bool unified_requested, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context); int mount_cgroups(const char *dest, bool unified_requested, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
int mount_systemd_cgroup_writable(const char *dest, bool unified_requested); int mount_systemd_cgroup_writable(const char *dest, bool unified_requested);

View File

@ -83,12 +83,12 @@
#include "udev-util.h" #include "udev-util.h"
#include "util.h" #include "util.h"
#include "nspawn-settings.h" #include "nspawn-cgroup.h"
#include "nspawn-expose-ports.h"
#include "nspawn-mount.h" #include "nspawn-mount.h"
#include "nspawn-network.h" #include "nspawn-network.h"
#include "nspawn-expose-ports.h"
#include "nspawn-cgroup.h"
#include "nspawn-register.h" #include "nspawn-register.h"
#include "nspawn-settings.h"
#include "nspawn-setuid.h" #include "nspawn-setuid.h"
typedef enum ContainerStatus { typedef enum ContainerStatus {
@ -2450,7 +2450,11 @@ static int inner_child(
} }
} }
r = mount_all(NULL, true, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context); r = mount_all(NULL, arg_userns, true, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
if (r < 0)
return r;
r = mount_sysfs(NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -2701,7 +2705,7 @@ static int outer_child(
return log_error_errno(r, "Failed to make tree read-only: %m"); return log_error_errno(r, "Failed to make tree read-only: %m");
} }
r = mount_all(directory, false, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context); r = mount_all(directory, arg_userns, false, arg_uid_shift, arg_uid_range, arg_selinux_apifs_context);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -78,7 +78,7 @@ int write_drop_in(const char *dir, const char *unit, unsigned level,
if (r < 0) if (r < 0)
return r; return r;
mkdir_p(p, 0755); (void) mkdir_p(p, 0755);
return write_string_file_atomic_label(q, data); return write_string_file_atomic_label(q, data);
} }
@ -132,8 +132,7 @@ static int iterate_dir(
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
log_error_errno(errno, "Failed to open directory %s: %m", path); return log_error_errno(errno, "Failed to open directory %s: %m", path);
return -errno;
} }
for (;;) { for (;;) {

View File

@ -5907,7 +5907,7 @@ static int is_system_running(int argc, char *argv[], void *userdata) {
} }
static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) { static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
char *t; _cleanup_free_ char *t = NULL;
int r; int r;
assert(new_path); assert(new_path);
@ -5919,26 +5919,21 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path); return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
r = mkdir_parents(new_path, 0755); r = mkdir_parents(new_path, 0755);
if (r < 0) { if (r < 0)
free(t);
return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path); return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
}
r = copy_file(original_path, t, 0, 0644, 0); r = copy_file(original_path, t, 0, 0644, 0);
if (r == -ENOENT) { if (r == -ENOENT) {
r = touch(t); r = touch(t);
if (r < 0) { if (r < 0)
log_error_errno(r, "Failed to create temporary file \"%s\": %m", t); return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
free(t);
return r; } else if (r < 0)
} return log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
} else if (r < 0) {
log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
free(t);
return r;
}
*ret_tmp_fn = t; *ret_tmp_fn = t;
t = NULL;
return 0; return 0;
} }
@ -5946,6 +5941,9 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) { static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
_cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL; _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
assert(name);
assert(ret_path);
switch (arg_scope) { switch (arg_scope) {
case UNIT_FILE_SYSTEM: case UNIT_FILE_SYSTEM:
path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name); path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
@ -5997,8 +5995,7 @@ static int get_file_to_edit(const char *name, const char *user_home, const char
} }
static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) { static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
char *tmp_new_path, *ending; char *tmp_new_path, *tmp_tmp_path, *ending;
char *tmp_tmp_path;
int r; int r;
assert(unit_name); assert(unit_name);
@ -6030,8 +6027,7 @@ static int unit_file_create_copy(
char **ret_new_path, char **ret_new_path,
char **ret_tmp_path) { char **ret_tmp_path) {
char *tmp_new_path; char *tmp_new_path, *tmp_tmp_path;
char *tmp_tmp_path;
int r; int r;
assert(fragment_path); assert(fragment_path);
@ -6150,7 +6146,7 @@ static int run_editor(char **paths) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to wait for child: %m"); return log_error_errno(r, "Failed to wait for child: %m");
return r; return 0;
} }
static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
@ -6234,13 +6230,14 @@ static int edit(int argc, char *argv[], void *userdata) {
goto end; goto end;
STRV_FOREACH_PAIR(original, tmp, paths) { STRV_FOREACH_PAIR(original, tmp, paths) {
/* If the temporary file is empty we ignore it. /* If the temporary file is empty we ignore it. It's
* It's useful if the user wants to cancel its modification * useful if the user wants to cancel its modification
*/ */
if (null_or_empty_path(*tmp)) { if (null_or_empty_path(*tmp)) {
log_warning("Editing \"%s\" canceled: temporary file is empty", *original); log_warning("Editing \"%s\" canceled: temporary file is empty.", *original);
continue; continue;
} }
r = rename(*tmp, *original); r = rename(*tmp, *original);
if (r < 0) { if (r < 0) {
r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original); r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
@ -6248,12 +6245,14 @@ static int edit(int argc, char *argv[], void *userdata) {
} }
} }
if (!arg_no_reload && bus && !install_client_side()) r = 0;
if (!arg_no_reload && !install_client_side())
r = daemon_reload(argc, argv, userdata); r = daemon_reload(argc, argv, userdata);
end: end:
STRV_FOREACH_PAIR(original, tmp, paths) STRV_FOREACH_PAIR(original, tmp, paths)
unlink_noerrno(*tmp); (void) unlink(*tmp);
return r; return r;
} }
@ -7004,7 +7003,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
assert(argc >= 0); assert(argc >= 0);
assert(argv); assert(argv);
while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0) while ((c = getopt_long(argc, argv, "HPrhkKtafFc", options, NULL)) >= 0)
switch (c) { switch (c) {
case ARG_HELP: case ARG_HELP:
@ -7487,6 +7486,10 @@ static int logind_schedule_shutdown(void) {
case ACTION_KEXEC: case ACTION_KEXEC:
action = "kexec"; action = "kexec";
break; break;
case ACTION_EXIT:
action = "exit";
break;
case ACTION_REBOOT:
default: default:
action = "reboot"; action = "reboot";
break; break;