summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSungbae Yoo <sungbae.yoo@samsung.com>2019-01-17 12:25:51 +0900
committerSungbae Yoo <sungbae.yoo@samsung.com>2019-01-29 11:56:38 +0900
commit2515a6ccc00a3714f1b550ba07d2a0d2cc63c808 (patch)
treeae8baef8c56250a4050858102906ab7096c3a35a
parent6da10ac6e17527f08099c7667749b6bd400c5b05 (diff)
downloadlibkrate-accepted/tizen_unified.tar.gz
libkrate-accepted/tizen_unified.tar.bz2
libkrate-accepted/tizen_unified.zip
It moves several classes such as Cgroup, Namespace. Change-Id: I27a13b19b216ad0d1bd818808166951ca1f57806 Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
-rwxr-xr-xCMakeLists.txt5
-rw-r--r--common/cgroup.cpp215
-rw-r--r--common/cgroup.h43
-rw-r--r--common/namespace.cpp77
-rw-r--r--common/namespace.h30
-rw-r--r--tools/cli/CMakeLists.txt7
-rw-r--r--tools/cli/krate-admin-cli.cpp17
7 files changed, 380 insertions, 14 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0cddac1..4699294 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ SET(KRATE_API ${PROJECT_SOURCE_DIR}/api)
SET(KRATE_LIB ${PROJECT_SOURCE_DIR}/lib)
SET(KRATE_TOOLS ${PROJECT_SOURCE_DIR}/tools)
SET(KRATE_MODULE ${PROJECT_SOURCE_DIR}/module)
+SET(KRATE_COMMON ${PROJECT_SOURCE_DIR}/common)
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
SET(CXX_STD "c++0x")
@@ -69,10 +70,6 @@ IF(NOT DEFINED HOME_DIR)
SET(HOME_DIR "/home")
ENDIF(NOT DEFINED HOME_DIR)
-IF(NOT DEFINED PAMD_DIR)
- SET(PAMD_DIR "${SYSCONF_INSTALL_DIR}/pam.d")
-ENDIF(NOT DEFINED PAMD_DIR)
-
IF(NOT DEFINED SYSTEMD_UNIT_DIR)
SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system")
ENDIF(NOT DEFINED SYSTEMD_UNIT_DIR)
diff --git a/common/cgroup.cpp b/common/cgroup.cpp
new file mode 100644
index 0000000..8276f46
--- /dev/null
+++ b/common/cgroup.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2015 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 <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#include <regex>
+#include <fstream>
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+
+#include "cgroup.h"
+
+#define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_-]*"
+#define PATH_PATTERN "(/*[A-Za-z_][A-Za-z0-9_-]*)*"
+
+bool Cgroup::existSubsystem(const std::string& name)
+{
+ try {
+ if (!std::regex_match(name, std::regex(NAME_PATTERN))) {
+ return false;
+ }
+ } catch (std::runtime_error &e) {
+ throw klay::Exception("Unexpected regex error");
+ }
+
+ klay::File dir("/sys/fs/cgroup/" + name);
+ if (dir.exists()) {
+ if (dir.isDirectory()) {
+ return true;
+ }
+ throw klay::Exception("Invalid subsystem name");
+ }
+
+ return false;
+}
+
+void Cgroup::createSubsystem(const std::string& name)
+{
+ try {
+ if (!std::regex_match(name, std::regex(NAME_PATTERN))) {
+ throw klay::Exception("Invalid subsystem name");
+ }
+ } catch (std::runtime_error &e) {
+ throw klay::Exception("Unexpected regex error");
+ }
+
+ if (existSubsystem(name)) {
+ return;
+ }
+
+ klay::File subsystem("/sys/fs/cgroup/" + name);
+ if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT |
+ MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
+ "mode=755")) {
+ throw klay::Exception("Failed to remount cgroupfs as the writable");
+ }
+
+ if (!subsystem.exists()) {
+ subsystem.makeDirectory(true);
+ }
+
+ if (::mount(name.c_str(), subsystem.getPath().c_str(),
+ "cgroup", MS_NODEV | MS_NOSUID | MS_NOEXEC,
+ ("none,name=" + name).c_str())) {
+ subsystem.remove(false);
+ throw klay::Exception("Failed to mount cgroup subsystem");
+ }
+
+ if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | MS_RDONLY |
+ MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
+ "mode=755")) {
+ throw klay::Exception("Failed to remount cgroupfs as the read-only");
+ }
+}
+
+void Cgroup::destroySubsystem(const std::string& name)
+{
+ if (!existSubsystem(name)) {
+ throw klay::Exception("No such subsystem");
+ }
+
+ if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT |
+ MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
+ "mode=755")) {
+ throw klay::Exception("Failed to remount cgroupfs as the writable");
+ }
+
+ klay::File subsystem("/sys/fs/cgroup/" + name);
+ ::umount2(subsystem.getPath().c_str(), MNT_EXPIRE);
+
+ subsystem.remove(false);
+
+ if (::mount(NULL, "/sys/fs/cgroup/", NULL, MS_REMOUNT | MS_RDONLY |
+ MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
+ "mode=755")) {
+ throw klay::Exception("Failed to remount cgroupfs as the read-only");
+ }
+}
+
+bool Cgroup::exist(const std::string& subsystem, const std::string& path)
+{
+ try {
+ if (!std::regex_match(path, std::regex(PATH_PATTERN))) {
+ return false;
+ }
+ } catch (std::runtime_error &e) {
+ throw klay::Exception("Unexpected regex error");
+ }
+
+ klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path);
+ if (dir.exists()) {
+ if (dir.isDirectory()) {
+ return true;
+ }
+ throw klay::Exception("Invalid path");
+ }
+
+ return false;
+}
+
+void Cgroup::create(const std::string& subsystem, const std::string& path)
+{
+ try {
+ if (!std::regex_match(path, std::regex(PATH_PATTERN))) {
+ throw klay::Exception("Invalid path");
+ }
+ } catch (std::runtime_error &e) {
+ throw klay::Exception("Unexpected regex error");
+ }
+
+ if (exist(subsystem, path)) {
+ return;
+ }
+
+ klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path);
+ dir.makeDirectory(true);
+}
+
+void Cgroup::destroy(const std::string& subsystem, const std::string& path)
+{
+ if (!exist(subsystem, path)) {
+ throw klay::Exception("No such path in subsystem");
+ }
+
+ klay::File dir("/sys/fs/cgroup/" + subsystem + "/" + path);
+ dir.remove(false);
+}
+
+void Cgroup::addProcess(const std::string& subsystem, const std::string& path, const pid_t pid)
+{
+ if (!exist(subsystem, path)) {
+ throw klay::Exception("No such path in subsystem");
+ }
+
+ std::ofstream ofs("/sys/fs/cgroup/" + subsystem + "/" + path +
+ "/tasks");
+
+ ofs << pid << std::endl;
+}
+
+std::vector<pid_t> Cgroup::getProcessList(const std::string& subsystem, const std::string& path)
+{
+ std::vector<pid_t> ret;
+ std::ifstream ifs("/sys/fs/cgroup/" + subsystem + "/" + path +
+ "/tasks");
+
+ pid_t pid;
+
+ ifs >> pid;
+
+ while (ifs.good()) {
+ ret.push_back(pid);
+ ifs >> pid;
+ }
+
+ return ret;
+}
+
+const std::string Cgroup::getPath(const std::string& subsystem, const pid_t pid)
+{
+ std::ifstream ifs("/proc/" + std::to_string(pid) + "/cgroup");
+ std::string ret = "/", line;
+
+ while (std::getline(ifs, line)) {
+ std::stringstream lineStream(line);
+ std::string name;
+
+ //the first getline is for removing the first argument
+ std::getline(lineStream, name, ':');
+ std::getline(lineStream, name, ':');
+
+ if (name == subsystem || name == "name=" + subsystem) {
+ ret = line.substr(line.find('/'));
+ }
+ }
+ return ret;
+}
diff --git a/common/cgroup.h b/common/cgroup.h
new file mode 100644
index 0000000..63994cd
--- /dev/null
+++ b/common/cgroup.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 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 __COMMON_CGROUP_H__
+#define __COMMON_CGROUP_H__
+
+#include <string>
+#include <vector>
+
+class Cgroup final {
+public:
+ Cgroup() = delete;
+
+ static bool existSubsystem(const std::string& name);
+ static void createSubsystem(const std::string& name);
+ static void destroySubsystem(const std::string& name);
+
+ static bool exist(const std::string& subsystem, const std::string& path);
+ static void create(const std::string& subsystem, const std::string& path);
+ static void destroy(const std::string& subsystem, const std::string& path);
+
+ static void addProcess(const std::string& subsystem,
+ const std::string& path, const pid_t pid);
+ static std::vector<pid_t> getProcessList(const std::string& subsystem,
+ const std::string& path);
+
+ static const std::string getPath(const std::string& subsystem, const pid_t pid);
+};
+
+#endif //!__RUNTIME_CGROUP_H__
diff --git a/common/namespace.cpp b/common/namespace.cpp
new file mode 100644
index 0000000..fdcd1b5
--- /dev/null
+++ b/common/namespace.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015 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 <vector>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mount.h>
+
+#include <klay/exception.h>
+
+#include "namespace.h"
+
+namespace {
+
+typedef std::pair<std::string, int> NamespacePair;
+std::vector<NamespacePair> namespaces = {
+ {"mnt", CLONE_NEWNS},
+ {"net", CLONE_NEWNET},
+ {"ipc", CLONE_NEWIPC},
+ {"pid", CLONE_NEWPID},
+ {"uts", CLONE_NEWUTS},
+ {"user", CLONE_NEWUSER},
+#ifdef CLONE_NEWCGROUP
+ {"cgroup", CLONE_NEWCGROUP},
+#endif
+};
+
+} // namespace
+
+void Namespace::attach(const pid_t pid)
+{
+ for (const NamespacePair& ns : namespaces) {
+ std::string nspath = "/proc/" + std::to_string(pid) + "/ns/" + ns.first;
+
+ int fd;
+ do {
+ fd = ::open(nspath.c_str(), O_RDONLY);
+ } while (fd == -1 && errno == EINTR);
+
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ throw klay::Exception("Failed to open namesapce: " + nspath);
+ }
+ } else {
+ if (::setns(fd, ns.second)) {
+ ::close(fd);
+ throw klay::Exception("Failed to set namespace: " + nspath);
+ }
+ ::close(fd);
+ }
+ }
+}
+
+void Namespace::unshare(int flags)
+{
+ if (::unshare(flags)) {
+ throw klay::Exception("Failed to unshare namespace");
+ }
+
+ if (flags & CLONE_NEWNS &&
+ ::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
+ throw klay::Exception("Failed to mount root filesystem");
+ }
+}
diff --git a/common/namespace.h b/common/namespace.h
new file mode 100644
index 0000000..bc9368c
--- /dev/null
+++ b/common/namespace.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 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 __RUNTIME_NAMESPACE_H__
+#define __RUNTIME_NAMESPACE_H__
+
+#include <sched.h>
+
+class Namespace final {
+public:
+ Namespace() = delete;
+
+ static void unshare(int flags);
+ static void attach(const pid_t pid);
+};
+
+#endif //!__RUNTIME_NAMESPACE_H__
diff --git a/tools/cli/CMakeLists.txt b/tools/cli/CMakeLists.txt
index d688ce0..a1cdb51 100644
--- a/tools/cli/CMakeLists.txt
+++ b/tools/cli/CMakeLists.txt
@@ -14,7 +14,10 @@
# limitations under the License.
#
-FILE(GLOB CLI_SRCS krate-admin-cli.cpp)
+FILE(GLOB CLI_SRCS krate-admin-cli.cpp
+ ${KRATE_COMMON}/cgroup.cpp
+ ${KRATE_COMMON}/namespace.cpp
+)
SET(CLI_NAME ${PROJECT_NAME}-admin-cli)
@@ -33,7 +36,7 @@ PKG_CHECK_MODULES(CLI_DEPS REQUIRED
capi-appfw-package-manager
)
-INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${KRATE_MODULE} ${KRATE_LIB})
+INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${KRATE_MODULE} ${KRATE_LIB} ${PROJECT_SOURCE_DIR})
TARGET_LINK_LIBRARIES(${CLI_NAME} ${CLI_DEPS_LIBRARIES} krate)
INSTALL(TARGETS ${CLI_NAME} DESTINATION sbin)
diff --git a/tools/cli/krate-admin-cli.cpp b/tools/cli/krate-admin-cli.cpp
index 29496d6..6620417 100644
--- a/tools/cli/krate-admin-cli.cpp
+++ b/tools/cli/krate-admin-cli.cpp
@@ -42,8 +42,6 @@
#include <iostream>
#include <functional>
-#include <klay/cgroup.h>
-#include <klay/namespace.h>
#include <klay/exception.h>
#include <klay/filesystem.h>
#include <klay/auth/user.h>
@@ -51,6 +49,9 @@
#include <krate/app-proxy.h>
#include <krate/package-proxy.h>
+#include "common/cgroup.h"
+#include "common/namespace.h"
+
#define DEFAULT_SETUP_WIZARD "org.tizen.krate-setup-wizard"
#define DEFAULT_SHELL "/bin/bash"
#define DEFAULT_MANIFEST "<?xml version='1.0' encoding='utf-8'?><manifest version='0.1.0' />"
@@ -321,20 +322,20 @@ int attachToKrate(const std::string& name, char* args[])
std::string path = CGROUP_SUBSYSTEM "/" + name;
pid_t pid = 0;
- if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
- auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
+ if (Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
+ auto pids = Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
if (pids.size() > 0) {
pid = pids[0];
}
} else {
- runtime::Cgroup::create(CGROUP_SUBSYSTEM, path);
+ Cgroup::create(CGROUP_SUBSYSTEM, path);
}
if (pid == 0) {
- runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
- runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
+ Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
+ Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
} else {
- runtime::Namespace::attach(pid);
+ Namespace::attach(pid);
}
launchProcess(user, args);