From e1d0df1f61b42727339cdba6eba37ffeb4a8be00 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 15 Dec 2023 13:28:00 +0900 Subject: [PATCH 01/16] Release version 0.38.23 Changes: - Use access() instead of std::filesystem::exists Change-Id: I4c3090d72ccb6b4d62888d9c462bd9d565cbd97e Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index b29e638..d17932d 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.22 +Version: 0.38.23 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From c7b2118b1d44cf41fd6babd3620e1b85c01ac72f Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 20 Dec 2023 10:27:20 +0900 Subject: [PATCH 02/16] Except file descriptors from closing list There is a smack issue by closing fds in the process-pool. In launchpad-process-pool, when using dlog, create a file descriptor with vlog_init(). - When creating a process-pool, close all file descriptors except for the dlog fd (at this time, the vlog fd is closed). - When using the security-manager, attempt to output dlog. Attempt to write using the vlog fd by calling vlog_write(), but at this time, actually use the fd created by the security-manager. - This fd points to /sys/fs/smackfs. - SMACK error occurred. Change-Id: I50b3f4860454f002dd550311bf48e7ef5a2916dc Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/process_pool.cc | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/launchpad-process-pool/process_pool.cc b/src/launchpad-process-pool/process_pool.cc index d91bc58..82456cc 100644 --- a/src/launchpad-process-pool/process_pool.cc +++ b/src/launchpad-process-pool/process_pool.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,24 @@ namespace { constexpr const char kProcessPool[] = "process-pool"; -std::vector GetDlogFds() { +bool IsExceptable(const std::string& path) { + static char buf[PATH_MAX]; + ssize_t len = readlink(path.c_str(), buf, sizeof(buf)); + if (len < 0) { + _E("readlink() is failed. errno: %d", errno); + return false; + } + + buf[len] = '\0'; + if (strstr(buf, "log") != nullptr || + strstr(buf, "trace") != nullptr || + strstr(buf, "dev") != nullptr) + return true; + + return false; +} + +std::vector GetExceptableFds() { std::vector fds; try { fs::path proc_path("/proc/self/fd"); @@ -49,7 +67,7 @@ std::vector GetDlogFds() { continue; int fd = std::stoi(entry.path().filename().string()); - if (dlog_is_log_fd(fd)) + if (dlog_is_log_fd(fd) || IsExceptable(entry.path().string())) fds.push_back(fd); } } catch (const fs::filesystem_error& e) { @@ -136,7 +154,7 @@ void ProcessPool::OnExecution() { snprintf(args[0], length, "/usr/bin/%s <%s>", kProcessPool, name_.c_str()); close(pipe_fd_[1]); - std::vector except_fds = GetDlogFds(); + std::vector except_fds = GetExceptableFds(); except_fds.push_back(pipe_fd_[0]); Util::CloseAllFds(except_fds); int ret = WaitForRequest(std::make_unique(pipe_fd_[0])); -- 2.7.4 From 4673d94e6c14bcefe819be579d7ac8a9f3098df4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 20 Dec 2023 11:23:18 +0900 Subject: [PATCH 03/16] Handle SIGCHLD event for process-pool If the process pool is terminated, the launchpad should remove the process information. And, if sending the request to the process pool is failed, the launchpad must create a new process to execute an application. Change-Id: I1d5096394593fe3db92fbd125f468bd9b73c498f Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/app_executor.cc | 8 ++++++- src/launchpad-process-pool/app_executor.hh | 1 + src/launchpad-process-pool/launchpad.cc | 1 + src/launchpad-process-pool/loader_executor.cc | 8 ++++++- src/launchpad-process-pool/loader_executor.hh | 3 +++ src/launchpad-process-pool/loader_manager.cc | 1 + src/launchpad-process-pool/process_pool.cc | 30 ++++++++++++++++++++------- src/launchpad-process-pool/process_pool.hh | 4 ++-- 8 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc index 06dda58..afb2e94 100644 --- a/src/launchpad-process-pool/app_executor.cc +++ b/src/launchpad-process-pool/app_executor.cc @@ -99,7 +99,9 @@ pid_t AppExecutor::Execute(const AppInfo* app_info) { if (process_pool_->IsPrepared()) { tizen_base::Parcel parcel; parcel.WriteParcelable(*app_info); - return process_pool_->Execute(parcel); + pid_t pid = process_pool_->Execute(parcel); + if (pid > 0) + return pid; } app_info_ = app_info; @@ -111,6 +113,10 @@ void AppExecutor::DisposeCandidateProcess() { process_pool_->SetTimer(); } +void AppExecutor::HandleSigchld(pid_t pid) { + process_pool_->HandleSigchld(pid); +} + void AppExecutor::OnExecution() { UserTracer::Print(std::to_string(getpid()) + "|after calling fork(). " + app_info_->GetAppId()); diff --git a/src/launchpad-process-pool/app_executor.hh b/src/launchpad-process-pool/app_executor.hh index 94b23fa..7fd168e 100644 --- a/src/launchpad-process-pool/app_executor.hh +++ b/src/launchpad-process-pool/app_executor.hh @@ -40,6 +40,7 @@ class AppExecutor : public Executor::Delegator, pid_t Execute(const AppInfo* app_info); void DisposeCandidateProcess(); + void HandleSigchld(pid_t pid); private: void OnExecution() override; diff --git a/src/launchpad-process-pool/launchpad.cc b/src/launchpad-process-pool/launchpad.cc index 1562f15..c12f04a 100644 --- a/src/launchpad-process-pool/launchpad.cc +++ b/src/launchpad-process-pool/launchpad.cc @@ -687,6 +687,7 @@ void Launchpad::OnSigchldReceived(pid_t pid) { launchpad::Log::Print("[SIGCHLD]", "pid(%7d)", pid); LoaderManager::GetInst().HandleSigchld(pid); + app_executor_->HandleSigchld(pid); } void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) { diff --git a/src/launchpad-process-pool/loader_executor.cc b/src/launchpad-process-pool/loader_executor.cc index be307ec..1a23a67 100644 --- a/src/launchpad-process-pool/loader_executor.cc +++ b/src/launchpad-process-pool/loader_executor.cc @@ -70,7 +70,9 @@ pid_t LoaderExecutor::Execute(const LoaderContext* loader_context, b.Add("LOADER_ARGS", loader_argv_); b.Add("LOADER_PRIORITY", std::to_string(priority)); auto parcel = CreateParcelFromBundle(&b); - return process_pool_->Execute(parcel); + pid_t pid = process_pool_->Execute(parcel); + if (pid > 0) + return pid; } return Executor::Execute(priority); @@ -85,6 +87,10 @@ void LoaderExecutor::DisposeCandidateProcess() { process_pool_->SetTimer(); } +void LoaderExecutor::HandleSigchld(pid_t pid) { + process_pool_->HandleSigchld(pid); +} + void LoaderExecutor::OnExecution() { std::vector loader_argv(loader_argv_.size() + 1); int loader_argc = loader_argv_.size(); diff --git a/src/launchpad-process-pool/loader_executor.hh b/src/launchpad-process-pool/loader_executor.hh index 110ffef..9a7c708 100644 --- a/src/launchpad-process-pool/loader_executor.hh +++ b/src/launchpad-process-pool/loader_executor.hh @@ -17,6 +17,8 @@ #ifndef LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_ #define LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_ +#include + #include #include #include @@ -41,6 +43,7 @@ class LoaderExecutor : public Executor::Delegator, pid_t Execute(const LoaderContext* loader_context, int priority); bool HasCandidateProcess() const; void DisposeCandidateProcess(); + void HandleSigchld(pid_t pid); private: LoaderExecutor(); diff --git a/src/launchpad-process-pool/loader_manager.cc b/src/launchpad-process-pool/loader_manager.cc index 4ddee1c..472d556 100644 --- a/src/launchpad-process-pool/loader_manager.cc +++ b/src/launchpad-process-pool/loader_manager.cc @@ -93,6 +93,7 @@ void LoaderManager::HandleSigchld(pid_t pid) { } RemoveLoaderContextsByCallerPid(pid); + LoaderExecutor::GetInst().HandleSigchld(pid); } void LoaderManager::AddDefaultLoaderContexts() { diff --git a/src/launchpad-process-pool/process_pool.cc b/src/launchpad-process-pool/process_pool.cc index 82456cc..81a5c05 100644 --- a/src/launchpad-process-pool/process_pool.cc +++ b/src/launchpad-process-pool/process_pool.cc @@ -102,22 +102,38 @@ pid_t ProcessPool::Execute(const tizen_base::Parcel& parcel) { return -1; auto process = std::move(queue_.front()); - queue_.pop(); - process->Send(parcel); + queue_.erase(queue_.begin()); + if (process->Send(parcel) < 0) + return -1; + return process->GetPid(); } void ProcessPool::Dispose() { - while (!queue_.empty()) { - auto process = std::move(queue_.front()); - queue_.pop(); + for (auto& process : queue_) { process->Kill(); _D("Kill process(%d)", process->GetPid()); } - + queue_.clear(); UnsetTimer(); } +void ProcessPool::HandleSigchld(pid_t pid) { + auto iter = queue_.begin(); + while (iter != queue_.end()) { + if ((*iter)->GetPid() == pid) { + iter = queue_.erase(iter); + break; + } + + iter++; + } + + int current_process_count = static_cast(queue_.size()); + if (current_process_count != num_processes_) + SetTimer(); +} + ProcessPool::Process::Process(pid_t pid, int fd) : pid_(pid), socket_(new Socket(fd)) { } @@ -186,7 +202,7 @@ void ProcessPool::PrepareProcess() { } close(pipe_fd_[0]); - queue_.push(std::make_shared(pid, pipe_fd_[1])); + queue_.push_back(std::make_shared(pid, pipe_fd_[1])); } } diff --git a/src/launchpad-process-pool/process_pool.hh b/src/launchpad-process-pool/process_pool.hh index d38e327..7d159c2 100644 --- a/src/launchpad-process-pool/process_pool.hh +++ b/src/launchpad-process-pool/process_pool.hh @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -48,6 +47,7 @@ class ProcessPool : public Executor::Delegator, bool IsPrepared() const; pid_t Execute(const tizen_base::Parcel& parcel); void Dispose(); + void HandleSigchld(pid_t pid); void SetTimer(); private: @@ -75,7 +75,7 @@ class ProcessPool : public Executor::Delegator, int num_processes_; IEvent* event_listener_; int pipe_fd_[2] = { -1, -1 }; - std::queue> queue_; + std::vector> queue_; guint timer_ = 0; }; -- 2.7.4 From 4ba729ec4d5fa1abcd1245fd85ea9d48fd9be8d0 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 20 Dec 2023 12:43:30 +0900 Subject: [PATCH 04/16] Release version 0.38.24 Changes: - Except file descriptors from closing list - Handle SIGCHLD event for process-pool Change-Id: I7fa11a06f4c2cc08c928d78d6b56f41209c2783e Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index d17932d..89e5561 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.23 +Version: 0.38.24 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 7b4b1efecc25dbdc4f7556ce449b1b5b94670413 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Thu, 21 Dec 2023 10:15:51 +0900 Subject: [PATCH 05/16] Fix build fail issue for gcc13 Change-Id: If85456e7b588255c95b0d3315859bef0be9b1487 Signed-off-by: Changgyu Choi --- src/lib/launchpad-common/cpu_boost_controller.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/launchpad-common/cpu_boost_controller.cc b/src/lib/launchpad-common/cpu_boost_controller.cc index 615adbd..bfe0671 100644 --- a/src/lib/launchpad-common/cpu_boost_controller.cc +++ b/src/lib/launchpad-common/cpu_boost_controller.cc @@ -18,6 +18,7 @@ #include +#include #include #include "launchpad-common/log_private.hh" -- 2.7.4 From b4ab36e5f4cdff07d75413931fce7d7146928e8e Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Thu, 21 Dec 2023 11:22:48 +0900 Subject: [PATCH 06/16] Release version 0.38.25 Changes: - Fix build fail issue for gcc13 Change-Id: Iab3fbd4642e46425840d94cc8620a919136cd05e Signed-off-by: Changgyu Choi --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 89e5561..94f1e11 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.24 +Version: 0.38.25 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 41344b6e4db97bc71863012457347ca3069d637e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 2 Jan 2024 17:08:52 +0900 Subject: [PATCH 07/16] Register application info when ping delivered If the application is executed using fast launch option of the app_launcher tool, there is a timing issue. When the app process is slow to enter the main function, amd does not know the process existence. To prevent the timing issue, launchpad sends the launches process list to amd when ping request is received. Change-Id: If7dea099493e0442b2a09137467238682c63d66e Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/launchpad.cc | 28 ++++++++++++++++++++++++++++ src/launchpad-process-pool/launchpad.hh | 2 ++ src/lib/launchpad-common/types.hh | 9 +++++++++ src/lib/launchpad-glib/app_info.cc | 22 ++++++++++++++++++++-- src/lib/launchpad-glib/app_info.hh | 9 +++++++-- src/lib/launchpad-glib/util.cc | 28 +++++++++++++++++++++++----- src/lib/launchpad-glib/util.hh | 2 ++ 7 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/launchpad-process-pool/launchpad.cc b/src/launchpad-process-pool/launchpad.cc index c12f04a..8b82267 100644 --- a/src/launchpad-process-pool/launchpad.cc +++ b/src/launchpad-process-pool/launchpad.cc @@ -364,6 +364,19 @@ void Launchpad::HandleDemandRequest(std::shared_ptr request) { void Launchpad::HandlePingRequest(std::shared_ptr request) { request->SendResult(getpid()); + ping_received_ = true; + for (auto& iter : fast_launches_) { + pid_t pid = iter.first; + auto& appid = iter.second; + tizen_base::Bundle b = { + { kAulAppId, appid }, + { kAulPid, std::to_string(pid) } + }; + + Util::SendCmdToAmd(AmdCmd::AppRegisterPid, b.GetHandle(), + static_cast(AmdSocketOption::NoReply | AmdSocketOption::Bundle)); + } + fast_launches_.clear(); _W("[PAD_CMD_PING]"); } @@ -559,6 +572,20 @@ void Launchpad::LaunchRequestComplete(std::shared_ptr request) { pid_map_[request->GetPid()] = app_info->GetAppId(); launchpad::Log::Print("[LAUNCH]", "pid(%7d) | appid(%s)", request->GetPid(), app_info->GetAppId().c_str()); + if (app_info->IsFastLaunch()) { + if (ping_received_) { + tizen_base::Bundle b = { + { kAulAppId, app_info->GetAppId() }, + { kAulPid, std::to_string(request->GetPid()) } + }; + + Util::SendCmdToAmd(AmdCmd::AppRegisterPid, b.GetHandle(), + static_cast( + AmdSocketOption::NoReply | AmdSocketOption::Bundle)); + } else { + fast_launches_[request->GetPid()] = app_info->GetAppId(); + } + } } } @@ -662,6 +689,7 @@ void Launchpad::OnIOEventReceived(int fd, int condition) { } void Launchpad::OnSigchldReceived(pid_t pid) { + fast_launches_.erase(pid); auto found = pid_map_.find(pid); if (found != pid_map_.end()) { auto appid = found->second; diff --git a/src/launchpad-process-pool/launchpad.hh b/src/launchpad-process-pool/launchpad.hh index 4e6cb01..40d20ae 100644 --- a/src/launchpad-process-pool/launchpad.hh +++ b/src/launchpad-process-pool/launchpad.hh @@ -107,6 +107,8 @@ class Launchpad : public IOChannel::IEvent, std::unique_ptr cleaner_; std::vector> pending_requests_; Config::LaunchMode::Mode mode_; + bool ping_received_ = false; + std::unordered_map fast_launches_; }; } // namespace launchpad diff --git a/src/lib/launchpad-common/types.hh b/src/lib/launchpad-common/types.hh index 5b7eada..c65e1cc 100644 --- a/src/lib/launchpad-common/types.hh +++ b/src/lib/launchpad-common/types.hh @@ -69,11 +69,20 @@ enum PadLoaderId { }; enum AmdCmd { + AppRegisterPid = 57, LaunchpadDeadSignal = 61, LaunchpadLaunchSignal = 83, AppStartupSignal = 89, }; +enum class AmdSocketOption : int { + None = 0x0, + NoReply = 0x1, + Async = 0x2, + Queue = 0x4, + Bundle = 0x8 +}; + } // namespace launchpad #endif // LIB_LAUNCHPAD_COMMON_TYPES_HH_ diff --git a/src/lib/launchpad-glib/app_info.cc b/src/lib/launchpad-glib/app_info.cc index c286f6b..7e95f69 100644 --- a/src/lib/launchpad-glib/app_info.cc +++ b/src/lib/launchpad-glib/app_info.cc @@ -86,6 +86,15 @@ AppInfo::Builder& AppInfo::Builder::SetLoaderName(const tizen_base::Bundle& b) { return *this; } +AppInfo::Builder& AppInfo::Builder::SetFastLaunch(const tizen_base::Bundle& b) { + if (b.GetString(kAulFastLaunch) == "true") + fast_launch_ = true; + else + fast_launch_ = false; + + return *this; +} + AppInfo::Builder& AppInfo::Builder::SetGlobal(const tizen_base::Bundle& b) { if (b.GetString(kAulIsGlobal) == "true") global_ = true; @@ -105,7 +114,7 @@ AppInfo::Builder::operator AppInfo*() { std::move(original_app_path_), std::move(pkg_type_), std::move(app_type_), std::move(hwacc_), std::move(taskmanage_), std::move(pkg_id_), std::move(comp_type_), std::move(internal_pool_), std::move(root_path_), - std::move(loader_name_), global_, std::move(b_)); + std::move(loader_name_), fast_launch_, global_, std::move(b_)); } AppInfo* AppInfo::Create(tizen_base::Bundle b) { @@ -121,6 +130,7 @@ AppInfo* AppInfo::Create(tizen_base::Bundle b) { .SetInternalPool(b) .SetRootPath(b) .SetLoaderName(b) + .SetFastLaunch(b) .SetGlobal(b) .SetBundle(std::move(b)); } @@ -173,6 +183,10 @@ const std::string& AppInfo::GetLoaderName() const { return loader_name_; } +const bool AppInfo::IsFastLaunch() const { + return fast_launch_; +} + const bool AppInfo::IsGlobal() const { return global_; } @@ -194,6 +208,7 @@ void AppInfo::WriteToParcel(tizen_base::Parcel* parcel) const { parcel->WriteString(internal_pool_); parcel->WriteString(root_path_); parcel->WriteString(loader_name_); + parcel->WriteBool(fast_launch_); parcel->WriteBool(global_); bundle_raw* b_raw = nullptr; @@ -217,6 +232,7 @@ void AppInfo::ReadFromParcel(tizen_base::Parcel* parcel) { internal_pool_ = parcel->ReadString(); root_path_ = parcel->ReadString(); loader_name_ = parcel->ReadString(); + parcel->ReadBool(&fast_launch_); parcel->ReadBool(&global_); auto raw = parcel->ReadString(); @@ -228,7 +244,8 @@ AppInfo::AppInfo(std::string app_id, std::string app_path, std::string original_app_path, std::string pkg_type, std::string app_type, std::string hwacc, std::string taskmanage, std::string pkg_id, std::string comp_type, std::string internal_pool, std::string root_path, - std::string loader_name, bool global, tizen_base::Bundle b) + std::string loader_name, bool fast_launch, bool global, + tizen_base::Bundle b) : app_id_(std::move(app_id)), app_path_(std::move(app_path)), original_app_path_(std::move(original_app_path)), @@ -241,6 +258,7 @@ AppInfo::AppInfo(std::string app_id, std::string app_path, internal_pool_(std::move(internal_pool)), root_path_(std::move(root_path)), loader_name_(std::move(loader_name)), + fast_launch_(fast_launch), global_(global), b_(std::move(b)) {} diff --git a/src/lib/launchpad-glib/app_info.hh b/src/lib/launchpad-glib/app_info.hh index a76a862..bfafe73 100644 --- a/src/lib/launchpad-glib/app_info.hh +++ b/src/lib/launchpad-glib/app_info.hh @@ -46,6 +46,7 @@ class EXPORT_API AppInfo : public tizen_base::Parcelable { Builder& SetInternalPool(const tizen_base::Bundle& b); Builder& SetRootPath(const tizen_base::Bundle& b); Builder& SetLoaderName(const tizen_base::Bundle& b); + Builder& SetFastLaunch(const tizen_base::Bundle& b); Builder& SetGlobal(const tizen_base::Bundle& b); Builder& SetBundle(tizen_base::Bundle b); operator AppInfo*(); @@ -63,7 +64,8 @@ class EXPORT_API AppInfo : public tizen_base::Parcelable { std::string internal_pool_; std::string root_path_; std::string loader_name_; - bool global_; + bool fast_launch_ = false; + bool global_ = true; tizen_base::Bundle b_; }; @@ -84,6 +86,7 @@ class EXPORT_API AppInfo : public tizen_base::Parcelable { const std::string& GetInternalPool() const; const std::string& GetRootPath() const; const std::string& GetLoaderName() const; + const bool IsFastLaunch() const; const bool IsGlobal() const; const tizen_base::Bundle& GetBundle() const; @@ -95,7 +98,8 @@ class EXPORT_API AppInfo : public tizen_base::Parcelable { std::string original_app_path, std::string pkg_type, std::string app_type, std::string hwacc, std::string taskmanage, std::string pkg_id, std::string comp_type, std::string internal_pool, std::string root_path, - std::string loader_name, bool global, tizen_base::Bundle b); + std::string loader_name, bool fast_launch, bool global, + tizen_base::Bundle b); private: std::string app_id_; @@ -110,6 +114,7 @@ class EXPORT_API AppInfo : public tizen_base::Parcelable { std::string internal_pool_; std::string root_path_; std::string loader_name_; + bool fast_launch_ = false; bool global_ = true; tizen_base::Bundle b_; }; diff --git a/src/lib/launchpad-glib/util.cc b/src/lib/launchpad-glib/util.cc index 2e79382..e13ff46 100644 --- a/src/lib/launchpad-glib/util.cc +++ b/src/lib/launchpad-glib/util.cc @@ -16,6 +16,7 @@ #include "launchpad-glib/util.hh" +#include #include #include #include @@ -316,12 +317,23 @@ class ExternalPackage : public DBus { class AmdPacket : public tizen_base::Parcelable { public: - explicit AmdPacket(int cmd) : cmd_(cmd) {} + explicit AmdPacket(int cmd, bundle* request, int opt) + : cmd_(cmd), request_(request), opt_(opt) {} void WriteToParcel(tizen_base::Parcel* parcel) const { parcel->WriteInt32(cmd_); - parcel->WriteInt32(0); - parcel->WriteInt32(0); + if (request_ == nullptr) { + parcel->WriteInt32(0); + parcel->WriteInt32(opt_); + } else { + bundle_raw* raw = nullptr; + int len = 0; + bundle_encode(request_, &raw, &len); + parcel->WriteInt32(len); + parcel->WriteInt32(opt_); + parcel->Write(reinterpret_cast(raw), len); + bundle_free_encoded_rawdata(&raw); + } } void ReadFromParcel(tizen_base::Parcel* parcel) { @@ -329,7 +341,9 @@ class AmdPacket : public tizen_base::Parcelable { } private: - int cmd_; + int cmd_ = -1; + bundle* request_ = nullptr; + int opt_ = 0; }; } // namespace @@ -548,6 +562,10 @@ int Util::PrepareAppIdFile(const AppInfo* app_info) { } int Util::SendCmdToAmd(enum AmdCmd cmd) { + return SendCmdToAmd(cmd, nullptr, static_cast(AmdSocketOption::None)); +} + +int Util::SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt) { try { std::string endpoint = "/run/aul/daemons/.amd-sock"; ClientSocket socket; @@ -555,7 +573,7 @@ int Util::SendCmdToAmd(enum AmdCmd cmd) { socket.SetReceiveBufferSize(Socket::kSocketMaxBufferSize); socket.SetReceiveTimeout(5000); - AmdPacket packet(static_cast(cmd)); + AmdPacket packet(static_cast(cmd), request, opt); tizen_base::Parcel parcel; parcel.WriteParcelable(packet); diff --git a/src/lib/launchpad-glib/util.hh b/src/lib/launchpad-glib/util.hh index 013581c..07713ac 100644 --- a/src/lib/launchpad-glib/util.hh +++ b/src/lib/launchpad-glib/util.hh @@ -17,6 +17,7 @@ #ifndef LIB_LAUNCHPAD_GLIB_UTIL_HH_ #define LIB_LAUNCHPAD_GLIB_UTIL_HH_ +#include #include #include @@ -46,6 +47,7 @@ class EXPORT_API Util { static int PrepareAppSocket(); static int PrepareAppIdFile(const AppInfo* app_info); static int SendCmdToAmd(enum AmdCmd cmd); + static int SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt); }; } // namespace launchpad -- 2.7.4 From 478fb2dadec7fa08b778f07bcc1d0fffa8fd1343 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 2 Jan 2024 19:22:56 +0900 Subject: [PATCH 08/16] Release version 0.38.26 Changes: - Register application info when ping delivered Change-Id: I35a390f1a43b48c8f678dfc3d7d52f25174933e5 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 94f1e11..5b2514a 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.25 +Version: 0.38.26 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 29086ece9e18efc76b9d729bf53b9295a045f4c3 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 8 Jan 2024 13:21:11 +0900 Subject: [PATCH 09/16] Remove MCJ file for dotnet apps The pal layer of coreclr creates the temporary file. If the process is terminated by SIGKILL, the file is not deleted normally. To prevent SMACK issue, the launchpad-process-pool removes the MCJ file. Change-Id: I63eac7ee30008195ff9dcd5572b7c3222d83501b Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/signal_manager.cc | 21 +++++++++++++++++---- src/launchpad-process-pool/signal_manager.hh | 7 +++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/launchpad-process-pool/signal_manager.cc b/src/launchpad-process-pool/signal_manager.cc index 51fb638..124537e 100644 --- a/src/launchpad-process-pool/signal_manager.cc +++ b/src/launchpad-process-pool/signal_manager.cc @@ -53,17 +53,17 @@ class GarbageCollector : public launchpad::Worker::Job { } } - void DoAtFork() { - _W("pid: %d", pid_); + void DoAtFork() { + _W("pid: %d", pid_); try { std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" + - std::to_string(pid_); + std::to_string(pid_); DeleteSocketPath(fs::path(path)); DeleteUnusedFiles(); } catch (const std::filesystem::filesystem_error& e) { _E("Exception occurs. error(%s:%d)", e.what(), e.code().value()); } - } + } private: void DeleteSocketPath(const fs::path& path) { @@ -87,6 +87,19 @@ class GarbageCollector : public launchpad::Worker::Job { } void DeleteUnusedFiles() { + DeleteMCJFile(); + DeleteTmpFiles(); + } + + void DeleteMCJFile() { + std::string path = "/tmp/.dotnet/mcj/MCJ.TMP." + std::to_string(pid_); + if (access(path.c_str(), F_OK) == 0) { + _W("Remove file: %s", path.c_str()); + fs::remove(path); + } + } + + void DeleteTmpFiles() { std::vector files = { "clr-debug-pipe-" + std::to_string(pid_) + "-", "dotnet-diagnostic-" + std::to_string(pid_) + "-" diff --git a/src/launchpad-process-pool/signal_manager.hh b/src/launchpad-process-pool/signal_manager.hh index 66acf22..c535ee2 100644 --- a/src/launchpad-process-pool/signal_manager.hh +++ b/src/launchpad-process-pool/signal_manager.hh @@ -60,8 +60,11 @@ class SignalManager : public SigchldEvent::IEvent, SignalAction(int signo, struct sigaction action) : signo_(signo), action_(action) {} - int GetSigno() const { return signo_; }; - struct sigaction GetSigaction() const { return action_; }; + int GetSigno() const { return signo_; } + + struct sigaction GetSigaction() const { + return action_; + } private: int signo_; -- 2.7.4 From 2c0ba0c179869551d41112aa011006d4ae9f640e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 8 Jan 2024 13:31:35 +0900 Subject: [PATCH 10/16] Release version 0.38.27 Changes: - Remove MCJ file for dotnet apps Change-Id: I0004127a33fba04212db4c6aa39149c73e1a02bc Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 5b2514a..667853c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.26 +Version: 0.38.27 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 102b2e96623d858e84213a1ae176c251307286e7 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 19 Jan 2024 18:52:37 +0900 Subject: [PATCH 11/16] Mount gadget resource paths for NUIGadget After this patch is applied, the launchpad tries to mount the gadget resource package separately. And, the gadget packages will be mounted to the bin directory of the application. The 'loader-mount' process is added for mounting gadget packages. Change-Id: Id6c4e6b5a3525eb5cc8687fbb28b6292e895ff3e Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/app_executor.cc | 6 + src/launchpad-process-pool/hydra_loader_context.cc | 10 +- src/launchpad-process-pool/hydra_loader_context.hh | 3 +- src/launchpad-process-pool/loader_context.cc | 22 +- src/launchpad-process-pool/loader_context.hh | 7 +- src/launchpad-process-pool/loader_factory.cc | 19 +- src/launchpad-process-pool/loader_factory.hh | 11 +- src/launchpad-process-pool/loader_manager.cc | 22 +- src/launchpad-process-pool/loader_manager.hh | 5 + src/launchpad-process-pool/loader_mount.cc | 329 +++++++++++++++++++++ src/launchpad-process-pool/loader_mount.hh | 61 ++++ src/lib/launchpad-common/aul_keys.hh | 2 + src/lib/launchpad-glib/util.cc | 29 +- src/lib/launchpad-glib/util.hh | 1 + src/lib/launchpad/step_prepare_execution.cc | 7 + 15 files changed, 508 insertions(+), 26 deletions(-) create mode 100644 src/launchpad-process-pool/loader_mount.cc create mode 100644 src/launchpad-process-pool/loader_mount.hh diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc index afb2e94..c47d3cf 100644 --- a/src/launchpad-process-pool/app_executor.cc +++ b/src/launchpad-process-pool/app_executor.cc @@ -200,6 +200,12 @@ int AppExecutor::StepEnableTrustAnchor() { } int AppExecutor::StepMountResDir() { + int ret = Util::MountGadgetDirectories(app_info_->GetBundle()); + if (ret != 0) { + _E("Failed to mount gadget resources"); + return ret; + } + return Util::MountResourceDirectories(app_info_); } diff --git a/src/launchpad-process-pool/hydra_loader_context.cc b/src/launchpad-process-pool/hydra_loader_context.cc index a2d29db..88bbf6c 100644 --- a/src/launchpad-process-pool/hydra_loader_context.cc +++ b/src/launchpad-process-pool/hydra_loader_context.cc @@ -39,12 +39,14 @@ const int kSocketMaxBufferSize = 131071; HydraLoaderContext::Builder::operator LoaderContext*() { return new HydraLoaderContext(std::move(loader_info_), loader_id_, - caller_pid_, activated_); + caller_pid_, activated_, std::move(loader_mount_)); } -HydraLoaderContext::HydraLoaderContext(std::shared_ptr loader_info, - int loader_id, pid_t caller_pid, bool activated) - : LoaderContext(std::move(loader_info), loader_id, caller_pid, activated) { +HydraLoaderContext::HydraLoaderContext( + std::shared_ptr loader_info, int loader_id, pid_t caller_pid, + bool activated, std::shared_ptr loader_mount) + : LoaderContext(std::move(loader_info), loader_id, caller_pid, activated, + std::move(loader_mount)) { Listen(); } diff --git a/src/launchpad-process-pool/hydra_loader_context.hh b/src/launchpad-process-pool/hydra_loader_context.hh index 88f2fbd..2b5945d 100644 --- a/src/launchpad-process-pool/hydra_loader_context.hh +++ b/src/launchpad-process-pool/hydra_loader_context.hh @@ -33,7 +33,8 @@ class HydraLoaderContext : public LoaderContext { }; HydraLoaderContext(std::shared_ptr loader_info, int loader_id, - pid_t caller_pid, bool activated); + pid_t caller_pid, bool activated, + std::shared_ptr loader_mount); void Listen() override; void Dispose() override; diff --git a/src/launchpad-process-pool/loader_context.cc b/src/launchpad-process-pool/loader_context.cc index 10b2b87..513dc78 100644 --- a/src/launchpad-process-pool/loader_context.cc +++ b/src/launchpad-process-pool/loader_context.cc @@ -124,20 +124,27 @@ LoaderContext::Builder& LoaderContext::Builder::SetActive() { return *this; } +LoaderContext::Builder& LoaderContext::Builder::SetLoaderMount( + std::shared_ptr loader_mount) { + loader_mount_ = std::move(loader_mount); + return *this; +} + LoaderContext::Builder::operator LoaderContext*() { return new LoaderContext(std::move(loader_info_), loader_id_, caller_pid_, - activated_); + activated_, std::move(loader_mount_)); } LoaderContext::LoaderContext(std::shared_ptr loader_info, - int loader_id, pid_t caller_pid, bool activated) + int loader_id, pid_t caller_pid, bool activated, + std::shared_ptr loader_mount) : loader_info_(std::move(loader_info)), loader_id_(loader_id), caller_pid_(caller_pid), activated_(activated), - cpu_checker_( - new CPUChecker(loader_info_->GetCpuThresholdMax(), - loader_info_->GetCpuThresholdMin())), + loader_mount_(std::move(loader_mount)), + cpu_checker_(new CPUChecker(loader_info_->GetCpuThresholdMax(), + loader_info_->GetCpuThresholdMin())), score_(kWinScore) { auto& executable_file = loader_info_->GetExe(); if (executable_file != "null") { @@ -238,6 +245,11 @@ pid_t LoaderContext::Prepare() { } pid_t LoaderContext::Deploy(const AppInfo* app_info) { + if (loader_mount_) { + if (loader_mount_->Mount(pid_, app_info) != 0) + _E("Failed to attach resources to loader process"); + } + Util::DeleteSocketPath(pid_, getuid()); tizen_base::Parcel parcel; parcel.WriteParcelable(*app_info); diff --git a/src/launchpad-process-pool/loader_context.hh b/src/launchpad-process-pool/loader_context.hh index feaf15d..814ff4b 100644 --- a/src/launchpad-process-pool/loader_context.hh +++ b/src/launchpad-process-pool/loader_context.hh @@ -32,6 +32,7 @@ #include "launchpad-process-pool/cpu_checker.hh" #include "launchpad-process-pool/loader_info.hh" #include "launchpad-process-pool/launcher_info.hh" +#include "launchpad-process-pool/loader_mount.hh" namespace launchpad { @@ -46,6 +47,7 @@ class LoaderContext : public std::enable_shared_from_this, Builder& SetLoaderId(int loader_id); Builder& SetCallerPid(pid_t caller_pid); Builder& SetActive(); + Builder& SetLoaderMount(std::shared_ptr loader_mount); virtual operator LoaderContext*(); @@ -54,6 +56,7 @@ class LoaderContext : public std::enable_shared_from_this, int loader_id_ = 0; pid_t caller_pid_ = getpid(); bool activated_ = true; + std::shared_ptr loader_mount_; }; class IEvent { @@ -65,7 +68,8 @@ class LoaderContext : public std::enable_shared_from_this, }; LoaderContext(std::shared_ptr loader_info, int loader_id, - pid_t caller_pid, bool activated); + pid_t caller_pid, bool activated, + std::shared_ptr loader_mount); virtual ~LoaderContext(); virtual void Listen(); @@ -136,6 +140,7 @@ class LoaderContext : public std::enable_shared_from_this, int loader_id_; pid_t caller_pid_; bool activated_; + std::shared_ptr loader_mount_; std::unique_ptr cpu_checker_; unsigned int score_; std::string loader_extra_; diff --git a/src/launchpad-process-pool/loader_factory.cc b/src/launchpad-process-pool/loader_factory.cc index e62b8c3..5d9b604 100644 --- a/src/launchpad-process-pool/loader_factory.cc +++ b/src/launchpad-process-pool/loader_factory.cc @@ -75,7 +75,7 @@ LoaderFactory& LoaderFactory::GetInst() { } std::shared_ptr LoaderFactory::CreateLoaderContext( - LoaderInfoPtr info) { + LoaderInfoPtr info, std::shared_ptr loader_mount) { auto app_types = GetAppTypeString(info); int loader_id = static_cast((info->GetExe() == "null") ? PadLoaderId::Direct : PadLoaderId::Static); @@ -85,12 +85,14 @@ std::shared_ptr LoaderFactory::CreateLoaderContext( context = HydraLoaderContext::Builder() .SetLoaderInfo(std::move(info)) .SetLoaderId(loader_id) - .SetActive(); + .SetActive() + .SetLoaderMount(std::move(loader_mount)); } else { context = LoaderContext::Builder() .SetLoaderInfo(std::move(info)) .SetLoaderId(loader_id) - .SetActive(); + .SetActive() + .SetLoaderMount(std::move(loader_mount)); } } catch (const Exception& e) { _E("Exception occurs. error(%s)", e.what()); @@ -109,7 +111,7 @@ std::shared_ptr LoaderFactory::CreateLoaderContext( } std::shared_ptr LoaderFactory::CreateLoaderContext( - tizen_base::Bundle b) { + tizen_base::Bundle b, std::shared_ptr loader_mount) { auto caller_pid = b.GetString(kAulCallerPid); if (caller_pid.empty()) return nullptr; @@ -126,7 +128,8 @@ std::shared_ptr LoaderFactory::CreateLoaderContext( .SetLoaderInfo(std::move(loader_info)) .SetLoaderId(loader_id) .SetCallerPid(std::stoi(caller_pid)) - .SetActive(); + .SetActive() + .SetLoaderMount(std::move(loader_mount)); if (context == nullptr) return nullptr; } catch (const Exception& e) { @@ -138,7 +141,8 @@ std::shared_ptr LoaderFactory::CreateLoaderContext( } std::shared_ptr LoaderFactory::CreateLoaderContext( - LoaderInfoPtr info, pid_t caller_pid) { + LoaderInfoPtr info, pid_t caller_pid, + std::shared_ptr loader_mount) { int loader_id = MakeDynamicLoaderId(); LoaderContext* context; try { @@ -146,7 +150,8 @@ std::shared_ptr LoaderFactory::CreateLoaderContext( .SetLoaderInfo(std::move(info)) .SetLoaderId(loader_id) .SetCallerPid(caller_pid) - .SetActive(); + .SetActive() + .SetLoaderMount(std::move(loader_mount)); if (context == nullptr) return nullptr; } catch (const Exception& e) { diff --git a/src/launchpad-process-pool/loader_factory.hh b/src/launchpad-process-pool/loader_factory.hh index f44da2c..2208c82 100644 --- a/src/launchpad-process-pool/loader_factory.hh +++ b/src/launchpad-process-pool/loader_factory.hh @@ -36,10 +36,13 @@ class LoaderFactory { static LoaderFactory& GetInst(); - std::shared_ptr CreateLoaderContext(LoaderInfoPtr info); - std::shared_ptr CreateLoaderContext(tizen_base::Bundle b); - std::shared_ptr CreateLoaderContext(LoaderInfoPtr info, - pid_t caller_pid); + std::shared_ptr CreateLoaderContext( + LoaderInfoPtr info, std::shared_ptr loader_mount); + std::shared_ptr CreateLoaderContext( + tizen_base::Bundle b, std::shared_ptr loader_mount); + std::shared_ptr CreateLoaderContext( + LoaderInfoPtr info, pid_t caller_pid, + std::shared_ptr loader_mount); private: LoaderFactory() = default; diff --git a/src/launchpad-process-pool/loader_manager.cc b/src/launchpad-process-pool/loader_manager.cc index 472d556..7632d39 100644 --- a/src/launchpad-process-pool/loader_manager.cc +++ b/src/launchpad-process-pool/loader_manager.cc @@ -43,6 +43,7 @@ void LoaderManager::Dispose() { if (disposed_) return; + loader_mount_.reset(); hwacc_config_.reset(); app_defined_loader_info_manager_.reset(); loader_info_manager_.reset(); @@ -65,6 +66,11 @@ void LoaderManager::Init() { app_defined_loader_info_manager_.reset(new AppDefinedLoaderInfoManager()); app_defined_loader_info_manager_->SetEventListener(this); hwacc_config_.reset(new HWAccelerationConfig()); + + if (!label_monitor.IsDisposed()) { + setenv("LOADER_MOUNT", "1", 1); + loader_mount_.reset(new LoaderMount()); + } } catch (const Exception& e) { _E("Exception occurs. error: %s", e.what()); return; @@ -73,6 +79,12 @@ void LoaderManager::Init() { disposed_ = false; } +void LoaderManager::PrepareApp(const std::shared_ptr& context, + const AppInfo* app_info) { + pid_t pid = context->GetPid(); + loader_mount_->Mount(pid, app_info); +} + void LoaderManager::SetEventListener(LoaderManager::IEvent* event_listener) { event_listener_ = event_listener; } @@ -94,6 +106,7 @@ void LoaderManager::HandleSigchld(pid_t pid) { RemoveLoaderContextsByCallerPid(pid); LoaderExecutor::GetInst().HandleSigchld(pid); + if (loader_mount_) loader_mount_->HandleSigchld(pid); } void LoaderManager::AddDefaultLoaderContexts() { @@ -101,7 +114,8 @@ void LoaderManager::AddDefaultLoaderContexts() { loader_info_manager_->Load(); for (auto& info : loader_info_manager_->GetLoaderInfoList()) { - auto context = LoaderFactory::GetInst().CreateLoaderContext(info); + auto context = + LoaderFactory::GetInst().CreateLoaderContext(info, loader_mount_); if (context != nullptr) { context->SetEventListener(this); loader_contexts_.push_back(std::move(context)); @@ -148,7 +162,8 @@ std::shared_ptr LoaderManager::PrepareAppDefinedLoaderContext( auto context = FindLoaderContextFromName(name); if (context == nullptr) { - context = LoaderFactory::GetInst().CreateLoaderContext(info, caller_pid); + context = LoaderFactory::GetInst().CreateLoaderContext(info, caller_pid, + loader_mount_); if (context == nullptr) { _E("Failed to create loader context. loader_name: %s", name.c_str()); @@ -166,7 +181,8 @@ std::shared_ptr LoaderManager::PrepareAppDefinedLoaderContext( std::shared_ptr LoaderManager::AddLoaderContext( tizen_base::Bundle b) { - auto context = LoaderFactory::GetInst().CreateLoaderContext(std::move(b)); + auto context = + LoaderFactory::GetInst().CreateLoaderContext(std::move(b), loader_mount_); if (context == nullptr) return nullptr; diff --git a/src/launchpad-process-pool/loader_manager.hh b/src/launchpad-process-pool/loader_manager.hh index 7f3f078..060c2c3 100644 --- a/src/launchpad-process-pool/loader_manager.hh +++ b/src/launchpad-process-pool/loader_manager.hh @@ -26,6 +26,7 @@ #include #include +#include #include #include "launchpad-process-pool/app_defined_loader_info_manager.hh" @@ -33,6 +34,7 @@ #include "launchpad-process-pool/hydra_loader_context.hh" #include "launchpad-process-pool/loader_context.hh" #include "launchpad-process-pool/loader_info.hh" +#include "launchpad-process-pool/loader_mount.hh" #include "launchpad-process-pool/memory_monitor.hh" #include "launchpad-process-pool/sequencer.hh" @@ -59,6 +61,8 @@ class LoaderManager : public AppDefinedLoaderInfoManager::IEvent, static LoaderManager& GetInst(); void Dispose(); + void PrepareApp(const std::shared_ptr& context, + const AppInfo* app_info); void SetEventListener(IEvent* event_listener); void HandleSigchld(pid_t pid); void AddDefaultLoaderContexts(); @@ -117,6 +121,7 @@ class LoaderManager : public AppDefinedLoaderInfoManager::IEvent, std::unique_ptr app_defined_loader_info_manager_; std::vector> loader_contexts_; std::unique_ptr hwacc_config_; + std::shared_ptr loader_mount_; }; } // namespace launchpad diff --git a/src/launchpad-process-pool/loader_mount.cc b/src/launchpad-process-pool/loader_mount.cc new file mode 100644 index 0000000..db264e8 --- /dev/null +++ b/src/launchpad-process-pool/loader_mount.cc @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2024 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-process-pool/loader_mount.hh" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "launchpad-process-pool/launchpad_args.hh" +#include "launchpad-process-pool/log_private.hh" + +namespace fs = std::filesystem; +namespace { + +bool IsExceptable(const std::string& path) { + static char buf[PATH_MAX]; + ssize_t len = readlink(path.c_str(), buf, sizeof(buf)); + if (len < 0) { + _E("readlink() is failed. errno: %d", errno); + return false; + } + + buf[len] = '\0'; + if (strstr(buf, "log") != nullptr || + strstr(buf, "trace") != nullptr || + strstr(buf, "dev") != nullptr) + return true; + + return false; +} + +std::vector GetExceptableFds() { + std::vector fds; + try { + fs::path proc_path("/proc/self/fd"); + for (const auto& entry : fs::directory_iterator(proc_path)) { + if (!isdigit(entry.path().filename().string()[0])) + continue; + + int fd = std::stoi(entry.path().filename().string()); + if (dlog_is_log_fd(fd) || IsExceptable(entry.path().string())) + fds.push_back(fd); + } + } catch (const fs::filesystem_error& e) { + _E("Exception occurs. error(%s)", e.what()); + } + + return fds; +} + +int ChangeMountNamespace(pid_t pid) { + std::string mnt_path = "/proc/" + std::to_string(pid) + "/ns/mnt"; + int fd = open(mnt_path.c_str(), O_RDONLY); + if (fd < 0) { + _E("open() is failed. path(%s), errno(%d)", mnt_path.c_str(), errno); + return -1; + } + + int ret = ::setns(fd, 0); + close(fd); + if (ret != 0) { + _E("setns() is failed. path(%s), errno(%d)", mnt_path.c_str(), errno); + return -1; + } + + _D("setns() is successful. pid(%d)", pid); + return 0; +} + +class Request : public tizen_base::Parcelable { + public: + explicit Request(tizen_base::Parcel* parcel) { ReadFromParcel(parcel); } + + Request(pid_t pid, tizen_base::Bundle b) : pid_(pid), b_(std::move(b)) {} + + pid_t GetPid() const { return pid_; } + + const tizen_base::Bundle& GetBundle() const { return b_; } + + void WriteToParcel(tizen_base::Parcel* parcel) const override { + parcel->WriteInt32(pid_); + bundle_raw* raw = nullptr; + int len = 0; + bundle_encode(b_.GetHandle(), &raw, &len); + parcel->WriteInt32(len); + parcel->Write(reinterpret_cast(raw), len); + bundle_free_encoded_rawdata(&raw); + } + + void ReadFromParcel(tizen_base::Parcel* parcel) override { + parcel->ReadInt32(&pid_); + int len = 0; + parcel->ReadInt32(&len); + if (len > 0) { + std::vector data(len); + parcel->Read(data.data(), data.size()); + b_ = tizen_base::Bundle( + bundle_decode(reinterpret_cast(data.data()), len), false, + true); + } + } + + private: + pid_t pid_; + tizen_base::Bundle b_; +}; + +class Reply : public tizen_base::Parcelable { + public: + explicit Reply(tizen_base::Parcel* parcel) { ReadFromParcel(parcel); } + + explicit Reply(int result) : result_(result) {} + + int GetResult() const { return result_; } + + void WriteToParcel(tizen_base::Parcel* parcel) const override { + parcel->WriteInt32(result_); + } + + void ReadFromParcel(tizen_base::Parcel* parcel) override { + parcel->ReadInt32(&result_); + } + + private: + int result_ = -1; +}; + +} // namespace + +namespace launchpad { + +LoaderMount::LoaderMount() : Executor(this), launchpad_ppid_(getppid()) { + Prepare(); +} + +LoaderMount::~LoaderMount() { Dispose(); } + +void LoaderMount::Prepare() { + if (pid_ > 0) return; + + int pipe_fd[2]; + if (CreatePipe(&pipe_fd) != 0) return; + + read_socket_.reset(new Socket(pipe_fd[0])); + int write_fd = pipe_fd[1]; + + if (CreatePipe(&pipe_fd) != 0) return; + + int read_fd = pipe_fd[0]; + write_socket_.reset(new Socket(pipe_fd[1])); + + _W("read_socket=%d, write_socket=%d", + read_socket_->GetFd(), write_socket_->GetFd()); + pid_ = Executor::Execute(); + if (pid_ == -1) { + _E("Failed to fork process. errno(%d)", errno); + close(read_fd); + close(write_fd); + return; + } + + read_socket_.reset(new Socket(read_fd)); + write_socket_.reset(new Socket(write_fd)); +} + +void LoaderMount::Dispose() { + read_socket_.reset(); + write_socket_.reset(); + if (pid_ > 0) { + if (kill(pid_, SIGKILL) == -1) + _E("Failed to send kill signal. pid(%d), errno(%d)", pid_, errno); + + pid_ = -1; + } +} + +void LoaderMount::HandleSigchld(pid_t pid) { + if (pid_ != pid) return; + + pid_ = -1; + Dispose(); + Prepare(); +} + +int LoaderMount::Mount(pid_t pid, const AppInfo* app_info) { + auto& b = app_info->GetBundle(); + if (b.GetType(kAulMountGadgetPaths) == BUNDLE_TYPE_NONE) return 0; + + tizen_base::Parcel parcel; + Request request(pid, b); + request.WriteToParcel(&parcel); + + _W("Send mount request"); + int ret = Write(parcel); + if (ret != 0) return ret; + + parcel.Clear(); + ret = Read(&parcel); + if (ret!= 0) return ret; + + _W("receive result"); + Reply reply(&parcel); + return reply.GetResult(); +} + +void LoaderMount::OnExecution() { + _D("Mount Manager"); + char** args = LaunchpadArgs::GetInst().GetArgs(); + size_t length = strlen(args[0]); + memset(args[0], '\0', length); + snprintf(args[0], length, "/usr/bin/loader-mount"); + + std::vector except_fds = GetExceptableFds(); + except_fds.push_back(read_socket_->GetFd()); + except_fds.push_back(write_socket_->GetFd()); + Util::CloseAllFds(except_fds); + int ret = ProcessRequests(); + exit(ret); +} + + +int LoaderMount::CreatePipe(int (*pipe_fd)[2]) { + *pipe_fd[0] = -1; + *pipe_fd[2] = -1; + + if (pipe(*pipe_fd) == -1) { + _E("pipe() is failed. errno(%d)", errno); + return -1; + } + + if (fcntl(*pipe_fd[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) + _E("Failed to set pipe size. errno(%d)", errno); + + if (fcntl(*pipe_fd[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) + _E("Failed to set pipe size. errno(%d)", errno); + + return 0; +} + +int LoaderMount::Write(const tizen_base::Parcel& parcel) { + size_t data_size = parcel.GetDataSize(); + int ret = + write_socket_->Write(static_cast(&data_size), sizeof(data_size)); + if (ret != 0) { + _E("Write() is failed. error(%d)", ret); + return -1; + } + + return write_socket_->Write(parcel.GetData(), parcel.GetDataSize()); +} + +int LoaderMount::Read(tizen_base::Parcel* parcel) { + size_t data_size = 0; + int ret = + read_socket_->Read(static_cast(&data_size), sizeof(data_size)); + if (ret != 0) { + _E("Read() is failed. error(%d)", ret); + return -1; + } + + std::vector data(data_size); + ret = read_socket_->Read(data.data(), data.size()); + if (ret != 0) { + _E("Read() is failed. error(%d)", ret); + return -1; + } + + parcel->Write(data.data(), data.size()); + return 0; +} + +int LoaderMount::ProcessRequests() { + tizen_base::Parcel parcel; + while (true) { + parcel.Clear(); + int ret = Read(&parcel); + if (ret != 0) continue; + + _W("Request received"); + Request request(&parcel); + ret = ChangeMountNamespace(request.GetPid()); + if (ret == 0) { + ret = Util::MountGadgetDirectories(request.GetBundle()); + ChangeMountNamespace(launchpad_ppid_); + } + + Reply reply(ret); + parcel.Clear(); + reply.WriteToParcel(&parcel); + Write(parcel); + } + + return 0; +} + +} // namespace launchpad diff --git a/src/launchpad-process-pool/loader_mount.hh b/src/launchpad-process-pool/loader_mount.hh new file mode 100644 index 0000000..6bc2274 --- /dev/null +++ b/src/launchpad-process-pool/loader_mount.hh @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 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 LAUNCHPAD_PROCESS_POOL_LOADER_MOUNT_HH_ +#define LAUNCHPAD_PROCESS_POOL_LOADER_MOUNT_HH_ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "launchpad-process-pool/executor.hh" + +namespace launchpad { + +class LoaderMount : public Executor::Delegator, public Executor { + public: + LoaderMount(); + virtual ~LoaderMount(); + + void Prepare(); + void Dispose(); + void HandleSigchld(pid_t pid); + + int Mount(pid_t pid, const AppInfo* app_info); + + private: + void OnExecution() override; + int CreatePipe(int (*pipe_fd)[2]); + int Write(const tizen_base::Parcel& parcel); + int Read(tizen_base::Parcel* parcel); + int ProcessRequests(); + + private: + pid_t launchpad_ppid_ = -1; + pid_t pid_ = -1; + std::unique_ptr read_socket_; + std::unique_ptr write_socket_; +}; + +} // namespace launchpad + +#endif // LAUNCHPAD_PROCESS_POOL_LOADER_MOUNT_HH_ diff --git a/src/lib/launchpad-common/aul_keys.hh b/src/lib/launchpad-common/aul_keys.hh index 61e1a69..b923aa4 100644 --- a/src/lib/launchpad-common/aul_keys.hh +++ b/src/lib/launchpad-common/aul_keys.hh @@ -54,6 +54,8 @@ constexpr const char kAulTaskManage[] = "__AUL_TASKMANAGE__"; constexpr const char kAulTepPath[] = "__AUL_TEP_PATH__"; constexpr const char kAulWaylandDisplay[] = "__AUL_WAYLAND_DISPLAY__"; constexpr const char kAulWaylandWorkingDir[] = "__AUL_WAYLAND_WORKING_DIR__"; +constexpr const char kAulMountGadgetPaths[] = "__AUL_MOUNT_GADGET_PATHS__"; +constexpr const char kAulMountGadgetPkgIds[] = "__AUL_MOUNT_GADGET_PKGIDS__"; } // namespace launchpad diff --git a/src/lib/launchpad-glib/util.cc b/src/lib/launchpad-glib/util.cc index e13ff46..b5861f6 100644 --- a/src/lib/launchpad-glib/util.cc +++ b/src/lib/launchpad-glib/util.cc @@ -95,6 +95,20 @@ void SetRegionFormatEnvironments() { setenv("LC_IDENTIFICATION", region, 1); } +void SetGadgetPkgIdsEnvironments(const tizen_base::Bundle& b) { + auto gadget_pkgids = b.GetStringArray(kAulMountGadgetPkgIds); + if (gadget_pkgids.empty()) return; + + std::string pkgids; + for (auto& pkgid : gadget_pkgids) { + if (!pkgids.empty()) pkgids += ":"; + + pkgids += pkgid; + } + + setenv("GADGET_PKGIDS", pkgids.c_str(), 1); +} + #ifdef TIZEN_FEATURE_SET_PERSONALITY_32 static void SetExecutionDomain() { int ret = personality(PER_LINUX32); @@ -241,7 +255,7 @@ class TepMountChecker : public DBus { std::vector paths_; }; -void MountDirectories(const std::vector& srcs, +int MountDirectories(const std::vector& srcs, const std::string& dest) { std::string opt = "lowerdir=" + dest; for (auto& src : srcs) @@ -251,6 +265,8 @@ void MountDirectories(const std::vector& srcs, int ret = mount(nullptr, dest.c_str(), "overlay", MS_RDONLY, opt.c_str()); if (ret != 0) _E("mount() is failed. dest(%s), errno(%d)", dest.c_str(), errno); + + return ret; } class ExternalPackage : public DBus { @@ -407,6 +423,7 @@ void Util::SetEnvironments(const AppInfo* app_info) { setenv("GCOV_PREFIX", "/tmp", 1); setenv("DALI_DISABLE_PARTIAL_UPDATE", "0", 1); + SetGadgetPkgIdsEnvironments(b); } void Util::DeleteSocketPath(pid_t pid, uid_t uid) { @@ -467,6 +484,16 @@ int Util::MountResourceDirectories(const AppInfo* app_info) { return 0; } +int Util::MountGadgetDirectories(const tizen_base::Bundle& b) { + auto gadget_paths = b.GetStringArray(kAulMountGadgetPaths); + if (!gadget_paths.empty()) { + auto root_path = b.GetString(kAulRootPath); + return MountDirectories(gadget_paths, root_path + "/bin"); + } + + return 0; +} + int Util::WaitTepMount(const AppInfo* app_info) { if (app_info->GetBundle().GetType(kAulTepPath) == BUNDLE_TYPE_NONE) return 0; diff --git a/src/lib/launchpad-glib/util.hh b/src/lib/launchpad-glib/util.hh index 07713ac..fa490fa 100644 --- a/src/lib/launchpad-glib/util.hh +++ b/src/lib/launchpad-glib/util.hh @@ -41,6 +41,7 @@ class EXPORT_API Util { static void DeleteSocketPath(pid_t pid, uid_t uid); static int EnableExternalPackage(const AppInfo* app_info); static int MountResourceDirectories(const AppInfo* app_info); + [[nodiscard]] static int MountGadgetDirectories(const tizen_base::Bundle& b); static int WaitTepMount(const AppInfo* app_info); static std::string GetLibDirectory(const std::string& app_path); static void CloseAllFds(const std::vector& except_fds = {}); diff --git a/src/lib/launchpad/step_prepare_execution.cc b/src/lib/launchpad/step_prepare_execution.cc index 1c19ce0..7da7fa3 100644 --- a/src/lib/launchpad/step_prepare_execution.cc +++ b/src/lib/launchpad/step_prepare_execution.cc @@ -98,6 +98,13 @@ int StepPrepareExecution::TrustAnchorLaunch(AppInfo* app_info) { } int StepPrepareExecution::MountResourceDirectories(AppInfo* app_info) { + if (getenv("LOADER_MOUNT") == nullptr) { + if (Util::MountGadgetDirectories(app_info->GetBundle()) != 0) { + _E("Failed to mount gadget resources"); + return -1; + } + } + int ret = Util::MountResourceDirectories(app_info); if (ret < 0) { _E("Failed to mount resource direstories. error: %d", ret); -- 2.7.4 From f65df2e79108161f8e244b9c4f35d14f865a46af Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 23 Jan 2024 12:52:04 +0900 Subject: [PATCH 12/16] Release version 0.39.0 Changes: - Mount gadget resource paths for NUIGadget Change-Id: Ief01323a30bfdf0a4e10e35ac68248e8f9b2425e Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 667853c..1870266 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.38.27 +Version: 0.39.0 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From c86f780bc9d17d835f911d662b9345b7a18da0d1 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 24 Jan 2024 07:59:51 +0900 Subject: [PATCH 13/16] Fix invalid access The array size is 2. Change-Id: If65b54963abee9d06ca7926aedd30be698371ca9 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/loader_mount.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad-process-pool/loader_mount.cc b/src/launchpad-process-pool/loader_mount.cc index db264e8..853a603 100644 --- a/src/launchpad-process-pool/loader_mount.cc +++ b/src/launchpad-process-pool/loader_mount.cc @@ -254,7 +254,7 @@ void LoaderMount::OnExecution() { int LoaderMount::CreatePipe(int (*pipe_fd)[2]) { *pipe_fd[0] = -1; - *pipe_fd[2] = -1; + *pipe_fd[1] = -1; if (pipe(*pipe_fd) == -1) { _E("pipe() is failed. errno(%d)", errno); -- 2.7.4 From 7735b4fcaff72fb970f62c25104aa13922a27fe8 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 24 Jan 2024 08:12:24 +0900 Subject: [PATCH 14/16] Release version 0.39.1 Changes: - Fix invalid access Change-Id: I9a8fb4ab6e48a615d3be0e6fe04ef82142be5e85 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 1870266..7047b08 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.39.0 +Version: 0.39.1 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4 From 0cd97536414fb4a27343ef74488617eb2cb7be6e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 24 Jan 2024 14:00:11 +0900 Subject: [PATCH 15/16] Fix crash issue Currently, __stack_chk_fail occurs by array accessment. Change-Id: I7e4aca03777c61b59a640c9a1e1bee8007dbc6e4 Signed-off-by: Hwankyu Jhun --- src/launchpad-process-pool/loader_mount.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/launchpad-process-pool/loader_mount.cc b/src/launchpad-process-pool/loader_mount.cc index 853a603..b31bb11 100644 --- a/src/launchpad-process-pool/loader_mount.cc +++ b/src/launchpad-process-pool/loader_mount.cc @@ -253,19 +253,19 @@ void LoaderMount::OnExecution() { int LoaderMount::CreatePipe(int (*pipe_fd)[2]) { - *pipe_fd[0] = -1; - *pipe_fd[1] = -1; + (*pipe_fd)[0] = -1; + (*pipe_fd)[1] = -1; if (pipe(*pipe_fd) == -1) { _E("pipe() is failed. errno(%d)", errno); return -1; } - if (fcntl(*pipe_fd[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) - _E("Failed to set pipe size. errno(%d)", errno); + if (fcntl((*pipe_fd)[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) + _E("Failed to set pipe size. pipe_fd(%d), errno(%d)", (*pipe_fd)[0], errno); - if (fcntl(*pipe_fd[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) - _E("Failed to set pipe size. errno(%d)", errno); + if (fcntl((*pipe_fd)[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1) + _E("Failed to set pipe size. pipe_fd(%d), errno(%d)", (*pipe_fd)[1], errno); return 0; } -- 2.7.4 From 6f6ec1b4c14c1894bdbea022b4162e32195107f2 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 24 Jan 2024 14:15:05 +0900 Subject: [PATCH 16/16] Release version 0.39.2 Changes: - Fix crash issue Change-Id: I674664a302d743944d8dae7bd2254417b5e93558 Signed-off-by: Hwankyu Jhun --- packaging/launchpad.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 7047b08..5b3c3c5 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -1,6 +1,6 @@ Name: launchpad Summary: Launchpad for launching applications -Version: 0.39.1 +Version: 0.39.2 Release: 1 Group: Application Framework/Daemons License: Apache-2.0 -- 2.7.4