#include "lxcpp/exception.hpp"
#include "lxcpp/process.hpp"
#include "lxcpp/filesystem.hpp"
-#include "lxcpp/namespace.hpp"
#include "lxcpp/capability.hpp"
#include "lxcpp/commands/attach.hpp"
#include "lxcpp/commands/start.hpp"
mConfig.mTerminals.count = count;
}
+void ContainerImpl::setNamespaces(const int namespaces)
+{
+ mConfig.mNamespaces = namespaces;
+}
+
void ContainerImpl::start()
{
// TODO: check config consistency and completeness somehow
#include <unistd.h>
#include <sys/wait.h>
-
namespace lxcpp {
+namespace {
-void startContainer(const ContainerConfig &cfg)
+int startContainer(void* data)
{
- lxcpp::execve(cfg.mInit);
+ ContainerConfig& config = *static_cast<ContainerConfig*>(data);
+
+ // TODO: container preparation part 2
+
+ PrepGuestTerminal terminals(config.mTerminals);
+ terminals.execute();
+
+ lxcpp::execve(config.mInit);
+
+ return EXIT_FAILURE;
}
-int startGuard(int channelFD)
+} // namespace
+
+
+Guard::Guard(const int channelFD)
+ : mChannel(channelFD)
{
- ContainerConfig cfg;
- utils::Channel channel(channelFD);
- channel.setCloseOnExec(true);
- config::loadFromFD(channel.getFD(), cfg);
+ mChannel.setCloseOnExec(true);
+ config::loadFromFD(mChannel.getFD(), mConfig);
- logger::setupLogger(cfg.mLogger.getType(),
- cfg.mLogger.getLevel(),
- cfg.mLogger.getArg());
+ logger::setupLogger(mConfig.mLogger.getType(),
+ mConfig.mLogger.getLevel(),
+ mConfig.mLogger.getArg());
- LOGD("Guard started, config & logging restored");
+ LOGD("Config & logging restored");
try {
LOGD("Setting the guard process title");
- const std::string title = "[LXCPP] " + cfg.mName + " " + cfg.mRootPath;
+ const std::string title = "[LXCPP] " + mConfig.mName + " " + mConfig.mRootPath;
setProcTitle(title);
} catch (std::exception &e) {
// Ignore, this is optional
LOGW("Failed to set the guard process title: " << e.what());
}
+}
- // TODO: container preparation part 1
-
- // TODO: switch to clone
- LOGD("Forking container's init process");
- pid_t pid = lxcpp::fork();
-
- if (pid == 0) {
- // TODO: container preparation part 2
+Guard::~Guard()
+{
+}
- PrepGuestTerminal terminals(cfg.mTerminals);
- terminals.execute();
+int Guard::execute()
+{
+ // TODO: container preparation part 1
- startContainer(cfg);
- ::_exit(EXIT_FAILURE);
- }
+ const pid_t initPid = lxcpp::clone(startContainer,
+ &mConfig,
+ mConfig.mNamespaces);
- cfg.mGuardPid = ::getpid();
- cfg.mInitPid = pid;
+ mConfig.mGuardPid = ::getpid();
+ mConfig.mInitPid = initPid;
- channel.write(cfg.mGuardPid);
- channel.write(cfg.mInitPid);
- channel.shutdown();
+ mChannel.write(mConfig.mGuardPid);
+ mChannel.write(mConfig.mInitPid);
+ mChannel.shutdown();
- int status = lxcpp::waitpid(pid);
+ int status = lxcpp::waitpid(initPid);
LOGD("Init exited with status: " << status);
return status;
}
-
} // namespace lxcpp
::_exit(EXIT_FAILURE);
}
- int channelFD = std::stoi(argv[1]);
-
// NOTE: this might not be required now, but I leave it here not to forget.
// We need to investigate this with vasum and think about possibility of
// poorly written software that leaks file descriptors and might use LXCPP.
}
#endif
- return lxcpp::startGuard(channelFD);
+ try {
+ int fd = std::stoi(argv[1]);
+ lxcpp::Guard guard(fd);
+ return guard.execute();
+ } catch(std::exception& e) {
+ // LOGE("Unexpected: " << utils::getTypeName(e) << ": " << e.what());
+ return EXIT_FAILURE;
+ }
}