#include "lxcpp/container-impl.hpp"
#include "lxcpp/exception.hpp"
#include "lxcpp/process.hpp"
+#include "lxcpp/filesystem.hpp"
+#include "lxcpp/namespace.hpp"
#include "utils/exception.hpp"
#include <unistd.h>
+#include <sys/mount.h>
+
namespace lxcpp {
throw NotImplementedException();
}
+namespace {
+void setupMountPoints()
+{
+ /* TODO: Uncomment when preparing the final attach() version
+
+ // TODO: This unshare should be optional only if we attach to PID/NET namespace, but not MNT.
+ // Otherwise container already has remounted /proc /sys
+ lxcpp::unshare(Namespace::MNT);
+
+ if (isMountPointShared("/")) {
+ // TODO: Handle case when the container rootfs or mount location is MS_SHARED, but not '/'
+ lxcpp::mount(nullptr, "/", nullptr, MS_SLAVE | MS_REC, nullptr);
+ }
+
+ if(isMountPoint("/proc")) {
+ lxcpp::umount("/proc", MNT_DETACH);
+ lxcpp::mount("none", "/proc", "proc", 0, nullptr);
+ }
+
+ if(isMountPoint("/sys")) {
+ lxcpp::umount("/sys", MNT_DETACH);
+ lxcpp::mount("none", "/sys", "sysfs", 0, nullptr);
+ }
+
+ */
+}
+} // namespace
int ContainerImpl::attachChild(void* data) {
try {
+ setupMountPoints();
return (*static_cast<Container::AttachCall*>(data))();
} catch(...) {
return -1; // Non-zero on failure
: Exception(message) {}
};
+struct FileSystemSetupException: public Exception {
+ FileSystemSetupException(const std::string& message = "Error during a file system operation")
+ : Exception(message) {}
+};
+
struct BadArgument: public Exception {
BadArgument(const std::string& message = "Bad argument passed")
: Exception(message) {}
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief file system handling routines
+ */
+
+#include "lxcpp/filesystem.hpp"
+#include "lxcpp/exception.hpp"
+#include "lxcpp/process.hpp"
+
+#include "utils/paths.hpp"
+#include "utils/exception.hpp"
+#include "logger/logger.hpp"
+
+#include <sstream>
+#include <fstream>
+#include <iterator>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+
+namespace lxcpp {
+
+void mount(const std::string& source,
+ const std::string& target,
+ const std::string& filesystemtype,
+ unsigned long mountflags,
+ const std::string& data)
+{
+ if (-1 == ::mount(source.c_str(),
+ target.c_str(),
+ filesystemtype.c_str(),
+ mountflags,
+ data.c_str())) {
+ const std::string msg = "mount() failed: src:" + source
+ + ", tgt: " + target
+ + ", filesystemtype: " + filesystemtype
+ + ", mountflags: " + std::to_string(mountflags)
+ + ", data: " + data
+ + ", msg: " + utils::getSystemErrorMessage();
+ LOGE(msg);
+ throw FileSystemSetupException(msg);
+ }
+}
+
+void umount(const std::string& path, const int flags)
+{
+ if (-1 == ::umount2(path.c_str(), flags)) {
+ const std::string msg = "umount() failed: '" + path + "': " + utils::getSystemErrorMessage();
+ LOGD(msg);
+ throw FileSystemSetupException(msg);
+ }
+}
+
+bool isMountPoint(const std::string& path)
+{
+ std::string parentPath = utils::dirName(path);
+
+ struct stat s1, s2;
+ if (-1 == ::stat(path.c_str(), &s1)) {
+ const std::string msg = "stat() failed: " + path + ": " + utils::getSystemErrorMessage();
+ LOGE(msg);
+ throw FileSystemSetupException(msg);
+ }
+
+ if (-1 == ::stat(parentPath.c_str(), &s2)) {
+ const std::string msg = "stat() failed: " + parentPath + ": " + utils::getSystemErrorMessage();
+ LOGE(msg);
+ throw FileSystemSetupException(msg);
+ }
+
+ return s1.st_dev != s2.st_dev;
+}
+
+bool isMountPointShared(const std::string& path)
+{
+ std::ifstream fileStream("/proc/self/mountinfo");
+ if (!fileStream.good()) {
+ const std::string msg = "Failed to open /proc/self/mountinfo";
+ LOGE(msg);
+ throw FileSystemSetupException(msg);
+ }
+
+ // Find the line corresponding to the path
+ std::string line;
+ while (std::getline(fileStream, line).good()) {
+ std::istringstream iss(line);
+ auto it = std::istream_iterator<std::string>(iss);
+ std::advance(it, 4);
+
+ if (it->compare(path)) {
+ // Wrong line, different path
+ continue;
+ }
+
+ // Right line, check if mount point shared
+ std::advance(it, 2);
+ return it->find("shared:") != std::string::npos;
+ }
+
+ // Path not found
+ return false;
+}
+
+} // namespace lxcpp
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @brief file system handling routines
+ */
+
+#ifndef LXCPP_FILESYSTEM_HPP
+#define LXCPP_FILESYSTEM_HPP
+
+#include <string>
+
+namespace lxcpp {
+
+void mount(const std::string& source,
+ const std::string& target,
+ const std::string& filesystemtype,
+ unsigned long mountflags,
+ const std::string& data);
+
+void umount(const std::string& path, const int flags);
+
+bool isMountPoint(const std::string& path);
+
+/**
+ * Detect whether path is mounted as MS_SHARED.
+ * Parses /proc/self/mountinfo
+ *
+ * @param path mount point
+ * @return is the mount point shared
+ */
+bool isMountPointShared(const std::string& path);
+
+} // namespace lxcpp
+
+#endif // LXCPP_FILESYSTEM_HPP
\ No newline at end of file
throw ProcessSetupException(msg);
}
+void unshare(const Namespace ns)
+{
+ if(-1 == ::unshare(toFlag(ns))) {
+ const std::string msg = "unshare() failed: " + utils::getSystemErrorMessage();
+ LOGE(msg);
+ throw ProcessSetupException(msg);
+ }
+}
} // namespace lxcpp
\ No newline at end of file
int waitpid(const pid_t pid);
+void unshare(const Namespace ns);
+
} // namespace lxcpp
#endif // LXCPP_PROCESS_HPP
\ No newline at end of file