}
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_);
}
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<LoaderInfo> 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<LoaderInfo> loader_info, int loader_id, pid_t caller_pid,
+ bool activated, std::shared_ptr<LoaderMount> loader_mount)
+ : LoaderContext(std::move(loader_info), loader_id, caller_pid, activated,
+ std::move(loader_mount)) {
Listen();
}
};
HydraLoaderContext(std::shared_ptr<LoaderInfo> loader_info, int loader_id,
- pid_t caller_pid, bool activated);
+ pid_t caller_pid, bool activated,
+ std::shared_ptr<LoaderMount> loader_mount);
void Listen() override;
void Dispose() override;
return *this;
}
+LoaderContext::Builder& LoaderContext::Builder::SetLoaderMount(
+ std::shared_ptr<LoaderMount> 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<LoaderInfo> loader_info,
- int loader_id, pid_t caller_pid, bool activated)
+ int loader_id, pid_t caller_pid, bool activated,
+ std::shared_ptr<LoaderMount> 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") {
}
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);
#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 {
Builder& SetLoaderId(int loader_id);
Builder& SetCallerPid(pid_t caller_pid);
Builder& SetActive();
+ Builder& SetLoaderMount(std::shared_ptr<LoaderMount> loader_mount);
virtual operator LoaderContext*();
int loader_id_ = 0;
pid_t caller_pid_ = getpid();
bool activated_ = true;
+ std::shared_ptr<LoaderMount> loader_mount_;
};
class IEvent {
};
LoaderContext(std::shared_ptr<LoaderInfo> loader_info, int loader_id,
- pid_t caller_pid, bool activated);
+ pid_t caller_pid, bool activated,
+ std::shared_ptr<LoaderMount> loader_mount);
virtual ~LoaderContext();
virtual void Listen();
int loader_id_;
pid_t caller_pid_;
bool activated_;
+ std::shared_ptr<LoaderMount> loader_mount_;
std::unique_ptr<CPUChecker> cpu_checker_;
unsigned int score_;
std::string loader_extra_;
}
std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
- LoaderInfoPtr info) {
+ LoaderInfoPtr info, std::shared_ptr<LoaderMount> loader_mount) {
auto app_types = GetAppTypeString(info);
int loader_id = static_cast<int>((info->GetExe() == "null") ?
PadLoaderId::Direct : PadLoaderId::Static);
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());
}
std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
- tizen_base::Bundle b) {
+ tizen_base::Bundle b, std::shared_ptr<LoaderMount> loader_mount) {
auto caller_pid = b.GetString(kAulCallerPid);
if (caller_pid.empty())
return nullptr;
.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) {
}
std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
- LoaderInfoPtr info, pid_t caller_pid) {
+ LoaderInfoPtr info, pid_t caller_pid,
+ std::shared_ptr<LoaderMount> loader_mount) {
int loader_id = MakeDynamicLoaderId();
LoaderContext* context;
try {
.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) {
static LoaderFactory& GetInst();
- std::shared_ptr<LoaderContext> CreateLoaderContext(LoaderInfoPtr info);
- std::shared_ptr<LoaderContext> CreateLoaderContext(tizen_base::Bundle b);
- std::shared_ptr<LoaderContext> CreateLoaderContext(LoaderInfoPtr info,
- pid_t caller_pid);
+ std::shared_ptr<LoaderContext> CreateLoaderContext(
+ LoaderInfoPtr info, std::shared_ptr<LoaderMount> loader_mount);
+ std::shared_ptr<LoaderContext> CreateLoaderContext(
+ tizen_base::Bundle b, std::shared_ptr<LoaderMount> loader_mount);
+ std::shared_ptr<LoaderContext> CreateLoaderContext(
+ LoaderInfoPtr info, pid_t caller_pid,
+ std::shared_ptr<LoaderMount> loader_mount);
private:
LoaderFactory() = default;
if (disposed_)
return;
+ loader_mount_.reset();
hwacc_config_.reset();
app_defined_loader_info_manager_.reset();
loader_info_manager_.reset();
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;
disposed_ = false;
}
+void LoaderManager::PrepareApp(const std::shared_ptr<LoaderContext>& 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;
}
RemoveLoaderContextsByCallerPid(pid);
LoaderExecutor::GetInst().HandleSigchld(pid);
+ if (loader_mount_) loader_mount_->HandleSigchld(pid);
}
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));
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());
std::shared_ptr<LoaderContext> 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;
#include <string_view>
#include <vector>
+#include <app_info.hh>
#include <hw_acceleration_config.hh>
#include "launchpad-process-pool/app_defined_loader_info_manager.hh"
#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"
static LoaderManager& GetInst();
void Dispose();
+ void PrepareApp(const std::shared_ptr<LoaderContext>& context,
+ const AppInfo* app_info);
void SetEventListener(IEvent* event_listener);
void HandleSigchld(pid_t pid);
void AddDefaultLoaderContexts();
std::unique_ptr<AppDefinedLoaderInfoManager> app_defined_loader_info_manager_;
std::vector<std::shared_ptr<LoaderContext>> loader_contexts_;
std::unique_ptr<HWAccelerationConfig> hwacc_config_;
+ std::shared_ptr<LoaderMount> loader_mount_;
};
} // namespace launchpad
--- /dev/null
+/*
+ * 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 <bundle_cpp.h>
+#include <bundle_internal.h>
+#include <dlog-redirect-stdout.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <aul_keys.hh>
+#include <exception.hh>
+#include <parcelable.hh>
+#include <util.hh>
+
+#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<int> GetExceptableFds() {
+ std::vector<int> 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<unsigned char*>(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<uint8_t> data(len);
+ parcel->Read(data.data(), data.size());
+ b_ = tizen_base::Bundle(
+ bundle_decode(reinterpret_cast<bundle_raw*>(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<int> 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<void*>(&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<void*>(&data_size), sizeof(data_size));
+ if (ret != 0) {
+ _E("Read() is failed. error(%d)", ret);
+ return -1;
+ }
+
+ std::vector<uint8_t> 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
--- /dev/null
+/*
+ * 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 <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <app_info.hh>
+#include <parcel.hh>
+#include <socket.hh>
+
+#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<Socket> read_socket_;
+ std::unique_ptr<Socket> write_socket_;
+};
+
+} // namespace launchpad
+
+#endif // LAUNCHPAD_PROCESS_POOL_LOADER_MOUNT_HH_
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
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);
std::vector<std::string> paths_;
};
-void MountDirectories(const std::vector<std::string>& srcs,
+int MountDirectories(const std::vector<std::string>& srcs,
const std::string& dest) {
std::string opt = "lowerdir=" + dest;
for (auto& src : 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 {
setenv("GCOV_PREFIX", "/tmp", 1);
setenv("DALI_DISABLE_PARTIAL_UPDATE", "0", 1);
+ SetGadgetPkgIdsEnvironments(b);
}
void Util::DeleteSocketPath(pid_t pid, uid_t uid) {
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;
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<int>& except_fds = {});
}
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);