[systemd-commits] 14 commits - Makefile.am TODO man/halt.xml man/journalctl.xml man/systemd-nspawn.xml man/systemd.service.xml src/core src/journal src/locale src/nspawn src/shared src/systemctl src/tmpfiles
Lennart Poettering
lennart at kemper.freedesktop.org
Fri Sep 7 03:37:43 PDT 2012
Makefile.am | 3
TODO | 34 ---
man/halt.xml | 9
man/journalctl.xml | 19 +
man/systemd-nspawn.xml | 2
man/systemd.service.xml | 11 -
src/core/shutdown.c | 50 ++--
src/journal/journal-file.c | 12 -
src/journal/journal-send.c | 2
src/journal/journal-vacuum.c | 2
src/journal/journalctl.c | 45 +---
src/journal/journald-kmsg.c | 2
src/journal/journald.c | 26 +-
src/locale/localed.c | 40 ---
src/nspawn/nspawn.c | 439 ++++++++++++++++++++++++++-----------------
src/shared/logs-show.c | 75 +++----
src/shared/logs-show.h | 10
src/shared/util.c | 4
src/systemctl/systemctl.c | 15 -
src/tmpfiles/tmpfiles.c | 16 +
20 files changed, 437 insertions(+), 379 deletions(-)
New commits:
commit 2b43f939a4b3ad5aeb2650868b0234ff42ec0045
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu Sep 6 00:32:51 2012 -0700
journald: avoid logging to kmsg in the normal paths
diff --git a/TODO b/TODO
index 59617a2..30e2f8e 100644
--- a/TODO
+++ b/TODO
@@ -51,8 +51,6 @@ Features:
* Query Paul Moore about relabelling socket fds while they are open
-* log fewer journal internal messages to the kernel kmsg
-
* move keymaps to /usr/lib/... rather than /usr/lib/udev/...
* journald: check whether it is OK if the client can still modify delivered journal entries
@@ -209,8 +207,6 @@ Features:
* journal: hook up with EFI firmware log
-* handle C-A-Del in logind, like the power/suspend buttons?
-
* nspawn: make use of device cgroup contrller by default
* drop accountsservice's StandardOutput=syslog and Type=dbus fields
@@ -337,8 +333,6 @@ Features:
* journalctl: --cursor support
-* systemctl status: show coredumps
-
* save coredump in Windows/Mozilla minidump format
* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 79f7598..697e7f3 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -490,7 +490,7 @@ static int journal_file_setup_data_hash_table(JournalFile *f) {
if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
s = DEFAULT_DATA_HASH_TABLE_SIZE;
- log_info("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem)));
+ log_debug("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem)));
r = journal_file_append_object(f,
OBJECT_DATA_HASH_TABLE,
@@ -2386,11 +2386,11 @@ void journal_default_metrics(JournalMetrics *m, int fd) {
m->keep_free = DEFAULT_KEEP_FREE;
}
- log_info("Fixed max_use=%s max_size=%s min_size=%s keep_free=%s",
- format_bytes(a, sizeof(a), m->max_use),
- format_bytes(b, sizeof(b), m->max_size),
- format_bytes(c, sizeof(c), m->min_size),
- format_bytes(d, sizeof(d), m->keep_free));
+ log_debug("Fixed max_use=%s max_size=%s min_size=%s keep_free=%s",
+ format_bytes(a, sizeof(a), m->max_use),
+ format_bytes(b, sizeof(b), m->max_size),
+ format_bytes(c, sizeof(c), m->min_size),
+ format_bytes(d, sizeof(d), m->keep_free));
}
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index ff2cd33..c890146 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -211,7 +211,7 @@ int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t m
break;
if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
- log_info("Deleted archived journal %s/%s.", directory, list[i].filename);
+ log_debug("Deleted archived journal %s/%s.", directory, list[i].filename);
sum -= list[i].usage;
} else if (errno != ENOENT)
log_warning("Failed to delete %s/%s: %m", directory, list[i].filename);
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index b259480..284ace9 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -359,7 +359,7 @@ int server_flush_dev_kmsg(Server *s) {
if (!s->dev_kmsg_readable)
return 0;
- log_info("Flushing /dev/kmsg...");
+ log_debug("Flushing /dev/kmsg...");
for (;;) {
r = server_read_dev_kmsg(s);
diff --git a/src/journal/journald.c b/src/journal/journald.c
index a1decea..5d0d203 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -304,7 +304,7 @@ static void server_rotate(Server *s) {
Iterator i;
int r;
- log_info("Rotating...");
+ log_debug("Rotating...");
if (s->runtime_journal) {
r = journal_file_rotate(&s->runtime_journal, s->compress, false);
@@ -349,7 +349,7 @@ static void server_vacuum(Server *s) {
sd_id128_t machine;
int r;
- log_info("Vacuuming...");
+ log_debug("Vacuuming...");
r = sd_id128_get_machine(&machine);
if (r < 0) {
@@ -444,7 +444,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
return;
if (journal_file_rotate_suggested(f)) {
- log_info("Journal header limits reached or header out-of-date, rotating.");
+ log_debug("Journal header limits reached or header out-of-date, rotating.");
server_rotate(s);
server_vacuum(s);
vacuumed = true;
@@ -475,11 +475,11 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
}
if (r == -E2BIG || r == -EFBIG || r == EDQUOT || r == ENOSPC)
- log_info("Allocation limit reached, rotating.");
+ log_debug("Allocation limit reached, rotating.");
else if (r == -EHOSTDOWN)
log_info("Journal file from other machine, rotating.");
else if (r == -EBUSY)
- log_info("Unlcean shutdown, rotating.");
+ log_info("Unclean shutdown, rotating.");
else
log_warning("Journal file corrupted, rotating.");
@@ -491,7 +491,7 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned
if (!f)
return;
- log_info("Retrying write.");
+ log_debug("Retrying write.");
}
}
@@ -890,7 +890,7 @@ static int server_flush_to_var(Server *s) {
if (!s->system_journal)
return 0;
- log_info("Flushing to /var...");
+ log_debug("Flushing to /var...");
r = sd_id128_get_machine(&machine);
if (r < 0) {
@@ -918,7 +918,7 @@ static int server_flush_to_var(Server *s) {
r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
if (r == -E2BIG) {
- log_info("Allocation limit reached.");
+ log_debug("Allocation limit reached.");
journal_file_post_change(s->system_journal);
server_rotate(s);
@@ -954,7 +954,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
ssize_t n;
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
@@ -990,7 +990,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
int r;
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
@@ -1004,7 +1004,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
ev->data.fd == s->syslog_fd) {
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
@@ -1132,7 +1132,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
} else if (ev->data.fd == s->stdout_fd) {
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
@@ -1143,7 +1143,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
StdoutStream *stream;
if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
commit f687b2738229570453c9412add6b9c4f99c9c004
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 23:54:09 2012 -0700
localed: system-setup-keyboard is no more on fedora
diff --git a/TODO b/TODO
index 4519037..59617a2 100644
--- a/TODO
+++ b/TODO
@@ -128,9 +128,6 @@ Features:
* add _SYSTEMD_USER_UNIT= field to journal entries
-* remove Fedora /dev/null logic from localed.c, now that system-config-keyboard is gone
- delete /etc/X11/xorg.conf.d/00-system-setup-keyboard.conf from spec file
-
* journal: expose current disk usage
* dracut-shutdown needs to be ordered before unmounting /boot
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 22950a6..667c5d1 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -271,24 +271,8 @@ static int read_data_x11(void) {
free_data_x11();
f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
- if (!f) {
- if (errno == ENOENT) {
-
-#ifdef TARGET_FEDORA
- f = fopen("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf", "re");
- if (!f) {
- if (errno == ENOENT)
- return 0;
- else
- return -errno;
- }
-#else
- return 0;
-#endif
-
- } else
- return -errno;
- }
+ if (!f)
+ return errno == ENOENT ? 0 : -errno;
while (fgets(line, sizeof(line), f)) {
char *l;
@@ -577,14 +561,6 @@ static int write_data_x11(void) {
isempty(state.x11_variant) &&
isempty(state.x11_options)) {
-#ifdef TARGET_FEDORA
- unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf");
-
- /* Symlink this to /dev/null, so that s-s-k (if it is
- * still running) doesn't recreate this. */
- symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf");
-#endif
-
if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
return errno == ENOENT ? 0 : -errno;
@@ -624,18 +600,8 @@ static int write_data_x11(void) {
r = -errno;
unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
unlink(temp_path);
- } else {
-
-#ifdef TARGET_FEDORA
- unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf");
-
- /* Symlink this to /dev/null, so that s-s-k (if it is
- * still running) doesn't recreate this. */
- symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf");
-#endif
-
+ } else
r = 0;
- }
fclose(f);
free(temp_path);
commit a29271926ad5530276cec486c93ea72ef71a652c
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 23:51:19 2012 -0700
man: document that ExecStart= doesn't understand shell command lines
diff --git a/TODO b/TODO
index 326edb0..4519037 100644
--- a/TODO
+++ b/TODO
@@ -83,14 +83,10 @@ Features:
* currently system services appear not to generate core dumps...
-* introduce /run/kmsg in containers?
-
* wall messages for shutdown should move to logind
* allow writing multiple conditions in unit files on one line
-* journal: json output needs to be able to deal with multiple assignments of the same field
-
* There's something wrong with escaping unit names: http://lists.freedesktop.org/archives/systemd-devel/2012-August/006292.html
* cleanup ellipsation for log output in journalctl and systemctl status: have a sane way to disable ellipsation, and disable it by default when invoked in less/more
@@ -103,8 +99,6 @@ Features:
* maybe make systemd-detect-virt suid? or use fscaps?
-* man: document in ExecStart= explicitly that we don't take shell command lines, only executable names with arguments
-
* shutdown: don't read-only mount anything when running in container
* nspawn: --read-only is not applied recursively to submounts
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 72b67c6..c547948 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -356,7 +356,16 @@
argument (i.e. the program to execute)
may not be a variable, and must be a
literal and absolute path
- name.</para></listitem>
+ name.</para>
+
+ <para>Note that this setting does not
+ directly support shell command
+ lines. If shell command lines are to
+ be used they need to be passed
+ explicitly to a shell implementation
+ of some kind. Example:
+ <literal>ExecStart=/bin/sh -c 'dmesg | tac'</literal></para>
+ </listitem>
</varlistentry>
<varlistentry>
commit cb7ed9dfca647198bce95f503552710eae22da37
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 23:39:55 2012 -0700
tmpfiles: don't attempt creation of device nodes when we run in a container
diff --git a/Makefile.am b/Makefile.am
index ae775c8..f88d193 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1296,7 +1296,8 @@ systemd_tmpfiles_SOURCES = \
systemd_tmpfiles_LDADD = \
libsystemd-label.la \
- libsystemd-shared.la
+ libsystemd-shared.la \
+ libsystemd-capability.la
# ------------------------------------------------------------------------------
systemd_machine_id_setup_SOURCES = \
diff --git a/TODO b/TODO
index c7f789b..326edb0 100644
--- a/TODO
+++ b/TODO
@@ -61,11 +61,9 @@ Features:
* json: properly serialize multiple fields with the same name per entry
-* journalctl: make -l the default
-
* journald: add option to choose between "split up nothing", "split up login user journals", "split up all user journals"
-* journal live copy, bsaed on libneon (client) and libmicrohttpd
+* journal live copy, based on libneon (client) and libmicrohttpd
* document in wiki json serialization
@@ -81,8 +79,6 @@ Features:
* system.conf should have controls for cgroups
-* tmpfiles: skip mknod if CAP_MKNOD is missing
-
* bind mount read-only the cgroup tree higher than than nspawn
* currently system services appear not to generate core dumps...
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index e70332c..323781f 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -38,6 +38,7 @@
#include <sys/param.h>
#include <glob.h>
#include <fnmatch.h>
+#include <sys/capability.h>
#include "log.h"
#include "util.h"
@@ -47,6 +48,7 @@
#include "label.h"
#include "set.h"
#include "conf-files.h"
+#include "capability.h"
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
* them in the file system. This is intended to be used to create
@@ -764,7 +766,19 @@ static int create_item(Item *i) {
case CREATE_BLOCK_DEVICE:
case CREATE_CHAR_DEVICE: {
- mode_t file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
+ mode_t file_type;
+
+ if (have_effective_cap(CAP_MKNOD) == 0) {
+ /* In a container we lack CAP_MKNOD. We
+ shouldnt attempt to create the device node in
+ that case to avoid noise, and we don't support
+ virtualized devices in containers anyway. */
+
+ log_debug("We lack CAP_MKNOD, skipping creation of device node %s.", i->path);
+ return 0;
+ }
+
+ file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
u = umask(0);
label_context_set(i->path, file_type);
commit dcc9ba80e160bb6e2ed97c7ee343953721702b0c
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 17:05:04 2012 -0700
systemctl: properly build flags for show_journal_by_unit()
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 14f8a12..98d0fcb 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2259,7 +2259,7 @@ static void print_status_info(UnitStatusInfo *i) {
if (i->id && arg_transport != TRANSPORT_SSH) {
int flags =
- arg_lines * OUTPUT_SHOW_ALL |
+ arg_all * OUTPUT_SHOW_ALL |
arg_follow * OUTPUT_FOLLOW |
!arg_quiet * OUTPUT_WARN_CUTOFF |
on_tty() * OUTPUT_COLOR;
commit cd931c0a464da9d0555e6a8e83c1aba176c0971b
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 16:52:46 2012 -0700
journalctl: show "Reboot" markers in output only when showing local-only entries
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 73e8cb8..1a6464d 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -823,7 +823,6 @@ int main(int argc, char *argv[]) {
for (;;) {
for (;;) {
- sd_id128_t boot_id;
int flags =
arg_show_all * OUTPUT_SHOW_ALL |
have_pager * OUTPUT_FULL_WIDTH |
@@ -840,14 +839,18 @@ int main(int argc, char *argv[]) {
if (r == 0)
break;
- r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
- if (r >= 0) {
- if (previous_boot_id_valid &&
- !sd_id128_equal(boot_id, previous_boot_id))
- printf(ANSI_HIGHLIGHT_ON "----- Reboot -----" ANSI_HIGHLIGHT_OFF "\n");
+ if (!arg_merge) {
+ sd_id128_t boot_id;
- previous_boot_id = boot_id;
- previous_boot_id_valid = true;
+ r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
+ if (r >= 0) {
+ if (previous_boot_id_valid &&
+ !sd_id128_equal(boot_id, previous_boot_id))
+ printf(ANSI_HIGHLIGHT_ON "----- Reboot -----" ANSI_HIGHLIGHT_OFF "\n");
+
+ previous_boot_id = boot_id;
+ previous_boot_id_valid = true;
+ }
}
line ++;
commit 9e8a535faa370bab283cb2c3c52b0a0d44e9d193
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 16:49:00 2012 -0700
journalctl: replace --local by --merge, i.e. don't interleave remote journals by default
diff --git a/man/journalctl.xml b/man/journalctl.xml
index b5950c9..296e3fd 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -234,11 +234,13 @@
</varlistentry>
<varlistentry>
- <term><option>--local</option></term>
- <term><option>-l</option></term>
+ <term><option>--merge</option></term>
+ <term><option>-m</option></term>
- <listitem><para>Show only locally
- generated messages.</para></listitem>
+ <listitem><para>Show entries
+ interleaved from all available
+ journals, including remote
+ ones.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 56a8abe..73e8cb8 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -58,7 +58,7 @@ static bool arg_no_pager = false;
static int arg_lines = -1;
static bool arg_no_tail = false;
static bool arg_quiet = false;
-static bool arg_local = false;
+static bool arg_merge = false;
static bool arg_this_boot = false;
static const char *arg_directory = NULL;
static int arg_priorities = 0xFF;
@@ -89,7 +89,7 @@ static int help(void) {
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
" verbose, export, json, json-pretty, cat)\n"
" -q --quiet Don't show privilege warning\n"
- " -l --local Only local entries\n"
+ " -m --merge Show entries from all available journals\n"
" -b --this-boot Show data only from current boot\n"
" -D --directory=PATH Show journal files from directory\n"
" -p --priority=RANGE Show only messages within the specified priority range\n\n"
@@ -132,7 +132,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "no-tail", no_argument, NULL, ARG_NO_TAIL },
{ "new-id128", no_argument, NULL, ARG_NEW_ID128 },
{ "quiet", no_argument, NULL, 'q' },
- { "local", no_argument, NULL, 'l' },
+ { "merge", no_argument, NULL, 'm' },
{ "this-boot", no_argument, NULL, 'b' },
{ "directory", required_argument, NULL, 'D' },
{ "header", no_argument, NULL, ARG_HEADER },
@@ -149,7 +149,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "hfo:an:qlbD:p:", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "hfo:an:qmbD:p:", options, NULL)) >= 0) {
switch (c) {
@@ -204,8 +204,8 @@ static int parse_argv(int argc, char *argv[]) {
arg_quiet = true;
break;
- case 'l':
- arg_local = true;
+ case 'm':
+ arg_merge = true;
break;
case 'b':
@@ -233,7 +233,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_VERIFY_KEY:
arg_action = ACTION_VERIFY;
arg_verify_key = optarg;
- arg_local = true;
+ arg_merge = false;
break;
case ARG_INTERVAL:
@@ -728,7 +728,7 @@ int main(int argc, char *argv[]) {
if (arg_directory)
r = sd_journal_open_directory(&j, arg_directory, 0);
else
- r = sd_journal_open(&j, arg_local ? SD_JOURNAL_LOCAL_ONLY : 0);
+ r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY);
if (r < 0) {
log_error("Failed to open journal: %s", strerror(-r));
commit d87be9b0af81a6e07d4fb3028e45c4409100dc26
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 16:23:41 2012 -0700
nspawn: handle poweroff/reboot nicely in containers
diff --git a/TODO b/TODO
index e683eea..c7f789b 100644
--- a/TODO
+++ b/TODO
@@ -49,15 +49,16 @@ Bugfixes:
Features:
+* Query Paul Moore about relabelling socket fds while they are open
+
* log fewer journal internal messages to the kernel kmsg
* move keymaps to /usr/lib/... rather than /usr/lib/udev/...
* journald: check whether it is OK if the client can still modify delivered journal entries
-* json: use yajl
-* json: don't add wrapping array, just put entries on one line each
-* json: add -o json-pretty in addition to -o json, make the latter output one line per entry
+* json: use jensson
+
* json: properly serialize multiple fields with the same name per entry
* journalctl: make -l the default
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 9f8b8e2..1f7d74e 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -232,7 +232,7 @@
CAP_SETUID, CAP_SYS_ADMIN,
CAP_SYS_CHROOT, CAP_SYS_NICE,
CAP_SYS_PTRACE, CAP_SYS_TTY_CONFIG,
- CAP_SYS_RESOURCE.</para></listitem>
+ CAP_SYS_RESOURCE, CAP_SYS_BOOT.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 7b1b5ea..7f084ef 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -92,7 +92,8 @@ static uint64_t arg_retain =
(1ULL << CAP_SYS_NICE) |
(1ULL << CAP_SYS_PTRACE) |
(1ULL << CAP_SYS_TTY_CONFIG) |
- (1ULL << CAP_SYS_RESOURCE);
+ (1ULL << CAP_SYS_RESOURCE) |
+ (1ULL << CAP_SYS_BOOT);
static int help(void) {
@@ -1167,11 +1168,6 @@ int main(int argc, char *argv[]) {
cfmakeraw(&raw_attr);
raw_attr.c_lflag &= ~ECHO;
- if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
- log_error("Failed to set terminal attributes: %m");
- goto finish;
- }
-
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, kmsg_socket_pair) < 0) {
log_error("Failed to create kmsg socket pair");
goto finish;
@@ -1181,232 +1177,271 @@ int main(int argc, char *argv[]) {
sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1);
assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
- pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
- if (pid < 0) {
- if (errno == EINVAL)
- log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
- else
- log_error("clone() failed: %m");
+ for (;;) {
+ siginfo_t status;
- goto finish;
- }
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
+ log_error("Failed to set terminal attributes: %m");
+ goto finish;
+ }
- if (pid == 0) {
- /* child */
-
- const char *home = NULL;
- uid_t uid = (uid_t) -1;
- gid_t gid = (gid_t) -1;
- const char *envp[] = {
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
- "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
- NULL, /* TERM */
- NULL, /* HOME */
- NULL, /* USER */
- NULL, /* LOGNAME */
- NULL, /* container_uuid */
- NULL
- };
-
- envp[2] = strv_find_prefix(environ, "TERM=");
+ pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
+ if (pid < 0) {
+ if (errno == EINVAL)
+ log_error("clone() failed, do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in): %m");
+ else
+ log_error("clone() failed: %m");
- close_nointr_nofail(master);
+ goto finish;
+ }
- close_nointr(STDIN_FILENO);
- close_nointr(STDOUT_FILENO);
- close_nointr(STDERR_FILENO);
+ if (pid == 0) {
+ /* child */
- close_all_fds(&kmsg_socket_pair[1], 1);
+ const char *home = NULL;
+ uid_t uid = (uid_t) -1;
+ gid_t gid = (gid_t) -1;
+ const char *envp[] = {
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+ "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */
+ NULL, /* TERM */
+ NULL, /* HOME */
+ NULL, /* USER */
+ NULL, /* LOGNAME */
+ NULL, /* container_uuid */
+ NULL
+ };
- reset_all_signal_handlers();
+ envp[2] = strv_find_prefix(environ, "TERM=");
- assert_se(sigemptyset(&mask) == 0);
- assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
+ close_nointr_nofail(master);
- if (open_terminal(console, O_RDWR) != STDIN_FILENO ||
- dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
- dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
- goto child_fail;
+ close_nointr(STDIN_FILENO);
+ close_nointr(STDOUT_FILENO);
+ close_nointr(STDERR_FILENO);
- if (setsid() < 0) {
- log_error("setsid() failed: %m");
- goto child_fail;
- }
+ close_all_fds(&kmsg_socket_pair[1], 1);
- if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
- log_error("PR_SET_PDEATHSIG failed: %m");
- goto child_fail;
- }
+ reset_all_signal_handlers();
- /* Mark everything as slave, so that we still
- * receive mounts from the real root, but don't
- * propagate mounts to the real root. */
- if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
- log_error("MS_SLAVE|MS_REC failed: %m");
- goto child_fail;
- }
+ assert_se(sigemptyset(&mask) == 0);
+ assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
- /* Turn directory into bind mount */
- if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) {
- log_error("Failed to make bind mount.");
- goto child_fail;
- }
+ if (open_terminal(console, O_RDWR) != STDIN_FILENO ||
+ dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO ||
+ dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
+ goto child_fail;
- if (arg_read_only)
- if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) {
- log_error("Failed to make read-only.");
+ if (setsid() < 0) {
+ log_error("setsid() failed: %m");
goto child_fail;
}
- if (mount_all(arg_directory) < 0)
- goto child_fail;
-
- if (copy_devnodes(arg_directory) < 0)
- goto child_fail;
-
- dev_setup(arg_directory);
-
- if (setup_dev_console(arg_directory, console) < 0)
- goto child_fail;
-
- if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
- goto child_fail;
-
- close_nointr_nofail(kmsg_socket_pair[1]);
+ if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) {
+ log_error("PR_SET_PDEATHSIG failed: %m");
+ goto child_fail;
+ }
- if (setup_boot_id(arg_directory) < 0)
- goto child_fail;
+ /* Mark everything as slave, so that we still
+ * receive mounts from the real root, but don't
+ * propagate mounts to the real root. */
+ if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
+ log_error("MS_SLAVE|MS_REC failed: %m");
+ goto child_fail;
+ }
- if (setup_timezone(arg_directory) < 0)
- goto child_fail;
+ /* Turn directory into bind mount */
+ if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) {
+ log_error("Failed to make bind mount.");
+ goto child_fail;
+ }
- if (setup_resolv_conf(arg_directory) < 0)
- goto child_fail;
+ if (arg_read_only)
+ if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) {
+ log_error("Failed to make read-only.");
+ goto child_fail;
+ }
- if (setup_journal(arg_directory) < 0)
- goto child_fail;
+ if (mount_all(arg_directory) < 0)
+ goto child_fail;
- if (chdir(arg_directory) < 0) {
- log_error("chdir(%s) failed: %m", arg_directory);
- goto child_fail;
- }
+ if (copy_devnodes(arg_directory) < 0)
+ goto child_fail;
- if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) {
- log_error("mount(MS_MOVE) failed: %m");
- goto child_fail;
- }
+ dev_setup(arg_directory);
- if (chroot(".") < 0) {
- log_error("chroot() failed: %m");
- goto child_fail;
- }
+ if (setup_dev_console(arg_directory, console) < 0)
+ goto child_fail;
- if (chdir("/") < 0) {
- log_error("chdir() failed: %m");
- goto child_fail;
- }
+ if (setup_kmsg(arg_directory, kmsg_socket_pair[1]) < 0)
+ goto child_fail;
- umask(0022);
+ close_nointr_nofail(kmsg_socket_pair[1]);
- loopback_setup();
+ if (setup_boot_id(arg_directory) < 0)
+ goto child_fail;
- if (drop_capabilities() < 0) {
- log_error("drop_capabilities() failed: %m");
- goto child_fail;
- }
+ if (setup_timezone(arg_directory) < 0)
+ goto child_fail;
- if (arg_user) {
+ if (setup_resolv_conf(arg_directory) < 0)
+ goto child_fail;
- if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) {
- log_error("get_user_creds() failed: %m");
+ if (setup_journal(arg_directory) < 0)
goto child_fail;
- }
- if (mkdir_parents_label(home, 0775) < 0) {
- log_error("mkdir_parents_label() failed: %m");
+ if (chdir(arg_directory) < 0) {
+ log_error("chdir(%s) failed: %m", arg_directory);
goto child_fail;
}
- if (mkdir_safe_label(home, 0775, uid, gid) < 0) {
- log_error("mkdir_safe_label() failed: %m");
+ if (mount(arg_directory, "/", NULL, MS_MOVE, NULL) < 0) {
+ log_error("mount(MS_MOVE) failed: %m");
goto child_fail;
}
- if (initgroups((const char*)arg_user, gid) < 0) {
- log_error("initgroups() failed: %m");
+ if (chroot(".") < 0) {
+ log_error("chroot() failed: %m");
goto child_fail;
}
- if (setresgid(gid, gid, gid) < 0) {
- log_error("setregid() failed: %m");
+ if (chdir("/") < 0) {
+ log_error("chdir() failed: %m");
goto child_fail;
}
- if (setresuid(uid, uid, uid) < 0) {
- log_error("setreuid() failed: %m");
+ umask(0022);
+
+ loopback_setup();
+
+ if (drop_capabilities() < 0) {
+ log_error("drop_capabilities() failed: %m");
goto child_fail;
}
- }
- if ((asprintf((char**)(envp + 3), "HOME=%s", home ? home: "/root") < 0) ||
- (asprintf((char**)(envp + 4), "USER=%s", arg_user ? arg_user : "root") < 0) ||
- (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
- log_oom();
- goto child_fail;
- }
+ if (arg_user) {
+
+ if (get_user_creds((const char**)&arg_user, &uid, &gid, &home, NULL) < 0) {
+ log_error("get_user_creds() failed: %m");
+ goto child_fail;
+ }
+
+ if (mkdir_parents_label(home, 0775) < 0) {
+ log_error("mkdir_parents_label() failed: %m");
+ goto child_fail;
+ }
+
+ if (mkdir_safe_label(home, 0775, uid, gid) < 0) {
+ log_error("mkdir_safe_label() failed: %m");
+ goto child_fail;
+ }
+
+ if (initgroups((const char*)arg_user, gid) < 0) {
+ log_error("initgroups() failed: %m");
+ goto child_fail;
+ }
- if (arg_uuid) {
- if (asprintf((char**)(envp + 6), "container_uuid=%s", arg_uuid) < 0) {
+ if (setresgid(gid, gid, gid) < 0) {
+ log_error("setregid() failed: %m");
+ goto child_fail;
+ }
+
+ if (setresuid(uid, uid, uid) < 0) {
+ log_error("setreuid() failed: %m");
+ goto child_fail;
+ }
+ }
+
+ if ((asprintf((char**)(envp + 3), "HOME=%s", home ? home: "/root") < 0) ||
+ (asprintf((char**)(envp + 4), "USER=%s", arg_user ? arg_user : "root") < 0) ||
+ (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user ? arg_user : "root") < 0)) {
log_oom();
goto child_fail;
}
- }
- setup_hostname();
+ if (arg_uuid) {
+ if (asprintf((char**)(envp + 6), "container_uuid=%s", arg_uuid) < 0) {
+ log_oom();
+ goto child_fail;
+ }
+ }
+
+ setup_hostname();
+
+ if (arg_boot) {
+ char **a;
+ size_t l;
- if (arg_boot) {
- char **a;
- size_t l;
+ /* Automatically search for the init system */
- /* Automatically search for the init system */
+ l = 1 + argc - optind;
+ a = newa(char*, l + 1);
+ memcpy(a + 1, argv + optind, l * sizeof(char*));
- l = 1 + argc - optind;
- a = newa(char*, l + 1);
- memcpy(a + 1, argv + optind, l * sizeof(char*));
+ a[0] = (char*) "/usr/lib/systemd/systemd";
+ execve(a[0], a, (char**) envp);
- a[0] = (char*) "/usr/lib/systemd/systemd";
- execve(a[0], a, (char**) envp);
+ a[0] = (char*) "/lib/systemd/systemd";
+ execve(a[0], a, (char**) envp);
- a[0] = (char*) "/lib/systemd/systemd";
- execve(a[0], a, (char**) envp);
+ a[0] = (char*) "/sbin/init";
+ execve(a[0], a, (char**) envp);
+ } else if (argc > optind)
+ execvpe(argv[optind], argv + optind, (char**) envp);
+ else {
+ chdir(home ? home : "/root");
+ execle("/bin/bash", "-bash", NULL, (char**) envp);
+ }
+
+ log_error("execv() failed: %m");
- a[0] = (char*) "/sbin/init";
- execve(a[0], a, (char**) envp);
- } else if (argc > optind)
- execvpe(argv[optind], argv + optind, (char**) envp);
- else {
- chdir(home ? home : "/root");
- execle("/bin/bash", "-bash", NULL, (char**) envp);
+ child_fail:
+ _exit(EXIT_FAILURE);
}
- log_error("execv() failed: %m");
+ if (process_pty(master, &mask) < 0)
+ goto finish;
- child_fail:
- _exit(EXIT_FAILURE);
- }
- if (process_pty(master, &mask) < 0)
- goto finish;
+ if (saved_attr_valid)
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
- if (saved_attr_valid) {
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr);
- saved_attr_valid = false;
- }
+ r = wait_for_terminate(pid, &status);
+ if (r < 0) {
+ r = EXIT_FAILURE;
+ break;
+ }
- r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid);
+ if (status.si_code == CLD_EXITED) {
+ if (status.si_status != 0) {
+ log_error("Container failed with error code %i.", status.si_status);
+ r = status.si_status;
+ break;
+ }
+
+ log_debug("Container exited successfully.");
+ break;
+ } else if (status.si_code == CLD_KILLED &&
+ status.si_status == SIGINT) {
+ log_info("Container has been shut down.");
+ r = 0;
+ break;
+ } else if (status.si_code == CLD_KILLED &&
+ status.si_status == SIGHUP) {
+ log_info("Container is being rebooted.");
+ continue;
+ } else if (status.si_code == CLD_KILLED ||
+ status.si_code == CLD_DUMPED) {
- if (r < 0)
- r = EXIT_FAILURE;
+ log_error("Container terminated by signal %s.", signal_to_string(status.si_status));
+ r = EXIT_FAILURE;
+ break;
+ } else {
+ log_error("Container failed due to unknown reason.");
+ r = EXIT_FAILURE;
+ break;
+ }
+ }
finish:
if (saved_attr_valid)
diff --git a/src/shared/util.c b/src/shared/util.c
index 95b577b..4f5cb26 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4011,7 +4011,8 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid) {
assert(name);
assert(pid > 1);
- if ((r = wait_for_terminate(pid, &status)) < 0) {
+ r = wait_for_terminate(pid, &status);
+ if (r < 0) {
log_warning("Failed to wait for %s: %s", name, strerror(-r));
return r;
}
@@ -4034,7 +4035,6 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid) {
log_warning("%s failed due to unknown reason.", name);
return -EPROTO;
-
}
_noreturn_ void freeze(void) {
commit cb7ec5645e0edf154f0cc8414f5914cb433d0dfe
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 15:37:18 2012 -0700
shutdown: in containers, invoke reboot(2), too. Then fallback to exit() if CAP_SYS_BOOT is missing
The kernel's PID namespaces support reboot(2) just fine, so let's make
use of it if possible.
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 558111b..cc8c57b 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -263,14 +263,8 @@ int main(int argc, char *argv[]) {
arguments[2] = NULL;
execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
- /* If we are in a container, just exit, this will kill our
- * container for good. */
- if (in_container) {
- log_error("Exiting container.");
- exit(0);
- }
-
- if (access("/run/initramfs/shutdown", X_OK) == 0) {
+ if (!in_container &&
+ access("/run/initramfs/shutdown", X_OK) == 0) {
if (prepare_new_root() >= 0 &&
pivot_to_new_root() >= 0) {
@@ -280,25 +274,37 @@ int main(int argc, char *argv[]) {
}
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
- /* We cheat and exec kexec to avoid doing all its work */
- pid_t pid = fork();
-
- if (pid < 0)
- log_error("Could not fork: %m. Falling back to normal reboot.");
- else if (pid > 0) {
- wait_for_terminate_and_warn("kexec", pid);
- log_warning("kexec failed. Falling back to normal reboot.");
- } else {
- /* Child */
- const char *args[3] = { "/sbin/kexec", "-e", NULL };
- execv(args[0], (char * const *) args);
- return EXIT_FAILURE;
+
+ if (!in_container) {
+ /* We cheat and exec kexec to avoid doing all its work */
+ pid_t pid = fork();
+
+ if (pid < 0)
+ log_error("Could not fork: %m. Falling back to normal reboot.");
+ else if (pid > 0) {
+ wait_for_terminate_and_warn("kexec", pid);
+ log_warning("kexec failed. Falling back to normal reboot.");
+ } else {
+ /* Child */
+ const char *args[3] = { "/sbin/kexec", "-e", NULL };
+ execv(args[0], (char * const *) args);
+ return EXIT_FAILURE;
+ }
}
cmd = RB_AUTOBOOT;
}
reboot(cmd);
+
+ if (errno == EPERM && in_container) {
+ /* If we are in a container, and we lacked
+ * CAP_SYS_BOOT just exit, this will kill our
+ * container for good. */
+ log_error("Exiting container.");
+ exit(0);
+ }
+
log_error("Failed to invoke reboot(): %m");
r = -errno;
commit 57371e5829a61e5ee6c9f98404dfc729d6c62608
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 15:32:57 2012 -0700
shutdown: remove explicit sync() invocations
The kernel implicitly does sync() anyway, hence there is no need to do
that in userspace explicitly. This makes the "-n" switch to halt(8) a
noop.
diff --git a/man/halt.xml b/man/halt.xml
index 7ba85ed..ed1c52c 100644
--- a/man/halt.xml
+++ b/man/halt.xml
@@ -136,15 +136,6 @@
</varlistentry>
<varlistentry>
- <term><option>-n</option></term>
- <term><option>--no-sync</option></term>
-
- <listitem><para>Don't sync hard disks/storage media before
- halt, power-off,
- reboot.</para></listitem>
- </varlistentry>
-
- <varlistentry>
<term><option>--no-wall</option></term>
<listitem><para>Don't send wall
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index c3a4c39..558111b 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -279,8 +279,6 @@ int main(int argc, char *argv[]) {
}
}
- sync();
-
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
/* We cheat and exec kexec to avoid doing all its work */
pid_t pid = fork();
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 871a04b..14f8a12 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -74,7 +74,6 @@ static bool arg_no_block = false;
static bool arg_no_legend = false;
static bool arg_no_pager = false;
static bool arg_no_wtmp = false;
-static bool arg_no_sync = false;
static bool arg_no_wall = false;
static bool arg_no_reload = false;
static bool arg_dry = false;
@@ -3949,7 +3948,6 @@ static int halt_help(void) {
" -f --force Force immediate halt/power-off/reboot\n"
" -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
" -d --no-wtmp Don't write wtmp record\n"
- " -n --no-sync Don't sync before halt/power-off/reboot\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n",
program_invocation_short_name,
arg_action == ACTION_REBOOT ? "Reboot" :
@@ -4271,7 +4269,6 @@ static int halt_parse_argv(int argc, char *argv[]) {
{ "force", no_argument, NULL, 'f' },
{ "wtmp-only", no_argument, NULL, 'w' },
{ "no-wtmp", no_argument, NULL, 'd' },
- { "no-sync", no_argument, NULL, 'n' },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
{ NULL, 0, NULL, 0 }
};
@@ -4317,16 +4314,13 @@ static int halt_parse_argv(int argc, char *argv[]) {
arg_no_wtmp = true;
break;
- case 'n':
- arg_no_sync = true;
- break;
-
case ARG_NO_WALL:
arg_no_wall = true;
break;
case 'i':
case 'h':
+ case 'n':
/* Compatibility nops */
break;
@@ -5168,9 +5162,6 @@ static int halt_main(DBusConnection *bus) {
}
}
- if (!arg_no_sync)
- sync();
-
if (arg_dry)
return 0;
commit 3eabccc46c003d129a847ba423a6d0ba778e4930
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 15:27:07 2012 -0700
nspawn: don't provide /dev/rtc0 in the container
Since RTCs are hardware devices and are very much shared resources we
should avoid to provide them in each container.
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 8765b01..7b1b5ea 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -443,8 +443,7 @@ static int copy_devnodes(const char *dest) {
"random\0"
"urandom\0"
"tty\0"
- "ptmx\0"
- "rtc0\0";
+ "ptmx\0";
const char *d;
int r = 0;
commit a6e87e90ede66815989ba2db92a07102a69906fe
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 15:25:32 2012 -0700
journalctl: rework JSON output mode
This splits the JSON output mode into different modes: json and
json-pretty. The former printing one entry per line, the latter showing
JSON objects nicely indented and in multiple lines to make it easier to
read for humans.
diff --git a/TODO b/TODO
index 92d709e..e683eea 100644
--- a/TODO
+++ b/TODO
@@ -49,6 +49,8 @@ Bugfixes:
Features:
+* log fewer journal internal messages to the kernel kmsg
+
* move keymaps to /usr/lib/... rather than /usr/lib/udev/...
* journald: check whether it is OK if the client can still modify delivered journal entries
@@ -72,7 +74,7 @@ Features:
* securityfs: don't mount in container
-* slave/shared remount root fs in container
+* slave/shared remount root fs in container might clash with CAP_SYS_MOUNTS
* ability to pass fds into systemd
@@ -327,7 +329,7 @@ Features:
* dbus: in fedora, make the machine a symlink to /etc/machine-id
-* dbus: on fedora, move dbus to early boot
+* dbus: move dbus to early boot
* journald: reuse XZ context
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 1ea004f..b5950c9 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -189,6 +189,7 @@
<literal>verbose</literal>,
<literal>export</literal>,
<literal>json</literal>,
+ <literal>json-pretty</literal>,
<literal>cat</literal>. <literal>short</literal>
is the default and generates an output
that is mostly identical to the
@@ -209,7 +210,13 @@
Export Format</ulink> for more
information). <literal>json</literal>
formats entries as JSON data
- structures. <literal>cat</literal>
+ structures, one per
+ line. <literal>json-pretty</literal>
+ also formats entries as JSON data
+ structures, but formats them in
+ multiple lines in order to make them
+ more readable for
+ humans. <literal>cat</literal>
generates a very terse output only
showing the actual message of each
journal entry with no meta data, not
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index d0f3b72..b192f1f 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -439,7 +439,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
memcpy(header, identifier, l);
header[l++] = '\n';
- header[l++] = '\n';
+ header[l++] = '\n'; /* unit id */
header[l++] = '0' + priority;
header[l++] = '\n';
header[l++] = '0' + !!level_prefix;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 6aff1f1..56a8abe 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -87,7 +87,7 @@ static int help(void) {
" -n --lines=INTEGER Journal entries to show\n"
" --no-tail Show all lines, even in follow mode\n"
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, cat)\n"
+ " verbose, export, json, json-pretty, cat)\n"
" -q --quiet Don't show privilege warning\n"
" -l --local Only local entries\n"
" -b --this-boot Show data only from current boot\n"
@@ -821,11 +821,6 @@ int main(int argc, char *argv[]) {
on_tty();
have_pager = !arg_no_pager && !arg_follow && pager_open();
- if (arg_output == OUTPUT_JSON) {
- fputc('[', stdout);
- fflush(stdout);
- }
-
for (;;) {
for (;;) {
sd_id128_t boot_id;
@@ -874,9 +869,6 @@ int main(int argc, char *argv[]) {
}
}
- if (arg_output == OUTPUT_JSON)
- fputs("\n]\n", stdout);
-
finish:
if (j)
sd_journal_close(j);
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 67b2056..d60e5e5 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -76,7 +76,7 @@ static bool shall_print(bool show_all, char *p, size_t l) {
return true;
}
-static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
+static int output_short(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns,
OutputFlags flags) {
int r;
const void *data;
@@ -152,7 +152,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
if (priority_len == 1 && *priority >= '0' && *priority <= '7')
p = *priority - '0';
- if (flags & OUTPUT_MONOTONIC_MODE) {
+ if (mode == OUTPUT_SHORT_MONOTONIC) {
uint64_t t;
sd_id128_t boot_id;
@@ -278,17 +278,7 @@ finish:
return r;
}
-static int output_short_realtime(sd_journal *j, unsigned line,
- unsigned n_columns, OutputFlags flags) {
- return output_short(j, line, n_columns, flags & ~OUTPUT_MONOTONIC_MODE);
-}
-
-static int output_short_monotonic(sd_journal *j, unsigned line,
- unsigned n_columns, OutputFlags flags) {
- return output_short(j, line, n_columns, flags | OUTPUT_MONOTONIC_MODE);
-}
-
-static int output_verbose(sd_journal *j, unsigned line,
+static int output_verbose(sd_journal *j, OutputMode mode, unsigned line,
unsigned n_columns, OutputFlags flags) {
const void *data;
size_t length;
@@ -340,7 +330,7 @@ static int output_verbose(sd_journal *j, unsigned line,
return 0;
}
-static int output_export(sd_journal *j, unsigned line,
+static int output_export(sd_journal *j, OutputMode mode, unsigned line,
unsigned n_columns, OutputFlags flags) {
sd_id128_t boot_id;
char sid[33];
@@ -452,7 +442,7 @@ static void json_escape(const char* p, size_t l) {
}
}
-static int output_json(sd_journal *j, unsigned line,
+static int output_json(sd_journal *j, OutputMode mode, unsigned line,
unsigned n_columns, OutputFlags flags) {
uint64_t realtime, monotonic;
char *cursor;
@@ -482,21 +472,25 @@ static int output_json(sd_journal *j, unsigned line,
return r;
}
- if (line == 1)
- fputc('\n', stdout);
+ if (mode == OUTPUT_JSON_PRETTY)
+ printf("{\n"
+ "\t\"__CURSOR\" : \"%s\",\n"
+ "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
+ "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
+ "\t\"_BOOT_ID\" : \"%s\"",
+ cursor,
+ (unsigned long long) realtime,
+ (unsigned long long) monotonic,
+ sd_id128_to_string(boot_id, sid));
else
- fputs(",\n", stdout);
-
- printf("{\n"
- "\t\"__CURSOR\" : \"%s\",\n"
- "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
- "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
- "\t\"_BOOT_ID\" : \"%s\"",
- cursor,
- (unsigned long long) realtime,
- (unsigned long long) monotonic,
- sd_id128_to_string(boot_id, sid));
-
+ printf("{ \"__CURSOR\" : \"%s\", "
+ "\"__REALTIME_TIMESTAMP\" : \"%llu\", "
+ "\"__MONOTONIC_TIMESTAMP\" : \"%llu\", "
+ "\"_BOOT_ID\" : \"%s\"",
+ cursor,
+ (unsigned long long) realtime,
+ (unsigned long long) monotonic,
+ sd_id128_to_string(boot_id, sid));
free(cursor);
SD_JOURNAL_FOREACH_DATA(j, data, length) {
@@ -514,18 +508,25 @@ static int output_json(sd_journal *j, unsigned line,
return -EINVAL;
}
- fputs(",\n\t", stdout);
+ if (mode == OUTPUT_JSON_PRETTY)
+ fputs(",\n\t", stdout);
+ else
+ fputs(", ", stdout);
+
json_escape(data, c - (const char*) data);
fputs(" : ", stdout);
json_escape(c + 1, length - (c - (const char*) data) - 1);
}
- fputs("\n}", stdout);
+ if (mode == OUTPUT_JSON_PRETTY)
+ fputs("\n}\n", stdout);
+ else
+ fputs(" }\n", stdout);
return 0;
}
-static int output_cat(sd_journal *j, unsigned line,
+static int output_cat(sd_journal *j, OutputMode mode, unsigned line,
unsigned n_columns, OutputFlags flags) {
const void *data;
size_t l;
@@ -547,13 +548,14 @@ static int output_cat(sd_journal *j, unsigned line,
return 0;
}
-static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line,
+static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, OutputMode mode, unsigned line,
unsigned n_columns, OutputFlags flags) = {
- [OUTPUT_SHORT] = output_short_realtime,
- [OUTPUT_SHORT_MONOTONIC] = output_short_monotonic,
+ [OUTPUT_SHORT] = output_short,
+ [OUTPUT_SHORT_MONOTONIC] = output_short,
[OUTPUT_VERBOSE] = output_verbose,
[OUTPUT_EXPORT] = output_export,
[OUTPUT_JSON] = output_json,
+ [OUTPUT_JSON_PRETTY] = output_json,
[OUTPUT_CAT] = output_cat
};
@@ -566,7 +568,7 @@ int output_journal(sd_journal *j, OutputMode mode, unsigned line,
if (n_columns <= 0)
n_columns = columns();
- ret = output_funcs[mode](j, line, n_columns, flags);
+ ret = output_funcs[mode](j, mode, line, n_columns, flags);
fflush(stdout);
return ret;
}
@@ -736,6 +738,7 @@ static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
[OUTPUT_VERBOSE] = "verbose",
[OUTPUT_EXPORT] = "export",
[OUTPUT_JSON] = "json",
+ [OUTPUT_JSON_PRETTY] = "json-pretty",
[OUTPUT_CAT] = "cat"
};
diff --git a/src/shared/logs-show.h b/src/shared/logs-show.h
index 58ff9e5..3e6b6e0 100644
--- a/src/shared/logs-show.h
+++ b/src/shared/logs-show.h
@@ -33,6 +33,7 @@ typedef enum OutputMode {
OUTPUT_VERBOSE,
OUTPUT_EXPORT,
OUTPUT_JSON,
+ OUTPUT_JSON_PRETTY,
OUTPUT_CAT,
_OUTPUT_MODE_MAX,
_OUTPUT_MODE_INVALID = -1
@@ -40,11 +41,10 @@ typedef enum OutputMode {
typedef enum OutputFlags {
OUTPUT_SHOW_ALL = 1 << 0,
- OUTPUT_MONOTONIC_MODE = 1 << 1,
- OUTPUT_FOLLOW = 1 << 2,
- OUTPUT_WARN_CUTOFF = 1 << 3,
- OUTPUT_FULL_WIDTH = 1 << 4,
- OUTPUT_COLOR = 1 << 5
+ OUTPUT_FOLLOW = 1 << 1,
+ OUTPUT_WARN_CUTOFF = 1 << 2,
+ OUTPUT_FULL_WIDTH = 1 << 3,
+ OUTPUT_COLOR = 1 << 4
} OutputFlags;
int output_journal(sd_journal *j, OutputMode mode, unsigned line,
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 2481849..871a04b 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3871,7 +3871,7 @@ static int systemctl_help(void) {
" -n --lines=INTEGER Journal entries to show\n"
" --follow Follow journal\n"
" -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, cat)\n\n"
+ " verbose, export, json, json-pretty, cat)\n\n"
"Unit Commands:\n"
" list-units List loaded units\n"
" start [NAME...] Start (activate) one or more units\n"
commit 04bc4a3f47074d22035831965e97b0990fcf6f63
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 14:39:16 2012 -0700
nspawn: generate a new randomized boot ID for each container
diff --git a/TODO b/TODO
index be301e2..92d709e 100644
--- a/TODO
+++ b/TODO
@@ -80,16 +80,12 @@ Features:
* tmpfiles: skip mknod if CAP_MKNOD is missing
-* fake boot id
-
* bind mount read-only the cgroup tree higher than than nspawn
* currently system services appear not to generate core dumps...
* introduce /run/kmsg in containers?
-* introduce $container_boot_id?
-
* wall messages for shutdown should move to logind
* allow writing multiple conditions in unit files on one line
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ed72c3e..8765b01 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -337,7 +337,8 @@ static int setup_timezone(const char *dest) {
assert(dest);
/* Fix the timezone, if possible */
- if (asprintf(&where, "%s/etc/localtime", dest) < 0)
+ where = strappend(dest, "/etc/localtime");
+ if (!where)
return log_oom();
if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0)
@@ -345,7 +346,8 @@ static int setup_timezone(const char *dest) {
free(where);
- if (asprintf(&where, "%s/etc/timezone", dest) < 0)
+ where = strappend(dest, "/etc/timezone");
+ if (!where)
return log_oom();
if (mount("/etc/timezone", where, "bind", MS_BIND, NULL) >= 0)
@@ -365,9 +367,9 @@ static int setup_resolv_conf(const char *dest) {
return 0;
/* Fix resolv.conf, if possible */
- if (asprintf(&where, "%s/etc/resolv.conf", dest) < 0) {
+ where = strappend(dest, "/etc/resolv.conf");
+ if (!where)
return log_oom();
- }
if (mount("/etc/resolv.conf", where, "bind", MS_BIND, NULL) >= 0)
mount("/etc/resolv.conf", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
@@ -377,6 +379,61 @@ static int setup_resolv_conf(const char *dest) {
return 0;
}
+static int setup_boot_id(const char *dest) {
+ char *from = NULL, *to = NULL;
+ sd_id128_t rnd;
+ char as_uuid[37];
+ int r;
+
+ assert(dest);
+
+ /* Generate a new randomized boot ID, so that each boot-up of
+ * the container gets a new one */
+
+ from = strappend(dest, "/dev/proc-sys-kernel-random-boot-id");
+ if (!from) {
+ r = log_oom();
+ goto finish;
+ }
+
+ to = strappend(dest, "/proc/sys/kernel/random/boot_id");
+ if (!to) {
+ r = log_oom();
+ goto finish;
+ }
+
+ r = sd_id128_randomize(&rnd);
+ if (r < 0) {
+ log_error("Failed to generate random boot id: %s", strerror(-r));
+ goto finish;
+ }
+
+ snprintf(as_uuid, sizeof(as_uuid),
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ SD_ID128_FORMAT_VAL(rnd));
+ char_array_0(as_uuid);
+
+ r = write_one_line_file(from, as_uuid);
+ if (r < 0) {
+ log_error("Failed to write boot id: %s", strerror(-r));
+ goto finish;
+ }
+
+ if (mount(from, to, "bind", MS_BIND, NULL) < 0) {
+ log_error("Failed to bind mount boot id: %m");
+ r = -errno;
+ } else
+ mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL);
+
+ unlink(from);
+
+finish:
+ free(from);
+ free(to);
+
+ return r;
+}
+
static int copy_devnodes(const char *dest) {
static const char devnodes[] =
@@ -1218,6 +1275,9 @@ int main(int argc, char *argv[]) {
close_nointr_nofail(kmsg_socket_pair[1]);
+ if (setup_boot_id(arg_directory) < 0)
+ goto child_fail;
+
if (setup_timezone(arg_directory) < 0)
goto child_fail;
commit 9c1c7f712d8270c4f6bd8141d0b1acb1f031fa08
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Sep 5 14:16:41 2012 -0700
nspawn: if a file system comes pre-mounted, still do the read-only remounts
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 4aa877d..ed72c3e 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -306,7 +306,8 @@ static int mount_all(const char *dest) {
continue;
}
- if (t > 0)
+ /* Skip this entry if it is not a remount. */
+ if (mount_table[k].what && t > 0)
continue;
mkdir_p_label(where, 0755);
More information about the systemd-commits
mailing list