Add klay-legacy classes into this repository 90/197890/2
authorSungbae Yoo <sungbae.yoo@samsung.com>
Thu, 17 Jan 2019 03:26:57 +0000 (12:26 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Tue, 29 Jan 2019 02:51:15 +0000 (11:51 +0900)
It moves several classes such as Cgroup, Namespace, xml.

Change-Id: I67bcd993230f8cbaf01012aba003d7bd8b7a734f
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
18 files changed:
CMakeLists.txt
common/cgroup.cpp [new file with mode: 0644]
common/cgroup.h [new file with mode: 0644]
common/namespace.cpp [new file with mode: 0644]
common/namespace.h [new file with mode: 0644]
common/xml/document.cpp [new file with mode: 0644]
common/xml/document.h [new file with mode: 0644]
common/xml/keepblanks.cpp [new file with mode: 0644]
common/xml/keepblanks.h [new file with mode: 0644]
common/xml/node.cpp [new file with mode: 0644]
common/xml/node.h [new file with mode: 0644]
common/xml/parser.cpp [new file with mode: 0644]
common/xml/parser.h [new file with mode: 0644]
module/CMakeLists.txt
module/krate-builder.cpp
module/krate-builder.h
server/CMakeLists.txt
server/manager.cpp

index e7b2b3e..0a9d6f5 100755 (executable)
@@ -33,6 +33,7 @@ SET(KRATE_SERVER    ${PROJECT_SOURCE_DIR}/server)
 SET(KRATE_DATA      ${PROJECT_SOURCE_DIR}/data)
 SET(KRATE_MODULE    ${PROJECT_SOURCE_DIR}/module)
 SET(KRATE_VOLUME    ${PROJECT_SOURCE_DIR}/volume)
+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")
diff --git a/common/cgroup.cpp b/common/cgroup.cpp
new file mode 100644 (file)
index 0000000..8276f46
--- /dev/null
@@ -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 (file)
index 0000000..63994cd
--- /dev/null
@@ -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 (file)
index 0000000..fdcd1b5
--- /dev/null
@@ -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 (file)
index 0000000..bc9368c
--- /dev/null
@@ -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/common/xml/document.cpp b/common/xml/document.cpp
new file mode 100644 (file)
index 0000000..6056b09
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *  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 <libxml/xpath.h>
+
+#include <iostream>
+
+#include <klay/exception.h>
+
+#include "document.h"
+#include "keepblanks.h"
+
+namespace xml {
+
+Document::Document(const std::string& root, const std::string& version) :
+       implementation(xmlNewDoc((const xmlChar*)version.c_str()))
+{
+       if (implementation == nullptr) {
+               throw klay::Exception("Failed to create document");
+       }
+
+       implementation->_private = this;
+
+       xmlNode* rootPtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)root.c_str()));
+       xmlDocSetRootElement(implementation, rootPtr);
+
+       rootNode = new Node(rootPtr);
+}
+
+Document::Document(xmlDoc* doc)
+       : implementation(doc)
+{
+       implementation->_private = this;
+
+       rootNode = new Node(xmlDocGetRootElement(implementation));
+}
+
+Document::~Document()
+{
+       if (rootNode != nullptr) {
+               delete rootNode;
+       }
+
+       xmlFreeDoc(implementation);
+}
+
+Node& Document::getRootNode()
+{
+       if (rootNode == nullptr) {
+               throw klay::Exception("Empty document");
+       }
+
+       return *rootNode;
+}
+
+Node::NodeList Document::evaluate(const std::string& xpath)
+{
+       auto ctxt = xmlXPathNewContext(implementation);
+       if (ctxt == nullptr) {
+               throw klay::Exception("Failed to create XPath context for " + xpath);
+       }
+
+       auto result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt);
+       if (result == nullptr) {
+               xmlXPathFreeContext(ctxt);
+               throw klay::Exception("Invalid XPath: " + xpath);
+       }
+
+       if (result ->type != XPATH_NODESET) {
+               xmlXPathFreeObject(result);
+               xmlXPathFreeContext(ctxt);
+
+               throw klay::Exception("Only nodeset result types are supported");
+       }
+
+       auto nodeset = result->nodesetval;
+
+       Node::NodeList nodes;
+       if ((nodeset == nullptr) || (xmlXPathNodeSetIsEmpty(nodeset))) {
+               xmlXPathFreeContext(ctxt);
+               return nodes;
+       }
+
+       const int count = xmlXPathNodeSetGetLength(nodeset);
+
+       nodes.reserve(count);
+       for (int i = 0; i != count; i++) {
+               auto cnode = xmlXPathNodeSetItem(nodeset, i);
+               if (!cnode) {
+                       continue;
+               }
+
+               if (cnode->type == XML_NAMESPACE_DECL) {
+                       continue;
+               }
+
+               nodes.emplace_back(cnode);
+       }
+
+       xmlXPathFreeObject(result);
+       xmlXPathFreeContext(ctxt);
+
+       return nodes;
+}
+
+void Document::write(const std::string& filename, const std::string& encoding, bool formatted)
+{
+       KeepBlanks keepBlanks(KeepBlanks::Default);
+       xmlIndentTreeOutput = formatted;
+
+       xmlResetLastError();
+
+       const int result = xmlSaveFormatFileEnc(filename.c_str(),
+                                                                                       implementation,
+                                                                                       encoding.c_str(),
+                                                                                       formatted);
+       if (result == 0) {
+               throw klay::Exception("Failed to write XML document");
+       }
+}
+
+} // namespace xml
diff --git a/common/xml/document.h b/common/xml/document.h
new file mode 100644 (file)
index 0000000..08dd1b5
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  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 __XML_DOCUMENT_H__
+#define __XML_DOCUMENT_H__
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#include <string>
+
+#include <common/xml/node.h>
+
+namespace xml {
+
+class Document {
+public:
+       Document(const std::string& root, const std::string& version = XML_DEFAULT_VERSION);
+       Document(xmlDoc* doc);
+
+       ~Document();
+
+       Node& getRootNode();
+
+       Node::NodeList evaluate(const std::string& xpath);
+       void write(const std::string& filename, const std::string& encoding, bool formatted);
+
+private:
+       Node* rootNode;
+       xmlDoc* implementation;
+};
+
+} // namespace xml
+
+
+#endif //__XML_DOCUMENT_H__
diff --git a/common/xml/keepblanks.cpp b/common/xml/keepblanks.cpp
new file mode 100644 (file)
index 0000000..906aa75
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  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 "keepblanks.h"
+
+namespace xml {
+
+KeepBlanks::KeepBlanks(bool value)
+{
+       preservedIndentTreeOutput = xmlIndentTreeOutput;
+       preservedKeepBlanksDefault = xmlKeepBlanksDefault(value ? 1 : 0);
+}
+
+KeepBlanks::~KeepBlanks()
+{
+       xmlKeepBlanksDefault(preservedKeepBlanksDefault);
+       xmlIndentTreeOutput = preservedIndentTreeOutput;
+}
+
+} // namespace xml
diff --git a/common/xml/keepblanks.h b/common/xml/keepblanks.h
new file mode 100644 (file)
index 0000000..d227051
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  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 __XML_KEEPBLANKS_H__
+#define __XML_KEEPBLANKS_H__
+
+#include <libxml/globals.h>
+
+namespace xml {
+
+class KeepBlanks {
+public:
+       KeepBlanks(bool value);
+       ~KeepBlanks();
+
+       static const bool Default = true;
+
+private:
+       int preservedKeepBlanksDefault;
+       int preservedIndentTreeOutput;
+};
+
+} // namespace xml
+
+#endif //__XML_KEEPBLANKS_H__
diff --git a/common/xml/node.cpp b/common/xml/node.cpp
new file mode 100644 (file)
index 0000000..0c0609e
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  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 <klay/exception.h>
+
+#include "node.h"
+
+namespace xml {
+
+Node::Node(xmlNode* node) :
+       implementation(node)
+{
+}
+
+Node::Node(Node&& node) :
+       implementation(node.implementation)
+{
+}
+
+Node::~Node()
+{
+}
+
+Node::NodeList Node::getChildren() const
+{
+       NodeList nodeList;
+
+       auto child = implementation->xmlChildrenNode;
+       while (child != nullptr) {
+               nodeList.emplace_back(child);
+               child = child->next;
+       }
+
+       return nodeList;
+}
+
+Node Node::addNewChild(const std::string& name)
+{
+       xmlNode* nodePtr = xmlNewNode(NULL, xmlStrdup((const xmlChar*)name.c_str()));
+       if (nodePtr == nullptr) {
+               throw klay::Exception("Can not create a new node");
+       }
+       xmlAddChild(implementation, nodePtr);
+
+       return Node(nodePtr);
+}
+
+std::string Node::getName() const
+{
+       return implementation->name ? (const char*)implementation->name : "";
+}
+
+void Node::setName(const std::string& name)
+{
+       xmlNodeSetName(implementation, (const xmlChar*)name.c_str());
+}
+
+std::string Node::getContent() const
+{
+       xmlChar* content = xmlNodeGetContent(implementation);
+       if (content == NULL) {
+               return "";
+       }
+       std::string ret((const char*)content);
+       xmlFree(content);
+       return ret;
+}
+
+void Node::setContent(const std::string& content)
+{
+       xmlNodeSetContent(implementation, (xmlChar*)content.c_str());
+}
+
+std::string Node::getProp(const std::string& name) const
+{
+       if (implementation->type != XML_ELEMENT_NODE) {
+               throw klay::Exception("This node type does not have properties");
+       }
+
+       xmlChar* prop = xmlGetProp(implementation, (xmlChar*)name.c_str());
+       if (prop) {
+               std::string ret((const char*)prop);
+               xmlFree(prop);
+               return ret;
+       }
+
+       return "";
+}
+
+void Node::setProp(const std::string& name, const std::string& val)
+{
+       if (implementation->type != XML_ELEMENT_NODE) {
+               throw klay::Exception("Can not set properties for this node type");
+       }
+
+       xmlSetProp(implementation, (xmlChar*)name.c_str(), (xmlChar*)val.c_str());
+}
+
+bool Node::isBlank() const
+{
+       return xmlIsBlankNode(const_cast<xmlNode*>(implementation));
+}
+
+} // namespace xml
diff --git a/common/xml/node.h b/common/xml/node.h
new file mode 100644 (file)
index 0000000..259164c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  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 __XML_NODE_H__
+#define __XML_NODE_H__
+
+#include <string>
+#include <vector>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+namespace xml {
+
+class Node {
+public:
+       typedef std::vector<Node> NodeList;
+
+       explicit Node(xmlNode* node);
+       Node(Node&&);
+       Node(const Node&) = delete;
+
+       ~Node();
+
+       Node& operator=(const Node&) = delete;
+
+       NodeList getChildren() const;
+       Node addNewChild(const std::string& name);
+
+       std::string getName() const;
+       void setName(const std::string& name);
+
+       std::string getContent() const;
+       void setContent(const std::string& content);
+
+       std::string getProp(const std::string& name) const;
+       void setProp(const std::string& name, const std::string& val);
+
+       bool isBlank() const;
+
+private:
+       xmlNode* implementation;
+};
+
+} // namespace xml
+
+#endif //__XML_NODE_H__
diff --git a/common/xml/parser.cpp b/common/xml/parser.cpp
new file mode 100644 (file)
index 0000000..a878d30
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  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 <libxml/parserInternals.h>
+
+#include <klay/exception.h>
+
+#include "parser.h"
+#include "keepblanks.h"
+
+namespace xml {
+
+Document* Parser::parseContext(xmlParserCtxt* context, bool validate)
+{
+       if (context == nullptr) {
+               throw klay::Exception("Could not create parser context");
+       }
+
+       KeepBlanks(false);
+
+       int options = 0;
+
+       if (validate) {
+               options |= XML_PARSE_DTDVALID;
+       } else {
+               options &= ~XML_PARSE_DTDVALID;
+       }
+
+       xmlCtxtUseOptions(context, options);
+
+       if (xmlParseDocument(context) < 0) {
+               xmlFreeParserCtxt(context);
+               throw klay::Exception("Parsing failed");
+       }
+
+       xmlDoc* document = context->myDoc;
+
+       // We took the ownership on the doc
+       context->myDoc = nullptr;
+
+       xmlFreeParserCtxt(context);
+
+       return new Document(document);
+}
+
+Document* Parser::parseFile(const std::string& filename, bool validate)
+{
+       xmlParserCtxt* context = xmlCreateFileParserCtxt(filename.c_str());
+       if (context == nullptr) {
+               throw klay::Exception("Could not create parser context");
+       }
+
+       if (context->directory == nullptr) {
+               context->directory = xmlParserGetDirectory(filename.c_str());
+       }
+
+       return parseContext(context, validate);
+}
+
+Document* Parser::parseString(const std::string& xml, bool validate)
+{
+       xmlParserCtxt* context = xmlCreateMemoryParserCtxt(xml.c_str(), xml.size() + 1);
+
+       if (context == nullptr) {
+               throw klay::Exception("Could not create parser context");
+       }
+
+       return parseContext(context, validate);
+}
+
+} // namespace xml
diff --git a/common/xml/parser.h b/common/xml/parser.h
new file mode 100644 (file)
index 0000000..f6f3eb9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  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 __XML_DOMPARSER_H__
+#define __XML_DOMPARSER_H__
+
+#include <libxml/parser.h>
+
+#include <string>
+
+#include <common/xml/document.h>
+
+namespace xml {
+
+class Parser {
+public:
+       static Document* parseFile(const std::string& filename, bool validate = false);
+       static Document* parseString(const std::string& xml, bool validate = false);
+
+private:
+       static Document* parseContext(xmlParserCtxt* context, bool validate = false);
+};
+
+} // namespace xml
+
+#endif //__XML_DOMPARSER_H__
index 2c3cd43..c3a603e 100644 (file)
 #
 SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
 
-FILE(GLOB BUILDER_SRCS krate-builder.cpp)
+FILE(GLOB BUILDER_SRCS krate-builder.cpp
+                                               ${KRATE_COMMON}/cgroup.cpp
+                                               ${KRATE_COMMON}/namespace.cpp
+                                               ${KRATE_COMMON}/xml/node.cpp
+                                               ${KRATE_COMMON}/xml/parser.cpp
+                                               ${KRATE_COMMON}/xml/document.cpp
+                                               ${KRATE_COMMON}/xml/keepblanks.cpp
+)
 
 PKG_CHECK_MODULES(BUILDER_DEPS REQUIRED
                                                                klay
@@ -40,7 +47,7 @@ MARK_AS_ADVANCED(PAM_INCLUDE_DIR PAM_LIBRARY)
 INCLUDE(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PAM DEFAULT_MSG PAM_LIBRARY PAM_INCLUDE_DIR)
 
-INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${BUILDER_DEPS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${BUILDER_DEPS_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR})
 
 TARGET_LINK_LIBRARIES(${PAM_NAME}      ${PAM_LIBRARY} ${BUILDER_DEPS_LIBRARIES})
 
index 3e13cc7..4b423cc 100644 (file)
 #include "krate-builder.h"
 
 #include <klay/exception.h>
-#include <klay/namespace.h>
 #include <klay/filesystem.h>
 
+#include <common/namespace.h>
+
 #define CGROUP_SUBSYSTEM "krate"
 
 KrateBuilder::KrateBuilder(const runtime::User& user) :
@@ -82,28 +83,28 @@ void KrateBuilder::enterKrate()
        std::string path = CGROUP_SUBSYSTEM "/" + user.getName();
        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);
        }
 }
 
 void KrateBuilder::exitKrate()
 {
        std::string path =  CGROUP_SUBSYSTEM "/" + user.getName();
-       auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
+       auto pids = Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
        if (pids.size() <= 1) {
-               runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path);
+               Cgroup::destroy(CGROUP_SUBSYSTEM, path);
        }
 }
index 1563c3e..724b9ea 100644 (file)
 #include <vector>
 #include <memory>
 
-#include <klay/cgroup.h>
-#include <klay/xml/parser.h>
-#include <klay/xml/document.h>
 #include <klay/auth/user.h>
 
+#include <common/cgroup.h>
+#include <common/xml/parser.h>
+#include <common/xml/document.h>
+
 class KrateBuilder final {
 public:
        KrateBuilder(const runtime::User& user);
index 7651c57..f75b6d6 100644 (file)
@@ -21,6 +21,11 @@ SET(SERVER_SRCS      main.cpp
                                manager.cpp
                                app-proxy.cpp
                                package-proxy.cpp
+                               ${KRATE_COMMON}/cgroup.cpp
+                               ${KRATE_COMMON}/xml/node.cpp
+                               ${KRATE_COMMON}/xml/parser.cpp
+                               ${KRATE_COMMON}/xml/document.cpp
+                               ${KRATE_COMMON}/xml/keepblanks.cpp
 )
 
 SET(DEPENDENCY klay
index d3b0aa5..4a95afa 100755 (executable)
 #include <gum/gum-user-service.h>
 #include <gum/common/gum-user-types.h>
 #include <klay/error.h>
-#include <klay/cgroup.h>
 #include <klay/process.h>
 #include <klay/filesystem.h>
 #include <klay/auth/user.h>
-#include <klay/xml/parser.h>
-#include <klay/xml/document.h>
+
 #include <klay/dbus/connection.h>
 #include <klay/audit/logger.h>
 
 #include "packman.h"
 #include "launchpad.h"
+#include <common/cgroup.h>
+#include <common/xml/parser.h>
+#include <common/xml/document.h>
 
 #include "rmi/manager.h"
 
@@ -531,8 +532,8 @@ Manager::Manager(KrateControlContext& ctx) :
        context.createNotification("Manager::created");
        context.createNotification("Manager::removed");
 
-       runtime::Cgroup::createSubsystem(CGROUP_SUBSYSTEM);
-       runtime::Cgroup::create(CGROUP_SUBSYSTEM, CGROUP_SUBSYSTEM);
+       Cgroup::createSubsystem(CGROUP_SUBSYSTEM);
+       Cgroup::create(CGROUP_SUBSYSTEM, CGROUP_SUBSYSTEM);
 
        KRATE_DEFAULT_OWNER = ::tzplatform_getenv(TZ_SYS_DEFAULT_USER);