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:
commit
1115d41706
5
TODO
5
TODO
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 (;;) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user