[systemd-commits] 7 commits - man/systemd.unit.xml src/core src/journal src/load-fragment-gperf.gperf.m4 src/main.c src/nspawn.c src/shared units/systemd-sysctl.service.in units/systemd-vconsole-setup.service.in

Lennart Poettering lennart at kemper.freedesktop.org
Thu Apr 12 03:59:13 PDT 2012


 man/systemd.unit.xml                    |   22 +++++++++++++++-------
 src/core/condition.c                    |   11 +++++++++++
 src/core/condition.h                    |    1 +
 src/core/execute.c                      |    2 +-
 src/journal/journald.c                  |    2 +-
 src/load-fragment-gperf.gperf.m4        |    1 +
 src/main.c                              |   19 ++++++++++---------
 src/nspawn.c                            |    8 +++++++-
 src/shared/util.c                       |   24 ++++++++++++++++++++++++
 src/shared/util.h                       |    3 +++
 units/systemd-sysctl.service.in         |    1 +
 units/systemd-vconsole-setup.service.in |    1 +
 12 files changed, 76 insertions(+), 19 deletions(-)

New commits:
commit 68fb08920b2162b48cf0fa8dd98b021327b42896
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 12:58:08 2012 +0200

    nspawn: bind mount /dev/nul to /proc/kmsg, so that the container can't muck with the host kmsg

diff --git a/src/nspawn.c b/src/nspawn.c
index 7b65e98..685b4d4 100644
--- a/src/nspawn.c
+++ b/src/nspawn.c
@@ -184,7 +184,8 @@ static int mount_all(const char *dest) {
                         break;
                 }
 
-                if ((t = path_is_mount_point(where, false)) < 0) {
+                t = path_is_mount_point(where, false);
+                if (t < 0) {
                         log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t));
                         free(where);
 
@@ -229,6 +230,11 @@ static int mount_all(const char *dest) {
                 free(where);
         }
 
+        if (asprintf(&where, "%s/proc/kmsg", dest) >= 0) {
+                mount("/dev/null", where, "bind", MS_BIND, NULL);
+                free(where);
+        }
+
         return r;
 }
 

commit 2abf99ac076299d80ed595fa4ae5cc46bb455975
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 12:57:41 2012 +0200

    journald: add missing flag to open()

diff --git a/src/journal/journald.c b/src/journal/journald.c
index 1549e6e..2e2d30f 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -2480,7 +2480,7 @@ static int open_proc_kmsg(Server *s) {
                 return 0;
 
 
-        s->proc_kmsg_fd = open("/proc/kmsg", O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        s->proc_kmsg_fd = open("/proc/kmsg", O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
         if (s->proc_kmsg_fd < 0) {
                 log_warning("Failed to open /proc/kmsg, ignoring: %m");
                 return 0;

commit 68faf98ca09314b61314ad2ac0cc133c400a83f9
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 03:38:52 2012 +0200

    execute: when we can't get the requested rlimit, get the next closest

diff --git a/src/core/execute.c b/src/core/execute.c
index 8ae3923..271c57f 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1367,7 +1367,7 @@ int exec_spawn(ExecCommand *command,
                                 if (!context->rlimit[i])
                                         continue;
 
-                                if (setrlimit(i, context->rlimit[i]) < 0) {
+                                if (setrlimit_closest(i, context->rlimit[i]) < 0) {
                                         err = -errno;
                                         r = EXIT_LIMITS;
                                         goto fail_child;
diff --git a/src/shared/util.c b/src/shared/util.c
index a3873a9..0b4d4d6 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6120,3 +6120,27 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
         execv(path, l);
         _exit(EXIT_FAILURE);
 }
+
+int setrlimit_closest(int resource, const struct rlimit *rlim) {
+        struct rlimit highest, fixed;
+
+        assert(rlim);
+
+        if (setrlimit(resource, rlim) >= 0)
+                return 0;
+
+        if (errno != EPERM)
+                return -errno;
+
+        /* So we failed to set the desired setrlimit, then let's try
+         * to get as close as we can */
+        assert_se(getrlimit(resource, &highest) == 0);
+
+        fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
+        fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
+
+        if (setrlimit(resource, &fixed) < 0)
+                return -errno;
+
+        return 0;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index 3f4e49e..c487b70 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -34,6 +34,7 @@
 #include <limits.h>
 #include <sys/stat.h>
 #include <dirent.h>
+#include <sys/resource.h>
 
 #include "macro.h"
 
@@ -531,4 +532,6 @@ int fd_inc_rcvbuf(int fd, size_t n);
 
 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
 
+int setrlimit_closest(int resource, const struct rlimit *rlim);
+
 #endif

commit d18f337c3f2fe14240598c18415f72d0cf15393f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 03:19:28 2012 +0200

    main: pass original environment block to shutdown binary so that it can detect container environments

diff --git a/src/main.c b/src/main.c
index 8c115bd..f03b959 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1648,19 +1648,16 @@ finish:
                 fdset_free(fds);
 
         if (shutdown_verb) {
-                char e[32];
-
                 const char * command_line[] = {
                         SYSTEMD_SHUTDOWN_BINARY_PATH,
                         shutdown_verb,
                         NULL
                 };
-                const char * env_block[] = {
-                        NULL,
-                        NULL
-                };
+                char **env_block;
 
                 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
+                        char e[32];
+
                         /* If we reboot let's set the shutdown
                          * watchdog and tell the shutdown binary to
                          * repeatedly ping it */
@@ -1670,11 +1667,15 @@ finish:
                         /* Tell the binary how often to ping */
                         snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
                         char_array_0(e);
-                        env_block[0] = e;
-                } else
+
+                        env_block = strv_append(environ, e);
+                } else {
+                        env_block = strv_copy(environ);
                         watchdog_close(true);
+                }
 
-                execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, (char**) env_block);
+                execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
+                free(env_block);
                 log_error("Failed to execute shutdown binary, freezing: %m");
         }
 

commit 1d7f3f5cc80434f363e2f1e8284324d317c3faf4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 02:51:16 2012 +0200

    units: start vconsole-setup only if there's actually a virtual console device

diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in
index ef222a5..1420ce8 100644
--- a/units/systemd-vconsole-setup.service.in
+++ b/units/systemd-vconsole-setup.service.in
@@ -11,6 +11,7 @@ DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=sysinit.target shutdown.target
+ConditionPathExists=/dev/tty0
 
 [Service]
 Type=oneshot

commit f2a46f8da51aeab1a34dd250e8ac48f2465bf095
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 02:41:02 2012 +0200

    units: run sysctl stuff only when /proc/sys is actually writable, to quieten container boots a little

diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in
index 692fa3b..d38f026 100644
--- a/units/systemd-sysctl.service.in
+++ b/units/systemd-sysctl.service.in
@@ -11,6 +11,7 @@ DefaultDependencies=no
 Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=sysinit.target shutdown.target
+ConditionPathIsReadWrite=/proc/sys/
 ConditionPathExists=|/etc/sysctl.conf
 ConditionDirectoryNotEmpty=|/lib/sysctl.d
 ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d

commit d051610953754ce2b79d23b83c1d5c167defd5be
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 12 02:39:02 2012 +0200

    unit: introduce ConditionPathIsReadWrite

diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 3fc7f78..28ca8ce 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -684,6 +684,7 @@
                                 <term><varname>ConditionPathIsDirectory=</varname></term>
                                 <term><varname>ConditionPathIsSymbolicLink=</varname></term>
                                 <term><varname>ConditionPathIsMountPoint=</varname></term>
+                                <term><varname>ConditionPathIsReadWrite=</varname></term>
                                 <term><varname>ConditionDirectoryNotEmpty=</varname></term>
                                 <term><varname>ConditionFileIsExecutable=</varname></term>
                                 <term><varname>ConditionKernelCommandLine=</varname></term>
@@ -731,7 +732,13 @@
                                 <varname>ConditionPathExists=</varname>
                                 but verifies whether a certain path
                                 exists and is a mount
-                                point. <varname>ConditionFileIsExecutable=</varname>
+                                point. <varname>ConditionPathIsReadWrite=</varname>
+                                is similar to
+                                <varname>ConditionPathExists=</varname>
+                                but verifies whether the underlying
+                                file system is read and writable
+                                (i.e. not mounted
+                                read-only). <varname>ConditionFileIsExecutable=</varname>
                                 is similar to
                                 <varname>ConditionPathExists=</varname>
                                 but verifies whether a certain path
@@ -780,12 +787,13 @@
                                 <varname>openvz</varname>,
                                 <varname>lxc</varname>,
                                 <varname>lxc-libvirt</varname>,
-                                <varname>systemd-nspawn</varname> to test
-                                against a specific implementation. If
-                                multiple virtualization technologies
-                                are nested only the innermost is
-                                considered. The test may be negated by
-                                prepending an exclamation mark.
+                                <varname>systemd-nspawn</varname> to
+                                test against a specific
+                                implementation. If multiple
+                                virtualization technologies are nested
+                                only the innermost is considered. The
+                                test may be negated by prepending an
+                                exclamation mark.
                                 <varname>ConditionSecurity=</varname>
                                 may be used to check whether the given
                                 security module is enabled on the
diff --git a/src/core/condition.c b/src/core/condition.c
index 5dad524..3b246f1 100644
--- a/src/core/condition.c
+++ b/src/core/condition.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/capability.h>
+#include <sys/statvfs.h>
 
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
@@ -222,6 +223,15 @@ bool condition_test(Condition *c) {
         case CONDITION_PATH_IS_MOUNT_POINT:
                 return (path_is_mount_point(c->parameter, true) > 0) == !c->negate;
 
+        case CONDITION_PATH_IS_READ_WRITE: {
+                struct statvfs st;
+
+                if (statvfs(c->parameter, &st) < 0)
+                        return c->negate;
+
+                return !(st.f_flag & ST_RDONLY) == !c->negate;
+        }
+
         case CONDITION_DIRECTORY_NOT_EMPTY: {
                 int k;
 
@@ -313,6 +323,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory",
         [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink",
         [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint",
+        [CONDITION_PATH_IS_READ_WRITE] = "ConditionPathIsReadWrite",
         [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
         [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine",
         [CONDITION_VIRTUALIZATION] = "ConditionVirtualization",
diff --git a/src/core/condition.h b/src/core/condition.h
index 2a44ba6..2d1f2cd 100644
--- a/src/core/condition.h
+++ b/src/core/condition.h
@@ -32,6 +32,7 @@ typedef enum ConditionType {
         CONDITION_PATH_IS_DIRECTORY,
         CONDITION_PATH_IS_SYMBOLIC_LINK,
         CONDITION_PATH_IS_MOUNT_POINT,
+        CONDITION_PATH_IS_READ_WRITE,
         CONDITION_DIRECTORY_NOT_EMPTY,
         CONDITION_FILE_IS_EXECUTABLE,
         CONDITION_KERNEL_COMMAND_LINE,
diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4
index 4b02e31..c65db30 100644
--- a/src/load-fragment-gperf.gperf.m4
+++ b/src/load-fragment-gperf.gperf.m4
@@ -118,6 +118,7 @@ Unit.ConditionPathExistsGlob,    config_parse_unit_condition_path,   CONDITION_P
 Unit.ConditionPathIsDirectory,   config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY,   0
 Unit.ConditionPathIsSymbolicLink,config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK,0
 Unit.ConditionPathIsMountPoint,  config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT, 0
+Unit.ConditionPathIsReadWrite,   config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE,  0
 Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, 0
 Unit.ConditionFileIsExecutable,  config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  0
 Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0



More information about the systemd-commits mailing list