loolwsd/LOOLKit.cpp |   61 +++++++++++++++++++++++++++++++++++++++++++---------
 loolwsd/Makefile.am |    5 +++-
 loolwsd/loolmount.c |   30 +++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 11 deletions(-)

New commits:
commit 1b25179b25992f78600b7b102d6cdc890ce6c1a3
Author: Michael Meeks <michael.me...@collabora.com>
Date:   Sat Apr 2 19:17:22 2016 +0100

    Use bind mounting to accelerate jail creation.
    
    of the 10k files still linked into the jail; 5700 are from usr/
    so bind mount just that directory, also set noatime, ro, and
    some other helpful looking options.
    
    Change-Id: I28d2d5cbbdf33fb57ea0f0c0915cb267603ee16d
    Reviewed-on: https://gerrit.libreoffice.org/23777
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index 23c498f..d6a0334 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -76,9 +76,33 @@ static int writerNotify = -1;
 
 namespace
 {
+    typedef enum { COPY_ALL, COPY_LO, COPY_NO_USR } LinkOrCopyType;
+    LinkOrCopyType linkOrCopyType;
     std::string sourceForLinkOrCopy;
     Path destinationForLinkOrCopy;
 
+    bool shouldCopyDir(const char *path)
+    {
+        switch (linkOrCopyType)
+        {
+        case COPY_NO_USR:
+            // bind mounted.
+            return strcmp(path,"usr");
+        case COPY_LO:
+            return
+                strcmp(path, "program/wizards") &&
+                strcmp(path, "sdk") &&
+                strcmp(path, "share/basic") &&
+                strcmp(path, "share/gallery") &&
+                strcmp(path, "share/Scripts") &&
+                strcmp(path, "share/template") &&
+                strcmp(path, "share/config/wizard") &&
+                strcmp(path, "share/config/wizard");
+        default: // COPY_ALL
+            return true;
+        }
+    }
+
     int linkOrCopyFunction(const char *fpath,
                            const struct stat* /*sb*/,
                            int typeflag,
@@ -110,13 +134,7 @@ namespace
                     Log::error("Error: stat(\"" + std::string(fpath) + "\") 
failed.");
                     return 1;
                 }
-                if (!strcmp(relativeOldPath, "program/wizards") ||
-                    !strcmp(relativeOldPath, "sdk") ||
-                    !strcmp(relativeOldPath, "share/gallery") ||
-                    !strcmp(relativeOldPath, "share/Scripts") ||
-                    !strcmp(relativeOldPath, "share/template") ||
-                    !strcmp(relativeOldPath, "share/config/wizard") ||
-                    !strcmp(relativeOldPath, "share/config/wizard"))
+                if (!shouldCopyDir(relativeOldPath))
                 {
                     Log::debug("skip redundant paths " + 
std::string(relativeOldPath));
                     return FTW_SKIP_SUBTREE;
@@ -149,8 +167,11 @@ namespace
         return 0;
     }
 
-    void linkOrCopy(const std::string& source, const Path& destination)
+    void linkOrCopy(const std::string& source,
+                    const Path& destination,
+                    LinkOrCopyType type)
     {
+        linkOrCopyType = type;
         sourceForLinkOrCopy = source;
         if (sourceForLinkOrCopy.back() == '/')
             sourceForLinkOrCopy.pop_back();
@@ -902,8 +923,26 @@ void lokit_main(const std::string& childRoot,
         File(jailLOInstallation).createDirectory();
 
         // Copy (link) LO installation and other necessary files into it from 
the template.
-        linkOrCopy(sysTemplate, jailPath);
-        linkOrCopy(loTemplate, jailLOInstallation);
+        bool bLoopMounted = false;
+        if (getenv("LOOL_BIND_MOUNT"))
+        {
+            Path usrSrcPath(sysTemplate, "usr");
+            Path usrDestPath(jailPath, "usr");
+            File(usrDestPath).createDirectory();
+            std::string mountCommand =
+                std::string("loolmount ") +
+                usrSrcPath.toString() +
+                std::string(" ") +
+                usrDestPath.toString();
+            Log::debug("Initializing jail bind mount.");
+            bLoopMounted = !system(mountCommand.c_str());
+            Log::debug("Initialized jail bind mount.");
+        }
+        linkOrCopy(sysTemplate, jailPath,
+                   bLoopMounted ? COPY_NO_USR : COPY_ALL);
+        linkOrCopy(loTemplate, jailLOInstallation, COPY_LO);
+
+        Log::debug("Initialized jail files.");
 
         // We need this because sometimes the hostname is not resolved
         const std::vector<std::string> networkFiles = {"/etc/host.conf", 
"/etc/hosts", "/etc/nsswitch.conf", "/etc/resolv.conf"};
@@ -949,6 +988,8 @@ void lokit_main(const std::string& childRoot,
         dropCapability(CAP_MKNOD);
         dropCapability(CAP_FOWNER);
 
+        Log::debug("Initialized jail nodes, dropped caps.");
+
         loKit = lok_init_2(instdir_path.c_str(), "file:///user");
         if (loKit == nullptr)
         {
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index f3f5662..7056792 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -1,6 +1,6 @@
 SUBDIRS = test
 
-bin_PROGRAMS = loolwsd loolbroker loolkit loolmap
+bin_PROGRAMS = loolwsd loolbroker loolkit loolmap loolmount
 
 dist_bin_SCRIPTS = loolwsd-systemplate-setup discovery.xml
 
@@ -53,6 +53,8 @@ loolkit_SOURCES = LOOLKit.cpp \
 loolbroker_SOURCES = LOOLBroker.cpp \
                      $(broker_shared_sources)
 
+loolmount_SOURCES = loolmount.c
+
 loolmap_SOURCES = loolmap.c
 
 noinst_HEADERS = Admin.hpp \
@@ -100,6 +102,7 @@ all-local: loolbroker loolkit certificates
        if test "$$BUILDING_FROM_RPMBUILD" != yes; then \
            sudo @SETCAP@ cap_fowner,cap_mknod,cap_sys_chroot=ep loolbroker; \
            sudo @SETCAP@ cap_fowner,cap_mknod,cap_sys_chroot=ep loolkit; \
+           sudo @SETCAP@ cap_sys_admin=ep loolmount; \
            echo "Set required capabilities"; \
        else \
            echo "Skipping capability setting"; \
diff --git a/loolwsd/loolmount.c b/loolwsd/loolmount.c
new file mode 100644
index 0000000..ceadeec
--- /dev/null
+++ b/loolwsd/loolmount.c
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/*
+ * This is a trivial helper to allow bind mounting.
+ */
+
+#include <sys/mount.h>
+
+int main(int argc, char **argv)
+{
+    if (argc < 3)
+        return 1;
+
+    int retval = mount (argv[1], argv[2], 0, MS_BIND, 0);
+    if (retval)
+        return retval;
+
+    // apparently this has to be done in a 2nd pass.
+    return mount(argv[1], argv[2], 0,
+                 (MS_BIND | MS_REMOUNT | MS_NOATIME | MS_NODEV |
+                  MS_NOSUID | MS_RDONLY  | MS_SILENT), 0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to