#include "logger/logger.hpp"
#include "lxc/zone.hpp"
#include "lxc/exception.hpp"
-#ifdef USE_EXEC
#include "utils/execute.hpp"
+#ifdef USE_EXEC
#include "utils/c-array.hpp"
#endif
return false;
}
int status;
- if (waitpid(pid, &status, 0) < 0) {
+ if (!utils::waitPid(pid, status)) {
return false;
}
return status == 0;
#include "config.hpp"
#include "utils/environment.hpp"
+#include "utils/execute.hpp"
#include "logger/logger.hpp"
#include <cap-ng.h>
if (pid == 0) {
if (::setuid(0) < 0) {
LOGW("Failed to become root: " << strerror(errno));
- ::exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
try {
if (!func()) {
LOGE("Failed to successfully execute func");
- ::exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
} catch (const std::exception& e) {
LOGE("Failed to successfully execute func: " << e.what());
- ::exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
- ::exit(EXIT_SUCCESS);
+ _exit(EXIT_SUCCESS);
}
- int result;
- if (::waitpid(pid, &result, 0) < 0) {
- LOGE("waitpid failed: " << strerror(errno));
+ int status;
+ if (!waitPid(pid, status)) {
return false;
}
- if (result != 0) {
- LOGE("Function launched as root failed with result " << result);
+ if (status != 0) {
+ LOGE("Function launched as root exited with status " << status);
return false;
}
execv(fname, const_cast<char* const*>(argv));
_exit(EXIT_FAILURE);
}
- int ret = waitpid(pid, &status, 0);
- if (ret != pid) {
- LOGE("Waitpid failed");
- return false;
- }
- return true;
+ return waitPid(pid, status);
}
bool executeAndWait(const char* fname, const char* const* argv)
return true;
}
+bool waitPid(pid_t pid, int& status)
+{
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR) {
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace utils
} // namespace security_containers
#ifndef COMMON_UTILS_EXECUTE_HPP
#define COMMON_UTILS_EXECUTE_HPP
+#include <sys/types.h>
namespace security_containers {
namespace utils {
bool executeAndWait(const char* fname, const char* const* argv, int& status);
+bool waitPid(pid_t pid, int& status);
+
} // namespace utils
} // namespace security_containers
};
}
-class FileCleanerRAII {
-public:
- FileCleanerRAII(const std::vector<std::string>& filePathsToClean):
- mFilePathsToClean(filePathsToClean)
- { }
-
- ~FileCleanerRAII()
- {
- namespace fs = boost::filesystem;
- for (const auto& file : mFilePathsToClean) {
- fs::path f(file);
- if (fs::exists(f)) {
- fs::remove(f);
- }
- }
- }
-
-private:
- const std::vector<std::string> mFilePathsToClean;
-};
-
struct Fixture {
security_containers::utils::ScopedGlibLoop mLoop;
BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest)
{
- const std::string newContainerId = "test1234";
+ const std::string container1 = "test1";
+ const std::string container2 = "test2";
+ const std::string container3 = "test3";
ContainersManager cm(EMPTY_DBUS_CONFIG_PATH);
cm.startAll();
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), "");
+
Latch callDone;
auto resultCallback = [&]() {
callDone.set();
DbusAccessory dbus(DbusAccessory::HOST_ID);
- // create new container
- dbus.callAsyncMethodCreateContainer(newContainerId, resultCallback);
+ // create container1
+ dbus.callAsyncMethodCreateContainer(container1, resultCallback);
BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
- // focus new container
- cm.focus(newContainerId);
- BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId);
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container1);
- // destroy container
- dbus.callAsyncMethodDestroyContainer(newContainerId, resultCallback);
+ // create container2
+ dbus.callAsyncMethodCreateContainer(container2, resultCallback);
BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container2); //TODO is this valid?
- BOOST_CHECK(cm.getRunningForegroundContainerId() == "");
+ // create container3
+ dbus.callAsyncMethodCreateContainer(container3, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container3);
+
+ // destroy container2
+ dbus.callAsyncMethodDestroyContainer(container2, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container3);
+
+ // destroy container3
+ dbus.callAsyncMethodDestroyContainer(container3, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+ //BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container1);//TODO fix it
+
+ // destroy container1
+ dbus.callAsyncMethodDestroyContainer(container1, resultCallback);
+ BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT));
+ BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), "");
}
BOOST_AUTO_TEST_CASE(DeclareFile)
#include "config.hpp"
#include "utils/scoped-daemon.hpp"
+#include "utils/execute.hpp"
#include "logger/logger.hpp"
volatile pid_t daemonPid = -1;// available in launcher process only;
-void startDaemon(const char* path, const char* const argv[])
+bool startDaemon(const char* path, const char* const argv[])
{
execv(path, const_cast<char* const*>(argv));
perror("exec failed");
+ return false;
}
-void waitForDaemon()
+bool waitForDaemon()
{
- if (waitpid(daemonPid, NULL, 0) == -1) {
- perror("wait for daemon failed");
- }
+ int status;
+ return waitPid(daemonPid, status);
}
void launcherSignalHandler(int sig)
signal(SIGHUP, SIG_DFL);
}
-void startByLauncher(const char* path, const char* const argv[])
+bool startByLauncher(const char* path, const char* const argv[])
{
cleanupProcess();
daemonPid = fork();
if (daemonPid == -1) {
perror("fork failed");
- return;
+ return false;
}
if (daemonPid == 0) {
- startDaemon(path, argv);
- _exit(1);
+ if (!startDaemon(path, argv)) {
+ return false;
+ }
}
registerLauncherSignalHandler();
registerParentDiedNotification();
- waitForDaemon();
+ return waitForDaemon();
}
} // namespace
throw std::runtime_error("fork failed");
}
if (mPid == 0) {
+ bool ret;
if (useLauncher) {
- startByLauncher(path, argv);
+ ret = startByLauncher(path, argv);
} else {
- startDaemon(path, argv);
+ ret = startDaemon(path, argv);
}
- _exit(0);
+ _exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
}
}
if (kill(mPid, SIGTERM) == -1) {
LOGE("kill failed");
}
- if (waitpid(mPid, NULL, 0) == -1) {
- LOGE("waitpid failed");
+ int status;
+ if (!waitPid(mPid, status)) {
+ throw std::runtime_error("waitpid failed");
+ }
+ if (status != EXIT_SUCCESS) {
+ LOGW("process exit with status " << status);
}
mPid = -1;
}
* @param argv arguments passed to the daemon
* @param useLauncher use additional launcher process
*/
- void start(const char* path, const char* const argv[], const bool useLauncher = true);
+ void start(const char* path, const char* const argv[], const bool useLauncher = false);
/**
* Stops a daemon by sending SIGTERM and waits for a process.