[M67 Dev][WRT][Perf] Add process pool feature 50/187850/3
authoryh106.jung <yh106.jung@samsung.com>
Tue, 6 Dec 2016 01:41:18 +0000 (10:41 +0900)
committerSungsik Han <ss440.han@samsung.com>
Wed, 10 Oct 2018 09:52:07 +0000 (09:52 +0000)
This adds process pool feature for web runtime.

Also, sometimes kZygoteCommandDropProcessPrivileges will be sent
between the operation to sent kZygoteCommandForkRealPID.
Now kZygoteCommandForkRealPID has been locked by |control_lock_|,
add the lock to prevent it from being interrupted.

Reference:
https://review.tizen.org/gerrit/#/c/173439
https://review.tizen.org/gerrit/#/c/189532

Change-Id: Ic0b23425a3c336d6fd65711532c9cc3f46f021e6
Signed-off-by: yh106.jung <yh106.jung@samsung.com>
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
content/browser/zygote_host/zygote_communication_linux.cc
content/browser/zygote_host/zygote_communication_linux.h
content/common/zygote_commands_linux.h
content/zygote/zygote_linux.cc
content/zygote/zygote_linux.h
packaging/chromium-efl.spec
tizen_src/build/BUILD.gn
tizen_src/chromium_impl/content/browser/browser_efl.gni
tizen_src/chromium_impl/content/content_efl.gni
tizen_src/ewk/efl_integration/eweb_context.cc

index f389aba..206a062 100644 (file)
@@ -320,4 +320,28 @@ int ZygoteCommunication::GetSandboxStatus() {
   return sandbox_status_;
 }
 
+#if defined(OS_TIZEN)
+void ZygoteCommunication::LoadInjectedBundlePath(
+    const std::string& injected_bundle_path) {
+  DCHECK(init_);
+  base::Pickle pickle;
+
+  pickle.WriteInt(kZygoteCommandLoadInjectedBundle);
+  pickle.WriteString(injected_bundle_path);
+  if (!SendMessage(pickle, NULL))
+    LOG(ERROR) << "Failed to send LoadInjectedBundlePath message to zygote";
+}
+
+void ZygoteCommunication::DropProcessPrivileges(const std::string& app_id) {
+  DCHECK(init_);
+  base::Pickle pickle;
+
+  pickle.WriteInt(kZygoteCommandDropProcessPrivileges);
+  pickle.WriteString(app_id);
+  base::AutoLock lock(control_lock_);
+  if (!SendMessage(pickle, NULL))
+    LOG(ERROR) << "Failed to send DropProcessPrivileges message to zygote";
+}
+#endif
+
 }  // namespace content
index 1318525..3a7051d 100644 (file)
@@ -66,6 +66,11 @@ class CONTENT_EXPORT ZygoteCommunication {
   // Returns the sandbox status of this zygote.
   int GetSandboxStatus();
 
+#if defined(OS_TIZEN)
+  void LoadInjectedBundlePath(const std::string& injected_bundle_path);
+  void DropProcessPrivileges(const std::string& app_id);
+#endif
+
  private:
   // Should be called every time a Zygote child is born.
   void ZygoteChildBorn(pid_t process);
index 24f3bf6..225e6f3 100644 (file)
@@ -46,7 +46,15 @@ enum {
 
   // Not a real zygote command, but a subcommand used during the zygote fork
   // protocol.  Sends the child's PID as seen from the browser process.
-  kZygoteCommandForkRealPID = 4
+  kZygoteCommandForkRealPID = 4,
+
+#if defined(OS_TIZEN)
+  // Load injected bundle library.
+  kZygoteCommandLoadInjectedBundle = 5,
+
+  // Drop privilege of zygote process.
+  kZygoteCommandDropProcessPrivileges = 6
+#endif
 };
 
 }  // namespace content
index 0f67102..b1fea01 100644 (file)
 #include "services/service_manager/sandbox/linux/sandbox_linux.h"
 #include "services/service_manager/sandbox/sandbox.h"
 #include "third_party/icu/source/i18n/unicode/timezone.h"
+#if defined(OS_TIZEN)
+#include <dlfcn.h>
+#include <security-manager/security-manager.h>
+#endif
 
 // See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_zygote.md
 
@@ -97,10 +101,18 @@ Zygote::Zygote(int sandbox_flags,
     : sandbox_flags_(sandbox_flags),
       helpers_(std::move(helpers)),
       initial_uma_index_(0),
+#if defined(OS_TIZEN)
+      injected_bundle_handle_(nullptr),
+#endif
       to_reap_(),
       ipc_backchannel_(ipc_backchannel) {}
 
-Zygote::~Zygote() {}
+Zygote::~Zygote() {
+#if defined(OS_TIZEN)
+  if (injected_bundle_handle_)
+    dlclose(injected_bundle_handle_);
+#endif
+}
 
 bool Zygote::ProcessRequests() {
   // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
@@ -278,6 +290,14 @@ bool Zygote::HandleRequestFromBrowser(int fd) {
         LOG(ERROR) << "Unexpected real PID message from browser";
         NOTREACHED();
         return false;
+#if defined(OS_TIZEN)
+      case kZygoteCommandLoadInjectedBundle:
+        HandleLoadInjectedBundle(fd, iter);
+        return false;
+      case kZygoteCommandDropProcessPrivileges:
+        HandleDropProcessPrivileges(fd, iter);
+        return false;
+#endif
       default:
         NOTREACHED();
         break;
@@ -665,4 +685,41 @@ bool Zygote::HandleGetSandboxStatus(int fd, base::PickleIterator iter) {
   return false;
 }
 
+#if defined(OS_TIZEN)
+typedef void (*DynamicPreloading)(void);
+void Zygote::HandleLoadInjectedBundle(int fd, base::PickleIterator iter) {
+  std::string injected_bundle_path;
+  if (!iter.ReadString(&injected_bundle_path))
+    return;
+
+  injected_bundle_handle_ = dlopen(injected_bundle_path.c_str(), RTLD_LAZY);
+  if (!injected_bundle_handle_) {
+    LOG(ERROR) << "No handle to " << injected_bundle_path.c_str() << " error "
+               << dlerror();
+    return;
+  }
+
+  DynamicPreloading dp = reinterpret_cast<DynamicPreloading>(
+      dlsym(injected_bundle_handle_, "DynamicPreloading"));
+  if (dp) {
+    dp();
+  } else {
+    LOG(ERROR) << "Fail to load symbol 'DynamicPreloading'"
+               << ", error " << dlerror();
+  }
+}
+
+void Zygote::HandleDropProcessPrivileges(int fd, base::PickleIterator iter) {
+  std::string app_id;
+  if (!iter.ReadString(&app_id))
+    return;
+
+  int error = security_manager_prepare_app(app_id.c_str());
+  if (error) {
+    LOG(ERROR) << "Fail on security_manager_prepare_app"
+               << ", error code " << error;
+  }
+}
+#endif
+
 }  // namespace content
index c86fed2..c752586 100644 (file)
@@ -127,6 +127,22 @@ class Zygote {
   // Attempt to reap all outstanding children in |to_reap_|.
   void ReapChildren();
 
+#if defined(OS_TIZEN)
+  // Get a library path from |iter|, and load it via dlopen().
+  // This step will reduce the launching time of
+  // actual web application launching.
+  // The loaded handle must be closed on termination.
+  void HandleLoadInjectedBundle(int fd, base::PickleIterator iter);
+
+  // Handle a 'drop privileges' request from the browser: this means
+  // that a new application will be launched and the browser
+  // will request a new renderer process. Thus before forking new process,
+  // zygote process should has restrict privileges.
+
+  // Get an actual application ID, and manipulate privileges of current process.
+  void HandleDropProcessPrivileges(int fd, base::PickleIterator iter);
+#endif
+
   // The Zygote needs to keep some information about each process. Most
   // notably what the PID of the process is inside the PID namespace of
   // the Zygote and whether or not a process was started by the
@@ -139,6 +155,12 @@ class Zygote {
   // Count of how many fork delegates for which we've invoked InitialUMA().
   size_t initial_uma_index_;
 
+#if defined(OS_TIZEN)
+  // This contains the FD that must be closed when current process is
+  // terminated.
+  void* injected_bundle_handle_;
+#endif
+
   // The vector contains the child processes that need to be reaped.
   std::vector<ZygoteProcessInfo> to_reap_;
 
index 3cde681..8a8db9b 100644 (file)
@@ -82,6 +82,7 @@ BuildRequires: pkgconfig(nspr)
 BuildRequires: pkgconfig(nss)
 BuildRequires: pkgconfig(openssl)
 BuildRequires: pkgconfig(scim)
+BuildRequires: pkgconfig(security-manager)
 BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(tts)
 BuildRequires: pkgconfig(ui-gadget-1)
index e6758ca..8b0068a 100644 (file)
@@ -507,6 +507,25 @@ config("mm-player-public") {
   }
 }
 
+config("security-manager") {
+  if (is_tizen) {
+    ldflags = [ "-lsecurity-manager-client" ]
+  }
+}
+
+tizen_pkg_config("libsecurity-manager") {
+  packages = []
+  if (is_tizen) {
+    packages = [ "security-manager" ]
+  }
+}
+
+config("security-manager-public") {
+  if (is_tizen) {
+    cflags = [ "-security-manager" ]
+  }
+}
+
 config("tts") {
   if (is_tizen) {
     ldflags = [ "-ltts" ]
index 77b3453..965b675 100644 (file)
@@ -21,6 +21,8 @@ external_content_browser_efl_configs = [
   "//tizen_src/build:libelementary",
   "//tizen_src/build:efl-extension",
   "//tizen_src/build:libefl-extension",
+  "//tizen_src/build:security-manager",
+  "//tizen_src/build:libsecurity-manager",
   "//tizen_src/build:tts",
   "//tizen_src/build:libtts",
 ]
index b622019..b84b1fe 100644 (file)
@@ -31,6 +31,8 @@ external_content_browser_configs = [
   "//tizen_src/build:libelementary",
   "//tizen_src/build:efl-extension",
   "//tizen_src/build:libefl-extension",
+  "//tizen_src/build:security-manager",
+  "//tizen_src/build:libsecurity-manager",
 ]
 
 external_content_browser_extra_configs = [
index 1ab3e93..f5aeb9b 100644 (file)
 #include "private/ewk_security_origin_private.h"
 #include "wrt/wrt_widget_host.h"
 
+#if defined(OS_TIZEN)
+#include "content/browser/zygote_host/zygote_communication_linux.h"
+#include "content/public/common/zygote_handle.h"
+#endif
+
 using content::BrowserThread;
 using content::BrowserContext;
 using content::BrowserContextEfl;
@@ -214,6 +219,11 @@ void EWebContext::SetWidgetInfo(const std::string& tizen_app_id,
   widget_scale_ = scale;
   widget_theme_ = theme;
   widget_encoded_bundle_ = encoded_bundle;
+
+#if defined(OS_TIZEN)
+  // Drop process privillages while web app is launching from WRT process pool.
+  content::GetGenericZygote()->DropProcessPrivileges(tizen_app_id_);
+#endif
 }
 
 void EWebContext::SendWrtMessage(const Ewk_Wrt_Message_Data& data) {
@@ -255,6 +265,12 @@ EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath)
       widget_scale_(0),
       m_pixmap(0),
       inspector_server_(NULL) {
+#if defined(OS_TIZEN)
+  // In order to support process pool for WRT, injected bundle should be
+  // preloaded on zygote process after first intialization of EwkGlobalData.
+  bool should_preload_injected_bundle =
+      (!injected_bundle_path_.empty() && !EwkGlobalData::IsInitialized());
+#endif
   CHECK(EwkGlobalData::GetInstance());
 
   // WRT does not really care about incognito, so set it to false
@@ -278,6 +294,13 @@ EWebContext::EWebContext(bool incognito, const std::string& injectedBundlePath)
   notification_cb_.reset(
       new EWebContextNotificationCallback(nullptr, nullptr, nullptr, nullptr));
   tizen_extensible_.reset(TizenExtensible::create());
+
+#if defined(OS_TIZEN)
+  // Preload injected bundle on zygote process for process pool.
+  if (should_preload_injected_bundle) {
+    content::GetGenericZygote()->LoadInjectedBundlePath(injected_bundle_path_);
+  }
+#endif
 }
 
 EWebContext::~EWebContext() {}