[systemd-commits] NEWS man/systemd-nspawn.xml src/nspawn src/shared

Lennart Poettering lennart at kemper.freedesktop.org
Tue Feb 18 23:38:04 CET 2014


 NEWS                   |    4 ++++
 man/systemd-nspawn.xml |   18 ++++++++++++++++++
 src/nspawn/nspawn.c    |   21 +++++++++++++++++++++
 src/shared/util.c      |   30 ++++++++++++++++++++++++++++++
 src/shared/util.h      |    2 ++
 5 files changed, 75 insertions(+)

New commits:
commit 6afc95b73605833e6e966af1c466b5c08feb953f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Feb 18 23:35:19 2014 +0100

    nspawn: add new --personality= switch to make it easier to run 32bit containers on a 64bit host

diff --git a/NEWS b/NEWS
index b40d369..c240d11 100644
--- a/NEWS
+++ b/NEWS
@@ -379,6 +379,10 @@ CHANGES WITH 209:
           switch then allows assigning the host side of this virtual
           Ethernet connection to a bridge device.
 
+        * systemd-nspawn gained a new --personality= switch for
+          setting the kernel personality for the container. This is
+          useful when running a 32bit container on a 64bit host.
+
         * logind will now also track a "Desktop" identifier for each
           session which encodes the desktop environment of it. This is
           useful for desktop environments that want to identify
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index b34d38c..6518eb8 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -555,6 +555,24 @@
                                 session.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--personality=</option></term>
+
+                                <listitem><para>Control the
+                                architecture ("personality") reported
+                                by
+                                <citerefentry><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+                                in the container. Currently, only
+                                <literal>x86</literal> and
+                                <literal>x86-64</literal> are
+                                supported. This is useful when running
+                                a 32bit container on a 64bit
+                                host. If this setting is not used
+                                the personality reported in the
+                                container is the same as the one
+                                reported on the
+                                host.</para></listitem>
+                        </varlistentry>
                 </variablelist>
 
         </refsect1>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 379ea92..98e90fe 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -43,6 +43,7 @@
 #include <sys/eventfd.h>
 #include <net/if.h>
 #include <linux/veth.h>
+#include <sys/personality.h>
 
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
@@ -138,6 +139,7 @@ static bool arg_keep_unit = false;
 static char **arg_network_interfaces = NULL;
 static bool arg_network_veth = false;
 static char *arg_network_bridge = NULL;
+static unsigned long arg_personality = 0xffffffffLU;
 
 static int help(void) {
 
@@ -206,6 +208,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NETWORK_INTERFACE,
                 ARG_NETWORK_VETH,
                 ARG_NETWORK_BRIDGE,
+                ARG_PERSONALITY,
         };
 
         static const struct option options[] = {
@@ -234,6 +237,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "network-interface",     required_argument, NULL, ARG_NETWORK_INTERFACE },
                 { "network-veth",          no_argument,       NULL, ARG_NETWORK_VETH      },
                 { "network-bridge",        required_argument, NULL, ARG_NETWORK_BRIDGE    },
+                { "personality",           required_argument, NULL, ARG_PERSONALITY       },
                 {}
         };
 
@@ -474,6 +478,16 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_keep_unit = true;
                         break;
 
+                case ARG_PERSONALITY:
+
+                        arg_personality = parse_personality(optarg);
+                        if (arg_personality == 0xffffffffLU) {
+                                log_error("Unknown or unsupported personality '%s'.", optarg);
+                                return -EINVAL;
+                        }
+
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1983,6 +1997,13 @@ int main(int argc, char *argv[]) {
 
                         setup_hostname();
 
+                        if (arg_personality != 0xffffffffLU) {
+                                if (personality(arg_personality) < 0) {
+                                        log_error("personality() failed: %m");
+                                        goto child_fail;
+                                }
+                        }
+
                         eventfd_read(sync_fd, &x);
                         close_nointr_nofail(sync_fd);
                         sync_fd = -1;
diff --git a/src/shared/util.c b/src/shared/util.c
index 72b1e2f..99658f0 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -58,6 +58,7 @@
 #include <limits.h>
 #include <langinfo.h>
 #include <locale.h>
+#include <sys/personality.h>
 #include <libgen.h>
 #undef basename
 
@@ -6192,3 +6193,32 @@ int fd_warn_permissions(const char *path, int fd) {
 
         return 0;
 }
+
+unsigned long parse_personality(const char *p) {
+
+        /* Parse a personality specifier. We introduce our own
+         * identifiers that indicate specific ABIs, rather than just
+         * hints regarding the register size, since we want to keep
+         * things open for multiple locally supported ABIs for the
+         * same register size. We try to reuse the ABI identifiers
+         * used by libseccomp. */
+
+#if defined(__x86_64__)
+
+        if (streq(p, "x86"))
+                return PER_LINUX32;
+
+        if (streq(p, "x86-64"))
+                return PER_LINUX;
+
+#elif defined(__i386__)
+
+        if (streq(p, "x86"))
+                return PER_LINUX;
+#endif
+
+        /* personality(7) documents that 0xffffffffUL is used for
+         * querying the current personality, hence let's use that here
+         * as error indicator. */
+        return 0xffffffffUL;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index a41348e..e379c30 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -870,3 +870,5 @@ int mkostemp_safe(char *pattern, int flags);
 int open_tmpfile(const char *path, int flags);
 
 int fd_warn_permissions(const char *path, int fd);
+
+unsigned long parse_personality(const char *p);



More information about the systemd-commits mailing list