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:
* add "requires=" deps on slices from services, not just "wants="
* 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 a new command "systemctl revert" or so, that removes all dropin

View File

@ -168,6 +168,13 @@
<option>--log-level=</option> described in
<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
files and print warnings if any errors are detected. Files
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,
&reply,
"");
if (r < 0) {
log_error("Failed issue method call: %s", bus_error_message(&error, -r));
return r;
}
if (r < 0)
return log_error_errno(r, "Failed issue method call: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &text);
if (r < 0)
@ -1251,11 +1249,36 @@ static int set_log_level(sd_bus *bus, char **args) {
&error,
"s",
args[0]);
if (r < 0) {
log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
return -EIO;
if (r < 0)
return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
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;
}
@ -1285,7 +1308,8 @@ static void help(void) {
" critical-chain Print a tree of the time critical chain of units\n"
" plot Output SVG graphic showing service initialization\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"
" verify FILE... Check unit files for correctness\n"
, program_invocation_short_name);
@ -1452,6 +1476,8 @@ int main(int argc, char *argv[]) {
r = dump(bus, argv+optind+1);
else if (streq(argv[optind], "set-log-level"))
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
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);
if (t < 0)
return t;
return -EINVAL;
log_set_max_level(t);
return 0;

View File

@ -216,8 +216,55 @@ static int tmpfs_patch_options(
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,
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) {
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/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 */
{ "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/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 },
@ -252,7 +299,7 @@ int mount_all(const char *dest,
_cleanup_free_ char *where = NULL, *options = NULL;
const char *o;
if (userns != mount_table[k].userns)
if (in_userns != mount_table[k].userns)
continue;
where = prefix_root(dest, mount_table[k].where);
@ -278,7 +325,7 @@ int mount_all(const char *dest,
o = mount_table[k].options;
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)
return log_oom();
if (r > 0)
@ -534,7 +581,7 @@ static int mount_legacy_cgroup_hierarchy(const char *dest, const char *controlle
char *to;
int r;
to = strjoina(dest, "/sys/fs/cgroup/", hierarchy);
to = strjoina(strempty(dest), "/sys/fs/cgroup/", hierarchy);
r = path_is_mount_point(to, 0);
if (r < 0 && r != -ENOENT)
@ -569,6 +616,8 @@ static int mount_legacy_cgroups(
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. */
r = path_is_mount_point(cgroup_root, AT_SYMLINK_FOLLOW);
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 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_systemd_cgroup_writable(const char *dest, bool unified_requested);

View File

@ -83,12 +83,12 @@
#include "udev-util.h"
#include "util.h"
#include "nspawn-settings.h"
#include "nspawn-cgroup.h"
#include "nspawn-expose-ports.h"
#include "nspawn-mount.h"
#include "nspawn-network.h"
#include "nspawn-expose-ports.h"
#include "nspawn-cgroup.h"
#include "nspawn-register.h"
#include "nspawn-settings.h"
#include "nspawn-setuid.h"
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)
return r;
@ -2701,7 +2705,7 @@ static int outer_child(
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)
return r;

View File

@ -78,7 +78,7 @@ int write_drop_in(const char *dir, const char *unit, unsigned level,
if (r < 0)
return r;
mkdir_p(p, 0755);
(void) mkdir_p(p, 0755);
return write_string_file_atomic_label(q, data);
}
@ -132,8 +132,7 @@ static int iterate_dir(
if (errno == ENOENT)
return 0;
log_error_errno(errno, "Failed to open directory %s: %m", path);
return -errno;
return log_error_errno(errno, "Failed to open directory %s: %m", path);
}
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) {
char *t;
_cleanup_free_ char *t = NULL;
int r;
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);
r = mkdir_parents(new_path, 0755);
if (r < 0) {
free(t);
if (r < 0)
return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
}
r = copy_file(original_path, t, 0, 0644, 0);
if (r == -ENOENT) {
r = touch(t);
if (r < 0) {
log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
free(t);
return r;
}
} else if (r < 0) {
log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
free(t);
return r;
}
if (r < 0)
return log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
} else if (r < 0)
return log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
*ret_tmp_fn = t;
t = NULL;
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) {
_cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
assert(name);
assert(ret_path);
switch (arg_scope) {
case UNIT_FILE_SYSTEM:
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) {
char *tmp_new_path, *ending;
char *tmp_tmp_path;
char *tmp_new_path, *tmp_tmp_path, *ending;
int r;
assert(unit_name);
@ -6030,8 +6027,7 @@ static int unit_file_create_copy(
char **ret_new_path,
char **ret_tmp_path) {
char *tmp_new_path;
char *tmp_tmp_path;
char *tmp_new_path, *tmp_tmp_path;
int r;
assert(fragment_path);
@ -6150,7 +6146,7 @@ static int run_editor(char **paths) {
if (r < 0)
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) {
@ -6234,13 +6230,14 @@ static int edit(int argc, char *argv[], void *userdata) {
goto end;
STRV_FOREACH_PAIR(original, tmp, paths) {
/* If the temporary file is empty we ignore it.
* It's useful if the user wants to cancel its modification
/* If the temporary file is empty we ignore it. It's
* useful if the user wants to cancel its modification
*/
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;
}
r = rename(*tmp, *original);
if (r < 0) {
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);
end:
STRV_FOREACH_PAIR(original, tmp, paths)
unlink_noerrno(*tmp);
(void) unlink(*tmp);
return r;
}
@ -7004,7 +7003,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
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) {
case ARG_HELP:
@ -7487,6 +7486,10 @@ static int logind_schedule_shutdown(void) {
case ACTION_KEXEC:
action = "kexec";
break;
case ACTION_EXIT:
action = "exit";
break;
case ACTION_REBOOT:
default:
action = "reboot";
break;