Modify setting scheduling priority 10/293310/5
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 24 May 2023 08:51:34 +0000 (08:51 +0000)
committerHwanKyu Jhun <h.jhun@samsung.com>
Thu, 25 May 2023 04:04:33 +0000 (04:04 +0000)
To set the scheduling priority properly, the launchpad-process-pool
sends the priority to the child process. And, after calling fork(),
the child process creates a new session using setsid().
The argument of the setpriority() is changed to PRIO_PGRP from PRIO_PROCESS.
The hydra loader changes the priority to 0 to restore to its original state.

Change-Id: Ie5d5d6d55493934c7706b32789d35697d05285d6
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
17 files changed:
src/launchpad-process-pool/app_executor.cc
src/launchpad-process-pool/app_executor.hh
src/launchpad-process-pool/executor.cc
src/launchpad-process-pool/hydra_loader_context.cc
src/launchpad-process-pool/loader_context.cc
src/launchpad-process-pool/loader_context.hh
src/launchpad-process-pool/loader_executor.cc
src/lib/common/src/launchpad_common.c
src/lib/launchpad-common/hydra_request.cc
src/lib/launchpad-common/hydra_request.hh
src/lib/launchpad-common/sched_priority.cc [new file with mode: 0644]
src/lib/launchpad-common/sched_priority.hh [new file with mode: 0644]
src/lib/launchpad-glib/util.cc
src/lib/launchpad-glib/util.hh
src/lib/launchpad-hydra/executor.cc
src/lib/launchpad-hydra/launchpad_hydra.cc
src/lib/launchpad-hydra/loader_executor.cc

index 86accb1..ff38056 100644 (file)
@@ -61,8 +61,6 @@ AppExecutor::AppExecutor() : Executor(this) {
   launcher_infos_ = inflator.Inflate("/usr/share/aul");
 
   prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepCreateNewSession, this));
-  prepare_funcs_.push_back(
       std::bind(&AppExecutor::StepPluginPrepareApp, this));
   prepare_funcs_.push_back(
       std::bind(&AppExecutor::StepEnableExternalPackage, this));
@@ -174,11 +172,6 @@ int AppExecutor::Prepare() {
   return 0;
 }
 
-int AppExecutor::StepCreateNewSession() {
-  setsid();
-  return 0;
-}
-
 int AppExecutor::StepPluginPrepareApp() {
   return Plugin::PrepareApp(app_info_->GetAppId(), app_info_->GetBundle());
 }
index 5d1327e..94b23fa 100644 (file)
@@ -46,7 +46,6 @@ class AppExecutor : public Executor::Delegator,
   void OnRequestReceived(tizen_base::Parcel* parcel) override;
 
   int Prepare();
-  int StepCreateNewSession();
   int StepPluginPrepareApp();
   int StepEnableExternalPackage();
   int StepEnableTrustAnchor();
index 74541d6..4aea7ca 100644 (file)
 
 #include "launchpad-process-pool/executor.hh"
 
+#include <stdlib.h>
 #include <unistd.h>
 
-#include <util.hh>
+#include <sched_priority.hh>
 
 #include "launchpad-process-pool/log_private.hh"
 
@@ -34,8 +35,9 @@ pid_t Executor::Execute(int priority) {
   }
 
   if (pid == 0) {
+    setsid();
     if (priority != 0)
-      Util::SetPriority(priority);
+      SchedPriority::Set(priority);
 
     _W("security_manager_prepare_app_candidate ++");
     int ret = security_manager_prepare_app_candidate();
index b42db39..545e107 100644 (file)
@@ -110,7 +110,7 @@ void HydraLoaderContext::SetHydraPid(pid_t hydra_pid) {
 
 void HydraLoaderContext::PrepareCandidateProcess() {
   _W("Send launch request to hydra loader. fd(%d)", client_socket_->GetFd());
-  HydraRequest request(LAUNCH_CANDIDATE);
+  HydraRequest request(LAUNCH_CANDIDATE, GetSchedPriority());
   tizen_base::Parcel parcel;
   parcel.WriteParcelable(request);
 
index 8ced9b8..7458bbb 100644 (file)
@@ -283,6 +283,10 @@ void LoaderContext::SetPrepared(bool prepared) {
   prepared_ = prepared;
 }
 
+int LoaderContext::GetSchedPriority() const {
+  return loader_info_->GetSchedPriority();
+}
+
 pid_t LoaderContext::GetPid() const {
   return pid_;
 }
index 8559ebe..1dfbc26 100644 (file)
@@ -114,6 +114,7 @@ class LoaderContext : public std::enable_shared_from_this<LoaderContext>,
  protected:
   void SetPrepared(bool prepared);
   void OnIOEventReceived(int fd, int condition) override;
+  int GetSchedPriority() const;
 
  private:
   void UpdateScore();
index cdf9f4a..43f1d4c 100644 (file)
@@ -23,6 +23,7 @@
 #include <utility>
 
 #include <parcel.hh>
+#include <sched_priority.hh>
 
 #include "launchpad-process-pool/config.hh"
 #include "launchpad-process-pool/log_private.hh"
 namespace launchpad {
 namespace {
 
-tizen_base::Parcel CreateParcelFromArgv(const std::vector<std::string>& argv) {
-  tizen_base::Bundle b;
-  b.Add("LOADER_ARGS", argv);
-  auto b_raw = b.ToRaw();
+tizen_base::Parcel CreateParcelFromBundle(tizen_base::Bundle* b) {
+  auto b_raw = b->ToRaw();
   std::string raw(reinterpret_cast<const char*>(b_raw.first.get()));
   tizen_base::Parcel parcel;
   parcel.WriteString(raw);
   return parcel;
 }
 
-std::vector<std::string> CreateArgvFromParcel(tizen_base::Parcel* parcel) {
+tizen_base::Bundle CreateBundleFromParcel(tizen_base::Parcel* parcel) {
   std::string raw = parcel->ReadString();
-  tizen_base::Bundle b(raw);
-  return b.GetStringArray("LOADER_ARGS");
+  return tizen_base::Bundle(raw);
 }
 
 }  // namespace
@@ -67,7 +65,10 @@ pid_t LoaderExecutor::Execute(const LoaderContext* loader_context,
     int priority) {
   loader_argv_ = CreateLoaderArgv(loader_context);
   if (process_pool_->IsPrepared()) {
-    auto parcel = CreateParcelFromArgv(loader_argv_);
+    tizen_base::Bundle b;
+    b.Add("LOADER_ARGS", loader_argv_);
+    b.Add("LOADER_PRIORITY", std::to_string(priority));
+    auto parcel = CreateParcelFromBundle(&b);
     return process_pool_->Execute(parcel);
   }
 
@@ -107,7 +108,12 @@ void LoaderExecutor::OnExecution() {
 
 void LoaderExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
   _W("Request received");
-  loader_argv_ = CreateArgvFromParcel(parcel);
+  tizen_base::Bundle b = CreateBundleFromParcel(parcel);
+  int priority = std::stoi(b.GetString("LOADER_PRIORITY"));
+  if (priority != 0)
+    SchedPriority::Set(priority);
+
+  loader_argv_ = b.GetStringArray("LOADER_ARGS");
   OnExecution();
 }
 
index b12f10d..9f75801 100644 (file)
@@ -1051,7 +1051,7 @@ int _set_priority(int prio)
 {
        int ret;
 
-       ret = setpriority(PRIO_PROCESS, 0, prio);
+       ret = setpriority(PRIO_PGRP, 0, prio);
        if (ret != 0) {
                SECURE_LOGE("Failed to set process(%d) priority(%d) - err(%d)",
                                getpid(), prio, errno);
index 3d4fc64..7001680 100644 (file)
 
 namespace launchpad {
 
-HydraRequest::HydraRequest(int cmd) : cmd_(cmd) {}
+HydraRequest::HydraRequest(int cmd, int priority)
+    : cmd_(cmd), priority_(priority) {}
 
-HydraRequest::HydraRequest(int cmd, int argc, char** argv)
-    : cmd_(cmd), argc_(argc), argv_(argv) {}
+HydraRequest::HydraRequest(int cmd, int priority, int argc, char** argv)
+    : cmd_(cmd), priority_(priority), argc_(argc), argv_(argv) {}
 
 int HydraRequest::GetCommand() const {
   return cmd_;
 }
 
+int HydraRequest::GetPriority() const {
+  return priority_;
+}
+
 int HydraRequest::GetArgc() const {
   return argc_;
 }
@@ -39,6 +44,7 @@ char** HydraRequest::GetArgv() const {
 
 void HydraRequest::WriteToParcel(tizen_base::Parcel* parcel) const {
   parcel->WriteInt32(cmd_);
+  parcel->WriteInt32(priority_);
   parcel->WriteInt32(argc_);
   for (int i = 0; i < argc_; ++i)
     parcel->WriteCString(argv_[i]);
@@ -52,6 +58,7 @@ void HydraRequest::ReadFromParcel(tizen_base::Parcel* parcel) {
   argv_ = nullptr;
 
   parcel->ReadInt32(&cmd_);
+  parcel->ReadInt32(&priority_);
   parcel->ReadInt32(&argc_);
   if (argc_ == 0)
     return;
index 0d06c93..fcffdd6 100644 (file)
@@ -29,12 +29,13 @@ namespace launchpad {
 
 class EXPORT_API HydraRequest : public tizen_base::Parcelable {
  public:
-  explicit HydraRequest(int cmd);
-  HydraRequest(int cmd, int argc, char** argv);
+  explicit HydraRequest(int cmd, int priority);
+  HydraRequest(int cmd, int priority, int argc, char** argv);
   HydraRequest() = default;
   virtual ~HydraRequest() = default;
 
   int GetCommand() const;
+  int GetPriority() const;
   int GetArgc() const;
   char** GetArgv() const;
 
@@ -43,6 +44,7 @@ class EXPORT_API HydraRequest : public tizen_base::Parcelable {
 
  private:
   int cmd_ = 0;
+  int priority_ = 0;
   int argc_ = 0;
   char** argv_ = nullptr;
 };
diff --git a/src/lib/launchpad-common/sched_priority.cc b/src/lib/launchpad-common/sched_priority.cc
new file mode 100644 (file)
index 0000000..68d5e48
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "launchpad-common/sched_priority.hh"
+
+#include <sys/resource.h>
+#include <sys/time.h>
+
+#include "launchpad-common/log_private.hh"
+
+namespace launchpad {
+
+void SchedPriority::Set(int priority) {
+  int ret = setpriority(PRIO_PGRP, 0, priority);
+  if (ret != 0) {
+    _E("Failed to set process priority. priority(%d), errno(%d)",
+        priority, errno);
+  } else {
+    _D("Setting priority(%d) is sucessful", priority);
+  }
+}
+
+int SchedPriority::Get() {
+  return getpriority(PRIO_PGRP, 0);
+}
+
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-common/sched_priority.hh b/src/lib/launchpad-common/sched_priority.hh
new file mode 100644 (file)
index 0000000..6e8d197
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIB_LAUNCHPAD_COMMON_SCHED_PRIORITY_HH_
+#define LIB_LAUNCHPAD_COMMON_SCHED_PRIORITY_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API SchedPriority {
+ public:
+  static void Set(int priority);
+  static int Get();
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_COMMON_SCHED_PRIORITY_HH_
index 3839f17..2d4e5cf 100644 (file)
@@ -130,16 +130,6 @@ void Util::SetEnvironments(const AppInfo* app_info) {
   setenv("GCOV_PREFIX", "/tmp", 1);
 }
 
-void Util::SetPriority(int priority) {
-  int ret = setpriority(PRIO_PROCESS, 0, priority);
-  if (ret != 0) {
-    _E("Failed to set process priority. priority(%d), errno(%d)",
-        priority, errno);
-  } else {
-    _D("Setting priority(%d) is sucessful", priority);
-  }
-}
-
 void Util::DeleteSocketPath(pid_t pid, uid_t uid) {
   std::string path ="/run/aul/apps/" + std::to_string(uid) + "/" +
       std::to_string(pid);
index 80f9001..0589202 100644 (file)
@@ -27,7 +27,6 @@ namespace launchpad {
 class EXPORT_API Util {
  public:
   static void SetEnvironments(const AppInfo* app_info);
-  static void SetPriority(int priority);
   static void DeleteSocketPath(pid_t pid, uid_t uid);
 };
 
index 06fe350..92191a6 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
+#include <sched_priority.hh>
 #include <stdio.hh>
 
 #include "launchpad-hydra/log_private.hh"
@@ -54,16 +55,6 @@ int SecurityManagerPrepareAppCandidate() {
   return 0;
 }
 
-void SetPriority(int priority) {
-  int ret = setpriority(PRIO_PROCESS, 0, priority);
-  if (ret != 0) {
-    _E("Failed to set process priority. priority(%d), errno(%d)",
-        priority, errno);
-  } else {
-    _D("Setting priority(%d) is successful", priority);
-  }
-}
-
 }  // namespace
 
 Executor::Executor(Executor::Delegator* delegator) : delegator_(delegator) {}
@@ -76,8 +67,9 @@ pid_t Executor::Execute(int argc, char** argv, int priority) {
   }
 
   if (pid == 0) {
+    setsid();
     if (priority != 0)
-      SetPriority(priority);
+      SchedPriority::Set(priority);
 
     int ret = SecurityManagerPrepareAppCandidate();
     if (ret != 0) {
index 1d301e2..c08106b 100644 (file)
@@ -24,8 +24,9 @@
 
 #include <exception.hh>
 #include <hydra_request.hh>
-#include <sigchld_info.hh>
 #include <parcel.hh>
+#include <sched_priority.hh>
+#include <sigchld_info.hh>
 
 #include "common/inc/launchpad_common.h"
 #include "common/inc/launchpad_types.h"
@@ -131,6 +132,7 @@ void LaunchpadHydra::Run(hydra_lifecycle_callback_s* callback,
   candidate_pid_ = executor_->Execute(argc_, argv_);
   _D("Candidate process(%d)", candidate_pid_);
   socket_->Send(&candidate_pid_, sizeof(candidate_pid_));
+  SchedPriority::Set(0);
 
   EventLoop::GetInst().Run();
   OnTerminate();
@@ -195,10 +197,11 @@ void LaunchpadHydra::HandleLaunchEvent(const HydraRequest& request) {
   pid_t pid = -1;
   if (request.GetCommand() == LAUNCH_CANDIDATE) {
     _W("LAUNCH_CANDIDATE");
-    pid = executor_->Execute(argc_, argv_);
+    pid = executor_->Execute(argc_, argv_, request.GetPriority());
   } else if (request.GetCommand() == LAUNCH_CANDIDATE_WITH_ARGS) {
     _W("LAUNCH_CANDIDATE_WITH_ARGS");
-    pid = executor_->Execute(request.GetArgc(), request.GetArgv());
+    pid = executor_->Execute(request.GetArgc(), request.GetArgv(),
+        request.GetPriority());
   } else {
     _W("Unknown command(%d)", request.GetCommand());
   }
@@ -269,7 +272,6 @@ void LaunchpadHydra::OnSigchldReceived(pid_t pid, int status) {
 
 void LaunchpadHydra::OnLoaderExecution(int argc, char** argv) {
   _D("Run loader. pid(%d)", getpid());
-  setsid();
   SignalManager::GetInst().Dispose();
   EventLoop::GetInst().Exit();
 
index 9f5b8b7..d4929b4 100644 (file)
 
 #include <errno.h>
 #include <stdio.h>
+#include <sys/resource.h>
+#include <sys/time.h>
 #include <unistd.h>
 
 #include <utility>
 
 #include <parcel.hh>
 #include <parcelable.hh>
+#include <sched_priority.hh>
 
 #include "launchpad-hydra/log_private.hh"
 #include "launchpad-hydra/signal_manager.hh"
@@ -33,7 +36,8 @@ namespace {
 
 class LoaderArgs : public tizen_base::Parcelable {
  public:
-  explicit LoaderArgs(int argc, char** argv) {
+  explicit LoaderArgs(int priority, int argc, char** argv)
+      : priority_(priority) {
     for (int i = 0; i < argc; ++i)
       args_.push_back(argv[i]);
   }
@@ -42,12 +46,14 @@ class LoaderArgs : public tizen_base::Parcelable {
   ~LoaderArgs() = default;
 
   void WriteToParcel(tizen_base::Parcel* parcel) const override {
+    parcel->WriteInt32(priority_);
     parcel->WriteInt32(args_.size());
     for (size_t i = 0; i < args_.size(); ++i)
       parcel->WriteString(args_[i]);
   }
 
   void ReadFromParcel(tizen_base::Parcel* parcel) override {
+    parcel->ReadInt32(&priority_);
     int data_size = 0;
     parcel->ReadInt32(&data_size);
     args_.resize(data_size);
@@ -55,11 +61,16 @@ class LoaderArgs : public tizen_base::Parcelable {
       args_[i] = parcel->ReadString();
   }
 
+  int GetPriority() const {
+    return priority_;
+  }
+
   const std::vector<std::string>& GetArgs() const {
     return args_;
   }
 
  private:
+  int priority_ = 0;
   std::vector<std::string> args_;
 };
 
@@ -71,7 +82,7 @@ LoaderExecutor::LoaderExecutor(IEvent* listener)
 
 pid_t LoaderExecutor::Execute(int argc, char** argv, int priority) {
   if (process_pool_->IsPrepared()) {
-    LoaderArgs loader_args(argc, argv);
+    LoaderArgs loader_args(priority, argc, argv);
     tizen_base::Parcel parcel;
     parcel.WriteParcelable(loader_args);
     return process_pool_->Execute(parcel);
@@ -95,6 +106,10 @@ void LoaderExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
   LoaderArgs loader_args;
   parcel->ReadParcelable(&loader_args);
 
+  int priority = loader_args.GetPriority();
+  if (priority != 0)
+    SchedPriority::Set(priority);
+
   auto& args = loader_args.GetArgs();
   std::vector<char*> loader_argv(args.size() + 1);
   int argc = args.size();