[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