Add a class to unshare/attach the namespaces of process 61/132161/1
authorSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 31 May 2017 06:43:54 +0000 (15:43 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Thu, 1 Jun 2017 09:04:59 +0000 (18:04 +0900)
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
Change-Id: Id599317957a08a0ae8806af2460223ac9341d14c

include/klay/namespace.h [new file with mode: 0644]
src/CMakeLists.txt
src/namespace.cpp [new file with mode: 0644]

diff --git a/include/klay/namespace.h b/include/klay/namespace.h
new file mode 100644 (file)
index 0000000..1a1a60e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  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>
+
+namespace runtime {
+
+class Namespace final {
+public:
+       Namespace() = delete;
+
+       static void unshare(int flags);
+       static void attach(const pid_t pid);
+};
+
+} // namespace runtime
+
+#endif //!__RUNTIME_NAMESPACE_H__
index 3c1339637408ea1cf9ead3258e14df3880f0f964..1e5f8ec78b0cda9e65f205f8d234f614cdfa368e 100755 (executable)
@@ -17,6 +17,7 @@ SET (KLAY_SOURCES             ${KLAY_SRC}/error.cpp
                                                ${KLAY_SRC}/process.cpp
                                                ${KLAY_SRC}/eventfd.cpp
                                                ${KLAY_SRC}/mainloop.cpp
+                                               ${KLAY_SRC}/namespace.cpp
                                                ${KLAY_SRC}/testbench.cpp
                                                ${KLAY_SRC}/file-user.cpp
                                                ${KLAY_SRC}/filesystem.cpp
diff --git a/src/namespace.cpp b/src/namespace.cpp
new file mode 100644 (file)
index 0000000..c52d9d4
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  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 <klay/namespace.h>
+
+namespace runtime {
+
+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 runtime::Exception("Failed to open namesapce: " + nspath);
+                       }
+               } else {
+                       if (::setns(fd, ns.second)) {
+                               ::close(fd);
+                               throw runtime::Exception("Failed to set namespace: " + nspath);
+                       }
+                       ::close(fd);
+               }
+       }
+}
+
+void Namespace::unshare(int flags)
+{
+       if (::unshare(flags)) {
+               throw runtime::Exception("Failed to unshare namespace");
+       }
+
+       if (flags & CLONE_NEWNS &&
+                       ::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
+               throw runtime::Exception("Failed to mount root filesystem");
+       }
+}
+
+} // namespace runtime