Sophie

Sophie

distrib > Fedora > 17 > x86_64 > by-pkgid > ab4b662b9827b6375ffd451bf4abd615 > files > 226

systemd-44-24.fc17.src.rpm

From 8093ef8c08bac27211290f362ed05ea3afd0cc3c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 25 Apr 2012 15:11:20 +0200
Subject: [PATCH] nspawn: add --read-only switch (cherry picked from commit
 bc2f673ec24b59948fcfc35b3077fda0314e69d8)

---
 man/systemd-nspawn.xml |    8 ++++++++
 src/nspawn/nspawn.c    |   28 ++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index f089e14..7bc5d79 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -198,6 +198,14 @@
                                 loopback device.</para></listitem>
                         </varlistentry>
 
+                        <varlistentry>
+                                <term><option>--read-only</option></term>
+
+                                <listitem><para>Mount the root file
+                                system read only for the
+                                container.</para></listitem>
+                        </varlistentry>
+
                 </variablelist>
 
         </refsect1>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 4b77a91..9fa7592 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -57,6 +57,7 @@ static char *arg_user = NULL;
 static char **arg_controllers = NULL;
 static char *arg_uuid = NULL;
 static bool arg_private_network = false;
+static bool arg_read_only = false;
 static bool arg_boot = false;
 
 static int help(void) {
@@ -69,7 +70,8 @@ static int help(void) {
                "  -u --user=USER        Run the command under specified user or uid\n"
                "  -C --controllers=LIST Put the container in specified comma-separated cgroup hierarchies\n"
                "     --uuid=UUID        Set a specific machine UUID for the container\n"
-               "     --private-network  Disable network in container\n",
+               "     --private-network  Disable network in container\n"
+               "     --read-only        Mount the root directory read-only\n",
                program_invocation_short_name);
 
         return 0;
@@ -79,7 +81,8 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_PRIVATE_NETWORK = 0x100,
-                ARG_UUID
+                ARG_UUID,
+                ARG_READ_ONLY
         };
 
         static const struct option options[] = {
@@ -90,6 +93,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "private-network", no_argument,       NULL, ARG_PRIVATE_NETWORK },
                 { "boot",            no_argument,       NULL, 'b'                 },
                 { "uuid",            required_argument, NULL, ARG_UUID            },
+                { "read-only",       no_argument,       NULL, ARG_READ_ONLY       },
                 { NULL,              0,                 NULL, 0                   }
         };
 
@@ -148,6 +152,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_uuid = optarg;
                         break;
 
+                case ARG_READ_ONLY:
+                        arg_read_only = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -971,6 +979,18 @@ int main(int argc, char *argv[]) {
                 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0)
                         goto child_fail;
 
+                /* Turn directory into bind mount */
+                if (mount(arg_directory, arg_directory, "bind", MS_BIND, NULL) < 0) {
+                        log_error("Failed to make bind mount.");
+                        goto child_fail;
+                }
+
+                if (arg_read_only)
+                        if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
+                                log_error("Failed to make read-only.");
+                                goto child_fail;
+                        }
+
                 if (mount_all(arg_directory) < 0)
                         goto child_fail;
 
@@ -1001,8 +1021,8 @@ int main(int argc, char *argv[]) {
                     dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
                         goto child_fail;
 
-                if (mount(arg_directory, "/", "bind", MS_BIND, NULL) < 0) {
-                        log_error("mount(MS_MOVE) failed: %m");
+                if (mount(arg_directory, "/", "bind", MS_MOVE, NULL) < 0) {
+                        log_error("mount(MS_BIND) failed: %m");
                         goto child_fail;
                 }