From 873c1046ffe0a34ab7ec0a4d48e59e1adae754d3 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Mon, 24 Nov 2014 17:10:29 +0100 Subject: [PATCH 01/16] Fix create container from template [Bug/Feature] Templates stops working after migration to lxc [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ifbc0db612391eb7460b757b3cd12dda79183178b --- common/utils/environment.cpp | 10 +++-- common/utils/environment.hpp | 2 +- server/configs/CMakeLists.txt | 4 ++ server/configs/lxc-templates/template.sh | 72 ++++++++++++++++++++++++++++++++ server/configs/templates/template.conf | 3 ++ server/containers-manager.cpp | 26 +++++------- 6 files changed, 98 insertions(+), 19 deletions(-) create mode 100755 server/configs/lxc-templates/template.sh diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index eaaef12..73c7057 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -84,8 +84,9 @@ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps) return true; } -bool launchAsRoot(const std::function& func) +bool launchAsRoot(const std::function& func) { + // TODO optimize if getuid() == 0 pid_t pid = fork(); if (pid < 0) { LOGE("Fork failed: " << strerror(errno)); @@ -99,8 +100,11 @@ bool launchAsRoot(const std::function& func) } try { - func(); - } catch (std::exception& e) { + if (!func()) { + LOGE("Failed to successfully execute func"); + ::exit(EXIT_FAILURE); + } + } catch (const std::exception& e) { LOGE("Failed to successfully execute func: " << e.what()); ::exit(EXIT_FAILURE); } diff --git a/common/utils/environment.hpp b/common/utils/environment.hpp index 120b6ac..07a767e 100644 --- a/common/utils/environment.hpp +++ b/common/utils/environment.hpp @@ -50,7 +50,7 @@ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps); * * This function forks, sets UID 0 to child process and calls func. */ -bool launchAsRoot(const std::function& func); +bool launchAsRoot(const std::function& func); } // namespace utils diff --git a/server/configs/CMakeLists.txt b/server/configs/CMakeLists.txt index ab4a94f..e4f9df9 100644 --- a/server/configs/CMakeLists.txt +++ b/server/configs/CMakeLists.txt @@ -21,6 +21,7 @@ MESSAGE(STATUS "Installing configs to " ${SC_CONFIG_INSTALL_DIR}) FILE(GLOB container_CONF containers/*.conf) FILE(GLOB admin_CONF lxc-templates/*.sh) +FILE(GLOB template_CONF templates/*.conf) ## Generate #################################################################### CONFIGURE_FILE(systemd/security-containers.service.in @@ -44,5 +45,8 @@ INSTALL(FILES ${container_CONF} INSTALL(PROGRAMS ${admin_CONF} DESTINATION ${SC_CONFIG_INSTALL_DIR}/lxc-templates) +INSTALL(PROGRAMS ${template_CONF} + DESTINATION ${SC_CONFIG_INSTALL_DIR}/templates) + INSTALL(FILES ${CMAKE_BINARY_DIR}/systemd/security-containers.service DESTINATION ${SYSTEMD_UNIT_DIR}) diff --git a/server/configs/lxc-templates/template.sh b/server/configs/lxc-templates/template.sh new file mode 100755 index 0000000..c03a050 --- /dev/null +++ b/server/configs/lxc-templates/template.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +echo LXC template, args: $@ + +options=$(getopt -o p:n: -l rootfs:,path:,name: -- "$@") +if [ $? -ne 0 ]; then + exit 1 +fi +eval set -- "$options" + +while true +do + case "$1" in + -p|--path) path=$2; shift 2;; + --rootfs) rootfs=$2; shift 2;; + -n|--name) name=$2; shift 2;; + --) shift 1; break ;; + *) break ;; + esac +done + +br_name="virbr-${name}" +sub_net="103" # TODO from param + +# XXX assume rootfs if mounted from iso + +# Prepare container configuration file +> ${path}/config +cat <> ${path}/config +lxc.utsname = ${name} +lxc.rootfs = ${rootfs} + +# userns 1-to-1 mapping +#lxc.id_map = u 0 0 65536 +#lxc.id_map = g 0 0 65536 + +lxc.pts = 256 +lxc.tty = 0 + +lxc.mount.auto = proc sys cgroup +lxc.mount.entry = /var/run/containers/${name}/run var/run none rw,bind 0 0 + +lxc.network.type = veth +lxc.network.link = ${br_name} +lxc.network.flags = up +lxc.network.name = eth0 +lxc.network.veth.pair = veth-${name} +lxc.network.ipv4.gateway = 10.0.${sub_net}.1 +lxc.network.ipv4 = 10.0.${sub_net}.2/24 + +lxc.hook.pre-start = ${path}/pre-start.sh + +#lxc.loglevel = TRACE +#lxc.logfile = /tmp/${name}.log +EOF + +# prepare pre start hook +cat <> ${path}/pre-start.sh +if [ -z "\$(/usr/sbin/brctl show | /bin/grep -P "${br_name}\t")" ] +then + /usr/sbin/brctl addbr ${br_name} + /usr/sbin/brctl setfd ${br_name} 0 + /sbin/ifconfig ${br_name} 10.0.${sub_net}.1 netmask 255.255.255.0 up +fi +if [ -z "\$(/usr/sbin/iptables -t nat -S | /bin/grep MASQUERADE)" ] +then + /bin/echo 1 > /proc/sys/net/ipv4/ip_forward + /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -j MASQUERADE +fi +EOF + +chmod 755 ${path}/pre-start.sh diff --git a/server/configs/templates/template.conf b/server/configs/templates/template.conf index a8f47fc..f91bf5f 100644 --- a/server/configs/templates/template.conf +++ b/server/configs/templates/template.conf @@ -1,4 +1,7 @@ { + "name" : "~NAME~", + "lxcTemplate" : "template.sh", + "initWithArgs" : [], "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "privilege" : 10, diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 62dbc14..def04c2 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -41,9 +41,6 @@ #include #include -#include -#include -#include #include #include #include @@ -70,7 +67,6 @@ const std::string HOST_ID = "host"; const std::string CONTAINER_TEMPLATE_CONFIG_PATH = "template.conf"; const boost::regex CONTAINER_NAME_REGEX("~NAME~"); -const boost::regex CONTAINER_UUID_REGEX("~UUID~"); const boost::regex CONTAINER_IP_THIRD_OCTET_REGEX("~IP~"); const unsigned int CONTAINER_IP_BASE_THIRD_OCTET = 100; @@ -522,12 +518,15 @@ void ContainersManager::handleGetContainerInfoCall(const std::string& id, result->setError(api::ERROR_INTERNAL, "Unrecognized state of container"); return; } - const std::string rootPath = boost::filesystem::absolute(id, mConfig.containersPath).string(); + const auto containerPath = boost::filesystem::absolute(id, mConfig.containersPath); + const auto rootfsDir = boost::filesystem::path("rootfs"); + const auto rootfsPath = containerPath / rootfsDir; + result->set(g_variant_new("((siss))", id.c_str(), container->getVT(), state, - rootPath.c_str())); + rootfsPath.string().c_str())); } void ContainersManager::handleSetActiveContainerCall(const std::string& id, @@ -581,14 +580,10 @@ void ContainersManager::generateNewConfig(const std::string& id, std::string resultConfig = boost::regex_replace(config, CONTAINER_NAME_REGEX, id); - boost::uuids::uuid u = boost::uuids::random_generator()(); - std::string uuidStr = to_string(u); - LOGD("uuid: " << uuidStr); - resultConfig = boost::regex_replace(resultConfig, CONTAINER_UUID_REGEX, uuidStr); - // generate third IP octet for network config + // TODO change algorithm after implementing removeContainer std::string thirdOctetStr = std::to_string(CONTAINER_IP_BASE_THIRD_OCTET + mContainers.size() + 1); - LOGD("ip_third_octet: " << thirdOctetStr); + LOGD("IP third octet: " << thirdOctetStr); resultConfig = boost::regex_replace(resultConfig, CONTAINER_IP_THIRD_OCTET_REGEX, thirdOctetStr); if (!utils::saveFileContent(resultPath, resultConfig)) { @@ -630,7 +625,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, } // copy container image if config contains path to image - LOGT("image path: " << mConfig.containerImagePath); + LOGT("Image path: " << mConfig.containerImagePath); if (!mConfig.containerImagePath.empty()) { auto copyImageContentsWrapper = std::bind(&utils::copyImageContents, mConfig.containerImagePath, @@ -659,6 +654,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, } catch(const std::exception& e) { LOGW("Failed to remove data: " << boost::diagnostic_information(e)); } + return true; }; try { @@ -682,13 +678,13 @@ void ContainersManager::handleAddContainerCall(const std::string& id, return; } - auto resultCallback = [this, id, result, containerPathStr, removeAllWrapper](bool succeeded) { + auto resultCallback = [this, id, result](bool succeeded) { if (succeeded) { focus(id); result->setVoid(); } else { LOGE("Failed to start container."); - utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); + // TODO removeContainer result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, "Failed to start container."); } -- 2.7.4 From 42b000bb7378f7d1e686306008767ff0e7c8babe Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 25 Nov 2014 14:47:46 +0100 Subject: [PATCH 02/16] Fix RPM build error [Bug/Feature] RPM build error [Cause] Installed but unpackaged file found [Solution] Add file [Verification] Build Change-Id: Ic4f8258386ae9a289c637cf28ac878effda0e197 Signed-off-by: Dariusz Michaluk --- packaging/security-containers.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index ee5ee83..3425c51 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -43,9 +43,11 @@ between them. A process from inside a container can request a switch of context %dir /etc/security-containers %dir /etc/security-containers/containers %dir /etc/security-containers/lxc-templates +%dir /etc/security-containers/templates %config /etc/security-containers/daemon.conf %config /etc/security-containers/containers/*.conf %attr(755,root,root) /etc/security-containers/lxc-templates/*.sh +%config /etc/security-containers/templates/*.conf %{_unitdir}/security-containers.service %{_unitdir}/multi-user.target.wants/security-containers.service /etc/dbus-1/system.d/org.tizen.containers.host.conf -- 2.7.4 From e47bd19c9bb22feaebb71432ded3b2d609ac7e45 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 25 Nov 2014 14:47:58 +0100 Subject: [PATCH 03/16] Templated network configuration [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run test Change-Id: I46af4da7ad656b05193184fc972c1d7489eb25f6 --- common/lxc/domain.cpp | 7 ++- common/lxc/domain.hpp | 2 +- server/configs/containers/business.conf | 4 +- server/configs/containers/private.conf | 4 +- server/configs/lxc-templates/business.sh | 72 ---------------------- server/configs/lxc-templates/private.sh | 72 ---------------------- server/configs/lxc-templates/template.sh | 15 +++-- server/configs/templates/template.conf | 2 + server/container-admin.cpp | 11 +++- server/container-config.hpp | 12 ++++ .../ut-client/containers/console1-dbus.conf.in | 2 + .../ut-client/containers/console2-dbus.conf.in | 2 + .../ut-client/containers/console3-dbus.conf.in | 2 + tests/unit_tests/lxc/ut-domain.cpp | 17 ++--- .../ut-container-admin/containers/buggy.conf | 2 + .../ut-container-admin/containers/missing.conf | 2 + .../containers/test-no-shutdown.conf | 2 + .../ut-container-admin/containers/test.conf | 2 + .../configs/ut-container/containers/buggy.conf | 2 + .../ut-container/containers/test-dbus.conf.in | 2 + .../configs/ut-container/containers/test.conf | 2 + .../containers/console1-dbus.conf.in | 2 + .../ut-containers-manager/containers/console1.conf | 2 + .../containers/console2-dbus.conf.in | 2 + .../ut-containers-manager/containers/console2.conf | 2 + .../containers/console3-dbus.conf.in | 2 + .../ut-containers-manager/containers/console3.conf | 2 + .../configs/ut-server/containers/container1.conf | 2 + .../configs/ut-server/containers/container2.conf | 2 + .../configs/ut-server/containers/container3.conf | 2 + 30 files changed, 93 insertions(+), 163 deletions(-) delete mode 100755 server/configs/lxc-templates/business.sh delete mode 100755 server/configs/lxc-templates/private.sh diff --git a/common/lxc/domain.cpp b/common/lxc/domain.cpp index bc2e74b..191f405 100644 --- a/common/lxc/domain.cpp +++ b/common/lxc/domain.cpp @@ -93,9 +93,12 @@ LxcDomain::State LxcDomain::getState() return STATE_MAP.at(str); } -bool LxcDomain::create(const std::string& templatePath) +bool LxcDomain::create(const std::string& templatePath, const char* const* argv) { - if (!mContainer->create(mContainer, templatePath.c_str(), NULL, NULL, 0, NULL)) { + if (!mContainer->create(mContainer, + templatePath.c_str(), + NULL, NULL, 0, + const_cast(argv))) { LOGE("Could not create domain " + getName()); return false; } diff --git a/common/lxc/domain.hpp b/common/lxc/domain.hpp index 8421d6d..60ae5a4 100644 --- a/common/lxc/domain.hpp +++ b/common/lxc/domain.hpp @@ -64,7 +64,7 @@ public: State getState(); - bool create(const std::string& templatePath); + bool create(const std::string& templatePath, const char* const* argv); bool destroy(); bool start(const char* const* argv); diff --git a/server/configs/containers/business.conf b/server/configs/containers/business.conf index 92eb06d..b211ce3 100644 --- a/server/configs/containers/business.conf +++ b/server/configs/containers/business.conf @@ -1,7 +1,9 @@ { "name" : "business", - "lxcTemplate" : "business.sh", + "lxcTemplate" : "template.sh", "initWithArgs" : [], + "ipv4Gateway" : "10.0.102.1", + "ipv4" : "10.0.102.2", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 10000, "enableDbusIntegration" : true, diff --git a/server/configs/containers/private.conf b/server/configs/containers/private.conf index 074f4f3..b4fb56a 100644 --- a/server/configs/containers/private.conf +++ b/server/configs/containers/private.conf @@ -1,7 +1,9 @@ { "name" : "private", - "lxcTemplate" : "private.sh", + "lxcTemplate" : "template.sh", "initWithArgs" : [], + "ipv4Gateway" : "10.0.101.1", + "ipv4" : "10.0.101.2", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 10000, "enableDbusIntegration" : true, diff --git a/server/configs/lxc-templates/business.sh b/server/configs/lxc-templates/business.sh deleted file mode 100755 index 21f7d2e..0000000 --- a/server/configs/lxc-templates/business.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash - -echo LXC template, args: $@ - -options=$(getopt -o p:n: -l rootfs:,path:,name: -- "$@") -if [ $? -ne 0 ]; then - exit 1 -fi -eval set -- "$options" - -while true -do - case "$1" in - -p|--path) path=$2; shift 2;; - --rootfs) rootfs=$2; shift 2;; - -n|--name) name=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -done - -br_name="virbr-${name}" -sub_net="101" # TODO from param - -# XXX assume rootfs if mounted from iso - -# Prepare container configuration file -> ${path}/config -cat <> ${path}/config -lxc.utsname = ${name} -lxc.rootfs = ${rootfs} - -# userns 1-to-1 mapping -#lxc.id_map = u 0 0 65536 -#lxc.id_map = g 0 0 65536 - -lxc.pts = 256 -lxc.tty = 0 - -lxc.mount.auto = proc sys cgroup -lxc.mount.entry = /var/run/containers/${name}/run var/run none rw,bind 0 0 - -lxc.network.type = veth -lxc.network.link = ${br_name} -lxc.network.flags = up -lxc.network.name = eth0 -lxc.network.veth.pair = veth-${name} -lxc.network.ipv4.gateway = 10.0.${sub_net}.1 -lxc.network.ipv4 = 10.0.${sub_net}.2/24 - -lxc.hook.pre-start = ${path}/pre-start.sh - -#lxc.loglevel = TRACE -#lxc.logfile = /tmp/${name}.log -EOF - -# prepare pre start hook -cat <> ${path}/pre-start.sh -if [ -z "\$(/usr/sbin/brctl show | /bin/grep -P "${br_name}\t")" ] -then - /usr/sbin/brctl addbr ${br_name} - /usr/sbin/brctl setfd ${br_name} 0 - /sbin/ifconfig ${br_name} 10.0.${sub_net}.1 netmask 255.255.255.0 up -fi -if [ -z "\$(/usr/sbin/iptables -t nat -S | /bin/grep MASQUERADE)" ] -then - /bin/echo 1 > /proc/sys/net/ipv4/ip_forward - /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -j MASQUERADE -fi -EOF - -chmod 755 ${path}/pre-start.sh diff --git a/server/configs/lxc-templates/private.sh b/server/configs/lxc-templates/private.sh deleted file mode 100755 index 542093a..0000000 --- a/server/configs/lxc-templates/private.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash - -echo LXC template, args: $@ - -options=$(getopt -o p:n: -l rootfs:,path:,name: -- "$@") -if [ $? -ne 0 ]; then - exit 1 -fi -eval set -- "$options" - -while true -do - case "$1" in - -p|--path) path=$2; shift 2;; - --rootfs) rootfs=$2; shift 2;; - -n|--name) name=$2; shift 2;; - --) shift 1; break ;; - *) break ;; - esac -done - -br_name="virbr-${name}" -sub_net="102" # TODO from param - -# XXX assume rootfs if mounted from iso - -# Prepare container configuration file -> ${path}/config -cat <> ${path}/config -lxc.utsname = ${name} -lxc.rootfs = ${rootfs} - -# userns 1-to-1 mapping -#lxc.id_map = u 0 0 65536 -#lxc.id_map = g 0 0 65536 - -lxc.pts = 256 -lxc.tty = 0 - -lxc.mount.auto = proc sys cgroup -lxc.mount.entry = /var/run/containers/${name}/run var/run none rw,bind 0 0 - -lxc.network.type = veth -lxc.network.link = ${br_name} -lxc.network.flags = up -lxc.network.name = eth0 -lxc.network.veth.pair = veth-${name} -lxc.network.ipv4.gateway = 10.0.${sub_net}.1 -lxc.network.ipv4 = 10.0.${sub_net}.2/24 - -lxc.hook.pre-start = ${path}/pre-start.sh - -#lxc.loglevel = TRACE -#lxc.logfile = /tmp/${name}.log -EOF - -# prepare pre start hook -cat <> ${path}/pre-start.sh -if [ -z "\$(/usr/sbin/brctl show | /bin/grep -P "${br_name}\t")" ] -then - /usr/sbin/brctl addbr ${br_name} - /usr/sbin/brctl setfd ${br_name} 0 - /sbin/ifconfig ${br_name} 10.0.${sub_net}.1 netmask 255.255.255.0 up -fi -if [ -z "\$(/usr/sbin/iptables -t nat -S | /bin/grep MASQUERADE)" ] -then - /bin/echo 1 > /proc/sys/net/ipv4/ip_forward - /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -j MASQUERADE -fi -EOF - -chmod 755 ${path}/pre-start.sh diff --git a/server/configs/lxc-templates/template.sh b/server/configs/lxc-templates/template.sh index c03a050..531ec30 100755 --- a/server/configs/lxc-templates/template.sh +++ b/server/configs/lxc-templates/template.sh @@ -2,7 +2,7 @@ echo LXC template, args: $@ -options=$(getopt -o p:n: -l rootfs:,path:,name: -- "$@") +options=$(getopt -o p:n: -l rootfs:,path:,name:,ipv4:,ipv4-gateway: -- "$@") if [ $? -ne 0 ]; then exit 1 fi @@ -14,13 +14,14 @@ do -p|--path) path=$2; shift 2;; --rootfs) rootfs=$2; shift 2;; -n|--name) name=$2; shift 2;; + --ipv4) ipv4=$2; shift 2;; + --ipv4-gateway) ipv4_gateway=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done br_name="virbr-${name}" -sub_net="103" # TODO from param # XXX assume rootfs if mounted from iso @@ -40,13 +41,16 @@ lxc.tty = 0 lxc.mount.auto = proc sys cgroup lxc.mount.entry = /var/run/containers/${name}/run var/run none rw,bind 0 0 +# create a separate network per container +# - it forbids traffic sniffing (like macvlan in bridge mode) +# - it enables traffic controlling from host using iptables lxc.network.type = veth lxc.network.link = ${br_name} lxc.network.flags = up lxc.network.name = eth0 lxc.network.veth.pair = veth-${name} -lxc.network.ipv4.gateway = 10.0.${sub_net}.1 -lxc.network.ipv4 = 10.0.${sub_net}.2/24 +lxc.network.ipv4.gateway = ${ipv4_gateway} +lxc.network.ipv4 = ${ipv4}/24 lxc.hook.pre-start = ${path}/pre-start.sh @@ -55,12 +59,13 @@ lxc.hook.pre-start = ${path}/pre-start.sh EOF # prepare pre start hook +> ${path}/pre-start.sh cat <> ${path}/pre-start.sh if [ -z "\$(/usr/sbin/brctl show | /bin/grep -P "${br_name}\t")" ] then /usr/sbin/brctl addbr ${br_name} /usr/sbin/brctl setfd ${br_name} 0 - /sbin/ifconfig ${br_name} 10.0.${sub_net}.1 netmask 255.255.255.0 up + /sbin/ifconfig ${br_name} ${ipv4_gateway} netmask 255.255.255.0 up fi if [ -z "\$(/usr/sbin/iptables -t nat -S | /bin/grep MASQUERADE)" ] then diff --git a/server/configs/templates/template.conf b/server/configs/templates/template.conf index f91bf5f..1939d51 100644 --- a/server/configs/templates/template.conf +++ b/server/configs/templates/template.conf @@ -2,6 +2,8 @@ "name" : "~NAME~", "lxcTemplate" : "template.sh", "initWithArgs" : [], + "ipv4Gateway" : "10.0.~IP~.1", + "ipv4" : "10.0.~IP~.2", "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "privilege" : 10, diff --git a/server/container-admin.cpp b/server/container-admin.cpp index 71185db..ef8ae0f 100644 --- a/server/container-admin.cpp +++ b/server/container-admin.cpp @@ -91,7 +91,16 @@ ContainerAdmin::ContainerAdmin(const std::string& containersPath, const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate, lxcTemplatePrefix); LOGI(mId << ": Creating domain from template: " << lxcTemplate); - if (!mDom.create(lxcTemplate)) { + std::vector args; + if (!config.ipv4Gateway.empty()) { + args.push_back("--ipv4-gateway"); + args.push_back(config.ipv4Gateway); + } + if (!config.ipv4.empty()) { + args.push_back("--ipv4"); + args.push_back(config.ipv4); + } + if (!mDom.create(lxcTemplate, Args(args).getAsCArray())) { throw ContainerOperationException("Could not create domain"); } } diff --git a/server/container-config.hpp b/server/container-config.hpp index 95030e0..779415d 100644 --- a/server/container-config.hpp +++ b/server/container-config.hpp @@ -53,6 +53,16 @@ struct ContainerConfig { std::vector initWithArgs; /** + * IP v4 gateway address + */ + std::string ipv4Gateway; + + /** + * IP v4 address + */ + std::string ipv4; + + /** * Privilege of the container. * The smaller the value the more important the container */ @@ -107,6 +117,8 @@ struct ContainerConfig { name, lxcTemplate, initWithArgs, + ipv4Gateway, + ipv4, privilege, vt, switchToDefaultAfterTimeout, diff --git a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf.in index 6855a28..bf8d1fc 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf.in +++ b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console1-dbus", "lxcTemplate" : "minimal-dbus1.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf.in index 728522a..73ff1b3 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf.in +++ b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console2-dbus", "lxcTemplate" : "minimal-dbus2.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : false, diff --git a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf.in index d273e57..c8a0a01 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf.in +++ b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console3-dbus", "lxcTemplate" : "minimal-dbus3.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/lxc/ut-domain.cpp b/tests/unit_tests/lxc/ut-domain.cpp index aa6c3a9..a529f9f 100644 --- a/tests/unit_tests/lxc/ut-domain.cpp +++ b/tests/unit_tests/lxc/ut-domain.cpp @@ -42,6 +42,7 @@ using namespace security_containers::lxc; const std::string LXC_PATH = "/tmp/ut-lxc/"; const std::string DOMAIN_NAME = "ut-domain"; const std::string TEMPLATE = SC_TEST_LXC_TEMPLATES_INSTALL_DIR "/minimal.sh"; +const char* TEMPLATE_ARGS[] = {NULL}; struct Fixture { utils::ScopedDir mLxcDirGuard; @@ -89,7 +90,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyTest) LxcDomain lxc(LXC_PATH, DOMAIN_NAME); BOOST_CHECK(!lxc.isDefined()); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); BOOST_CHECK(lxc.isDefined()); BOOST_CHECK_EQUAL(lxc.getConfigItem("lxc.rootfs"), LXC_PATH + DOMAIN_NAME + "/rootfs"); @@ -104,7 +105,7 @@ BOOST_AUTO_TEST_CASE(StartShutdownTest) { { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } LxcDomain lxc(LXC_PATH, DOMAIN_NAME); BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); @@ -127,7 +128,7 @@ BOOST_AUTO_TEST_CASE(StartStopTest) { { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } LxcDomain lxc(LXC_PATH, DOMAIN_NAME); BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); @@ -149,7 +150,7 @@ BOOST_AUTO_TEST_CASE(StartHasStoppedTest) { { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } LxcDomain lxc(LXC_PATH, DOMAIN_NAME); BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); @@ -170,7 +171,7 @@ BOOST_AUTO_TEST_CASE(StartHasStoppedTest) BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); const char* argv[] = { "/bin/sh", "-c", @@ -193,7 +194,7 @@ BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) BOOST_AUTO_TEST_CASE(FreezeStopTest) { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); const char* argv[] = { "/bin/sh", "-c", @@ -216,8 +217,8 @@ BOOST_AUTO_TEST_CASE(FreezeStopTest) BOOST_AUTO_TEST_CASE(RepeatTest) { LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.create(TEMPLATE)); - BOOST_CHECK(!lxc.create(TEMPLATE));// forbidden + BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); + BOOST_CHECK(!lxc.create(TEMPLATE, TEMPLATE_ARGS));// forbidden const char* argv[] = { "/bin/sh", "-c", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf index 22f5810..ffa8652 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf @@ -2,6 +2,8 @@ "name" : "ut-container-admin-test", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/foo"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf index 6ff36fe..686dde2 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf @@ -2,6 +2,8 @@ "name" : "ut-container-admin-test", "lxcTemplate" : "missing.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf index 7877f8e..307afd5 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf @@ -2,6 +2,8 @@ "name" : "ut-container-admin-test", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf index a7cf00d..76f4a70 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf @@ -2,6 +2,8 @@ "name" : "ut-container-admin-test", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf index c31efc5..2af10da 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf @@ -2,6 +2,8 @@ "name" : "ut-container-test", "lxcTemplate" : "/buggy/path", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf.in b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf.in index e3eaf9b..f8e60f6 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-container-test-dbus", "lxcTemplate" : "minimal-dbus1.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-container/containers/test.conf b/tests/unit_tests/server/configs/ut-container/containers/test.conf index ec6bf54..1264669 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/test.conf @@ -2,6 +2,8 @@ "name" : "ut-container-test", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf.in index 6855a28..bf8d1fc 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console1-dbus", "lxcTemplate" : "minimal-dbus1.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf index 2bc7251..1ca1e5f 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console1", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf.in index 728522a..73ff1b3 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console2-dbus", "lxcTemplate" : "minimal-dbus2.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : false, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf index 9a0134f..155910b 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console2", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf.in index d273e57..c8a0a01 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf.in @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console3-dbus", "lxcTemplate" : "minimal-dbus3.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf index 6ff8900..a144c79 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf @@ -2,6 +2,8 @@ "name" : "ut-containers-manager-console3", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 15, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-server/containers/container1.conf b/tests/unit_tests/server/configs/ut-server/containers/container1.conf index d232bc3..995efb4 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container1.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container1.conf @@ -2,6 +2,8 @@ "name" : "ut-server-container1", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-server/containers/container2.conf b/tests/unit_tests/server/configs/ut-server/containers/container2.conf index 650782f..1e9b3b7 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container2.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container2.conf @@ -2,6 +2,8 @@ "name" : "ut-server-container2", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, diff --git a/tests/unit_tests/server/configs/ut-server/containers/container3.conf b/tests/unit_tests/server/configs/ut-server/containers/container3.conf index 0d9f947..47396f5 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container3.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container3.conf @@ -2,6 +2,8 @@ "name" : "ut-server-container3", "lxcTemplate" : "minimal.sh", "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "ipv4Gateway" : "", + "ipv4" : "", "privilege" : 15, "vt" : -1, "switchToDefaultAfterTimeout" : true, -- 2.7.4 From 734be9c06a56b1492ea90589ebfb6af0667d7841 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 25 Nov 2014 14:33:28 +0100 Subject: [PATCH 04/16] Add client stubs for domain lifetime management [Bug/Feature] Client stubs for domain lifetime management [Cause] N/A [Solution] N/A [Verification] Build Change-Id: I4b6b659e4de5e18d2b00851ecbdeacfd80e3d442 Signed-off-by: Dariusz Michaluk --- client/security-containers-client-impl.cpp | 12 ++++++++++++ client/security-containers-client-impl.hpp | 10 ++++++++++ client/security-containers-client.cpp | 10 ++++++++++ client/security-containers-client.h | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 2fcc776..0f08a02 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -471,6 +471,18 @@ VsmStatus Client::vsm_start_domain(const char*) noexcept return vsm_get_status(); } +VsmStatus Client::vsm_lock_domain(const char*) noexcept +{ + mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); + return vsm_get_status(); +} + +VsmStatus Client::vsm_unlock_domain(const char*) noexcept +{ + mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); + return vsm_get_status(); +} + VsmStatus Client::vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback, void* data, VsmSubscriptionId* subscriptionId) noexcept diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index 48e1c19..df07099 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -159,6 +159,16 @@ public: VsmStatus vsm_start_domain(const char* id) noexcept; /** + * @see ::vsm_lock_domain + */ + VsmStatus vsm_lock_domain(const char* id) noexcept; + + /** + * @see ::vsm_unlock_domain + */ + VsmStatus vsm_unlock_domain(const char* id) noexcept; + + /** * @see ::vsm_add_state_callback */ VsmStatus vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback, diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index e867a9e..b96718f 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -173,6 +173,16 @@ API VsmStatus vsm_start_domain(VsmClient client, const char* id) return getClient(client).vsm_start_domain(id); } +API VsmStatus vsm_lock_domain(VsmClient client, const char* id) +{ + return getClient(client).vsm_lock_domain(id); +} + +API VsmStatus vsm_unlock_domain(VsmClient client, const char* id) +{ + return getClient(client).vsm_unlock_domain(id); +} + API VsmStatus vsm_add_state_callback(VsmClient client, VsmContainerDbusStateCallback containerDbusStateCallback, void* data, diff --git a/client/security-containers-client.h b/client/security-containers-client.h index ee16e01..b796c16 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -401,6 +401,24 @@ VsmStatus vsm_shutdown_domain(VsmClient client, const char* id); VsmStatus vsm_start_domain(VsmClient client, const char* id); /** + * Lock domain + * + * @param[in] client security-containers-server's client + * @param[in] id domain name + * @return status of this function call + */ +VsmStatus vsm_lock_domain(VsmClient client, const char* id); + +/** + * Unlock domain + * + * @param[in] client security-containers-server's client + * @param[in] id domain name + * @return status of this function call + */ +VsmStatus vsm_unlock_domain(VsmClient client, const char* id); + +/** * Register dbus state change callback function. * * @note The callback function will be invoked on a different thread. -- 2.7.4 From 8bf786c5dbd0a19132e439fc0800a613aa4fa544 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 25 Nov 2014 16:13:41 +0100 Subject: [PATCH 05/16] Added lock_domain/unlock_domain to cli [Feature] Ability to lock/unlock domain through cli [Cause] The need for the ability to lock/unlock domains [Solution] Add lock_domain/unlock_domain cli function [Verification] Build, install, run Change-Id: I4a017b328f0b44913f0561bd444e913c68f67359 Signed-off-by: Dariusz Michaluk --- cli/command-line-interface.cpp | 22 ++++++++++++++++++++++ cli/command-line-interface.hpp | 14 ++++++++++++++ cli/main.cpp | 16 ++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index d027e63..0549afd 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -154,6 +154,28 @@ void create_domain(int pos, int argc, const char** argv) one_shot(bind(vsm_create_domain, _1, argv[pos + 1], nullptr)); } +void lock_domain(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 1) { + throw runtime_error("Not enough parameters"); + } + + one_shot(bind(vsm_lock_domain, _1, argv[pos + 1])); +} + +void unlock_domain(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 1) { + throw runtime_error("Not enough parameters"); + } + + one_shot(bind(vsm_unlock_domain, _1, argv[pos + 1])); +} + void lookup_domain_by_id(int pos, int argc, const char** argv) { using namespace std::placeholders; diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index c254d84..41f5048 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -111,6 +111,20 @@ void set_active_container(int pos, int argc, const char** argv); void create_domain(int pos, int argc, const char** argv); /** + * Parses command line arguments and call vsm_lock_domain + * + * @see vsm_lock_domain + */ +void lock_domain(int pos, int argc, const char** argv); + +/** + * Parses command line arguments and call vsm_unlock_domain + * + * @see vsm_unlock_domain + */ +void unlock_domain(int pos, int argc, const char** argv); + +/** * Parses command line arguments and call vsm_lookup_domain_by_id * * @see vsm_lookup_domain_by_id diff --git a/cli/main.cpp b/cli/main.cpp index d701475..774881b 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -50,6 +50,22 @@ std::map commands = { } }, { + "lock_domain", { + lock_domain, + "lock_domain container_id", + "Lock container", + {{"container_id", "id container name"}} + } + }, + { + "unlock_domain", { + unlock_domain, + "unlock_domain container_id", + "Unlock container", + {{"container_id", "id container name"}} + } + }, + { "lookup_domain_by_id", { lookup_domain_by_id, "lookup_domain_by_id container_id", -- 2.7.4 From 67c0aa5c4ea021326fd0d1565143543e29f468a2 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 24 Nov 2014 15:33:27 +0100 Subject: [PATCH 06/16] Add tizen common (with wayland) lxc template Change-Id: If6d1fe2641f9a36a7d3a8c16b9a658661491ff13 Signed-off-by: Dariusz Michaluk --- .../configs/lxc-templates/tizen-common-wayland.sh | 398 +++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100755 server/configs/lxc-templates/tizen-common-wayland.sh diff --git a/server/configs/lxc-templates/tizen-common-wayland.sh b/server/configs/lxc-templates/tizen-common-wayland.sh new file mode 100755 index 0000000..002e1f7 --- /dev/null +++ b/server/configs/lxc-templates/tizen-common-wayland.sh @@ -0,0 +1,398 @@ +#!/bin/bash + +# lxc-tizen template script +# +# Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved +# +# Contact: Dariusz Michaluk +# +# 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. + +usage() +{ + cat < + [-p|--path=] [-r|--rootfs=] [-v|--vt=] + [--ipv4=] [--ipv4-gateway=] [-h|--help] +Mandatory args: + -n,--name container name +Optional args: + -p,--path path to container config files, defaults to /var/lib/lxc + --rootfs path to container rootfs, defaults to /var/lib/lxc/[NAME]/rootfs + -v,--vt container virtual terminal + --ipv4 container IP address + --ipv4-gateway container gateway + -h,--help print help +EOF + return 0 +} + +options=$(getopt -o hp:v:n: -l help,rootfs:,path:,vt:,name:,ipv4:,ipv4-gateway: -- "$@") +if [ $? -ne 0 ]; then + usage $(basename $0) + exit 1 +fi +eval set -- "$options" + +while true +do + case "$1" in + -h|--help) usage $0 && exit 0;; + --rootfs) rootfs=$2; shift 2;; + -p|--path) path=$2; shift 2;; + -v|--vt) vt=$2; shift 2;; + -n|--name) name=$2; shift 2;; + --ipv4) ipv4=$2; shift 2;; + --ipv4-gateway) ipv4_gateway=$2; shift 2;; + --) shift 1; break ;; + *) break ;; + esac +done + +if [ "$(id -u)" != "0" ]; then + echo "This script should be run as 'root'" + exit 1 +fi + +if [ -z $name ]; then + echo "Container name must be given" + exit 1 +fi + +if [ -z "$path" ]; then + echo "'path' parameter is required" + exit 1 +fi + +br_name="virbr-${name}" + +# Prepare container rootfs +ROOTFS_DIRS="\ +${rootfs}/bin \ +${rootfs}/dev \ +${rootfs}/etc \ +${rootfs}/home \ +${rootfs}/home/alice \ +${rootfs}/home/bob \ +${rootfs}/home/carol \ +${rootfs}/home/guest \ +${rootfs}/lib \ +${rootfs}/media \ +${rootfs}/mnt \ +${rootfs}/opt \ +${rootfs}/proc \ +${rootfs}/root \ +${rootfs}/run \ +${rootfs}/run/dbus \ +${rootfs}/run/memory \ +${rootfs}/run/systemd \ +${rootfs}/run/udev \ +${rootfs}/sbin \ +${rootfs}/sys \ +${rootfs}/tmp \ +${rootfs}/usr \ +${path}/hooks \ +${path}/scripts \ +${path}/systemd \ +${path}/systemd/system \ +${path}/systemd/user +" +/bin/mkdir ${ROOTFS_DIRS} +/bin/chown alice:users ${rootfs}/home/alice +/bin/chown bob:users ${rootfs}/home/bob +/bin/chown carol:users ${rootfs}/home/carol +/bin/chown guest:users ${rootfs}/home/guest + +/bin/ln -s /dev/null ${path}/systemd/system/bluetooth.service +/bin/ln -s /dev/null ${path}/systemd/system/sshd.service +/bin/ln -s /dev/null ${path}/systemd/system/sshd.socket +/bin/ln -s /dev/null ${path}/systemd/system/sshd@.service +/bin/ln -s /dev/null ${path}/systemd/system/systemd-udevd.service +/bin/ln -s /dev/null ${path}/systemd/system/user-session-launch@seat0-5100.service +/bin/ln -s /dev/null ${path}/systemd/system/vconf-setup.service + +cat <>${path}/systemd/system/display-manager-run.service +# Run weston with framebuffer backend on selected virtual terminal. +[Unit] +Description=Weston display daemon + +[Service] +User=display +WorkingDirectory=/run/%u +# FIXME: log files shouldn't be stored in tmpfs directories (can get quite big and have side effects) +#ExecStart=/bin/sh -c 'backend=drm ; [ -d /dev/dri ] || backend=fbdev ; exec /usr/bin/weston --backend=$backend-backend.so -i0 --log=/run/%u/weston.log' +ExecStart=/usr/bin/weston --backend=fbdev-backend.so -i0 --log=/tmp/weston.log --tty=${vt} +#StandardInput=tty +#TTYPath=/dev/tty7 +EnvironmentFile=/etc/systemd/system/weston +Restart=on-failure +RestartSec=10 + +#adding the capability to configure ttys +#may be needed if the user 'display' doesn't own the tty +CapabilityBoundingSet=CAP_SYS_TTY_CONFIG + +[Install] +WantedBy=graphical.target +EOF + +cat <>${path}/systemd/system/display-manager.path +# Wayland socket path is changed to /tmp directory. +[Unit] +Description=Wait for wayland socket +Requires=display-manager-run.service +After=display-manager-run.service + +[Path] +PathExists=/tmp/wayland-0 +EOF + +cat <>${path}/systemd/system/display-manager.service +# Wayland socket path is changed to /tmp directory. +[Unit] +Description=Display manager setup service +Requires=display-manager-run.service +After=display-manager-run.service + +[Service] +Type=oneshot +ExecStart=/usr/bin/chmod g+w /tmp/wayland-0 +#ExecStart=/usr/bin/chsmack -a User /tmp/wayland-0 + +[Install] +WantedBy=graphical.target +EOF + +cat <>${path}/systemd/system/weston +# path to display manager runtime dir +XDG_RUNTIME_DIR=/tmp +XDG_CONFIG_HOME=/etc/systemd/system +EOF + +cat <>${path}/systemd/system/weston.ini +# Weston config for container. +[core] +modules=desktop-shell.so + +[shell] +background-image=/usr/share/backgrounds/tizen/golfe-morbihan.jpg +background-color=0xff002244 +background-type=scale-crop +panel-color=0x95333333 +locking=true +panel=false +animation=zoom +#binding-modifier=ctrl +num-workspaces=4 +#cursor-theme=whiteglass +#cursor-size=24 +startup-animation=fade + +#lockscreen-icon=/usr/share/icons/gnome/256x256/actions/lock.png +#lockscreen=/usr/share/backgrounds/gnome/Garden.jpg +#homescreen=/usr/share/backgrounds/gnome/Blinds.jpg + +## weston + +[launcher] +icon=/usr/share/icons/tizen/32x32/terminal.png +path=/usr/bin/weston-terminal + +[screensaver] +# Uncomment path to disable screensaver +duration=600 + +[input-method] +path=/usr/libexec/weston-keyboard +#path=/bin/weekeyboard + +#[keyboard] +#keymap_layout=fr + +#[output] +#name=LVDS1 +#mode=1680x1050 +#transform=90 +#icc_profile=/usr/share/color/icc/colord/Bluish.icc + +#[output] +#name=VGA1 +#mode=173.00 1920 2048 2248 2576 1080 1083 1088 1120 -hsync +vsync +#transform=flipped + +#[output] +#name=X1 +#mode=1024x768 +#transform=flipped-270 + +#[touchpad] +#constant_accel_factor = 50 +#min_accel_factor = 0.16 +#max_accel_factor = 1.0 + +[output] +name=DP1 +default_output=1 +EOF + +cat <>${path}/systemd/user/weston-user.service +# Wayland socket path is changed to /tmp directory. +[Unit] +Description=Shared weston session + +[Service] +ExecStartPre=/usr/bin/ln -sf /tmp/wayland-0 /run/user/%U/ +ExecStart=/bin/sh -l -c "/usr/bin/tz-launcher -c /usr/share/applications/tizen/launcher.conf %h/.applications/desktop" +EnvironmentFile=/etc/sysconfig/weston-user + +[Install] +WantedBy=default.target +EOF + +# Prepare host configuration +cat <>/etc/udev/rules.d/99-tty.rules +SUBSYSTEM=="tty", KERNEL=="tty${vt}", OWNER="display", SECLABEL{smack}="^" +EOF + +cat </etc/systemd/system/display-manager-run.service +# Run weston with framebuffer backend on tty7. +[Unit] +Description=Weston display daemon + +[Service] +User=display +WorkingDirectory=/run/%u +# FIXME: log files shouldn't be stored in tmpfs directories (can get quite big and have side effects) +#ExecStart=/bin/sh -c 'backend=drm ; [ -d /dev/dri ] || backend=fbdev ; exec /usr/bin/weston --backend=$backend-backend.so -i0 --log=/run/%u/weston.log' +ExecStart=/usr/bin/weston --backend=fbdev-backend.so -i0 --log=/run/%u/weston.log +StandardInput=tty +TTYPath=/dev/tty7 +EnvironmentFile=/etc/sysconfig/weston +Restart=on-failure +RestartSec=10 + +#adding the capability to configure ttys +#may be needed if the user 'display' doesn't own the tty +#CapabilityBoundingSet=CAP_SYS_TTY_CONFIG + +[Install] +WantedBy=graphical.target +EOF + +# Prepare container configuration file +cat <>${path}/config +lxc.utsname = ${name} +lxc.rootfs = ${rootfs} + +#lxc.cap.drop = audit_control +#lxc.cap.drop = audit_write +#lxc.cap.drop = mac_admin +#lxc.cap.drop = mac_override +#lxc.cap.drop = mknod +#lxc.cap.drop = setfcap +#lxc.cap.drop = setpcap +#lxc.cap.drop = sys_admin +#lxc.cap.drop = sys_boot +#lxc.cap.drop = sys_chroot #required by SSH +#lxc.cap.drop = sys_module +#lxc.cap.drop = sys_nice +#lxc.cap.drop = sys_pacct +#lxc.cap.drop = sys_rawio +#lxc.cap.drop = sys_resource +#lxc.cap.drop = sys_time +#lxc.cap.drop = sys_tty_config #required by getty + +lxc.cgroup.devices.deny = a +lxc.cgroup.devices.allow = c 1:* rwm #/dev/null, /dev/zero, ... +lxc.cgroup.devices.allow = c 5:* rwm #/dev/console, /dev/ptmx, ... +lxc.cgroup.devices.allow = c 136:* rwm #/dev/pts/0 ... +lxc.cgroup.devices.allow = c 10:223 rwm #/dev/uinput +lxc.cgroup.devices.allow = c 13:64 rwm #/dev/input/event0 +lxc.cgroup.devices.allow = c 13:65 rwm #/dev/input/event1 +lxc.cgroup.devices.allow = c 13:66 rwm #/dev/input/event2 +lxc.cgroup.devices.allow = c 13:67 rwm #/dev/input/event3 +lxc.cgroup.devices.allow = c 13:68 rwm #/dev/input/event4 +lxc.cgroup.devices.allow = c 13:69 rwm #/dev/input/event5 +lxc.cgroup.devices.allow = c 13:63 rwm #/dev/input/mice +lxc.cgroup.devices.allow = c 13:32 rwm #/dev/input/mouse0 +lxc.cgroup.devices.allow = c 226:0 rwm #/dev/dri/card0 +lxc.cgroup.devices.allow = c 2:* rwm #/dev/pty + +lxc.pts = 256 +lxc.tty = 0 +#lxc.console=/dev/tty1 +lxc.kmsg = 0 + +#lxc.cgroup.cpu.shares = 1024 +#lxc.cgroup.cpuset.cpus = 0,1,2,3 +#lxc.cgroup.memory.limit_in_bytes = 512M +#lxc.cgroup.memory.memsw.limit_in_bytes = 1G +#lxc.cgroup.blkio.weight = 500 + +lxc.mount.auto = proc sys:rw cgroup +lxc.mount = ${path}/fstab + +# create a separate network per container +# - it forbids traffic sniffing (like macvlan in bridge mode) +# - it enables traffic controlling from host using iptables +lxc.network.type = veth +lxc.network.link = ${br_name} +lxc.network.flags = up +lxc.network.name = eth0 +lxc.network.veth.pair = veth-${name} +lxc.network.ipv4.gateway = ${ipv4_gateway} +lxc.network.ipv4 = ${ipv4}/24 + +lxc.hook.pre-start = ${path}/hooks/pre-start.sh +#lxc.hook.post-stop = ${path}/hooks/post-stop.sh +EOF + +# Prepare container hook files +cat <>${path}/hooks/pre-start.sh +if [ -z "\$(/usr/sbin/brctl show | /bin/grep -P "${br_name}\t")" ] +then + /usr/sbin/brctl addbr ${br_name} + /usr/sbin/brctl setfd ${br_name} 0 + /sbin/ifconfig ${br_name} ${ipv4_gateway} netmask 255.255.255.0 up +fi +if [ -z "\$(/usr/sbin/iptables -t nat -S | /bin/grep MASQUERADE)" ] +then + /bin/echo 1 > /proc/sys/net/ipv4/ip_forward + /usr/sbin/iptables -t nat -A POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -j MASQUERADE +fi +EOF + +chmod 770 ${path}/hooks/pre-start.sh + +# Prepare container fstab file +cat <>${path}/fstab +/bin bin none ro,bind 0 0 +/etc etc none ro,bind 0 0 +${path}/systemd/system etc/systemd/system none ro,bind 0 0 +${path}/systemd/user etc/systemd/user none ro,bind 0 0 +/lib lib none ro,bind 0 0 +/media media none ro,bind 0 0 +/mnt mnt none ro,bind 0 0 +/sbin sbin none ro,bind 0 0 +/usr usr none ro,rbind 0 0 +/opt opt none rw,rbind 0 0 +devtmpfs dev devtmpfs rw,relatime,mode=755 0 0 +devpts dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0 +/run/dbus run/dbus none rw,bind 0 0 +/run/memory run/memory none rw,bind 0 0 +/run/systemd run/systemd none rw,bind 0 0 +/run/udev run/udev none rw,bind 0 0 +/sys/fs/smackfs sys/fs/smackfs none rw,bind 0 0 +#tmpfs run tmpfs rw,nosuid,nodev,mode=755 0 0 +EOF -- 2.7.4 From 24a8cab8c347623492ea89d32e8d250e9e1e1c03 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 26 Nov 2014 15:24:00 +0100 Subject: [PATCH 07/16] Added testing union in config file [Bug/Feature] Testing union in config file [Cause] Added union to config [Solution] Added union field in testing structure [Verification] Build, install, run scs tests Change-Id: I538e6ea370ea1a57f647bbde0f040b1585a4fd0a --- tests/unit_tests/config/ut-configuration.cpp | 47 ++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index 1d72bd8..7f9703b 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -26,6 +26,7 @@ #include "config.hpp" #include "ut.hpp" #include "config/fields.hpp" +#include "config/fields-union.hpp" #include "config/manager.hpp" #include #include @@ -62,6 +63,14 @@ struct TestConfig { ) }; + struct SubConfigOption { + CONFIG_DECLARE_UNION + ( + SubConfig, + int + ) + }; + int intVal; std::int64_t int64Val; std::string stringVal; @@ -76,6 +85,10 @@ struct TestConfig { SubConfig subObj; std::vector subVector; + SubConfigOption union1; + SubConfigOption union2; + std::vector unions; + CONFIG_REGISTER ( intVal, @@ -90,7 +103,11 @@ struct TestConfig { doubleVector, subObj, - subVector + subVector, + + union1, + union2, + unions ) }; @@ -111,7 +128,14 @@ const std::string jsonTestString = "\"doubleVector\": [ 0.000000, 1.000000, 2.000000 ], " "\"subObj\": { \"intVal\": 54321, \"intVector\": [ 1, 2 ], \"subSubObj\": { \"intVal\": 234 } }, " "\"subVector\": [ { \"intVal\": 123, \"intVector\": [ 3, 4 ], \"subSubObj\": { \"intVal\": 345 } }, " - "{ \"intVal\": 456, \"intVector\": [ 5, 6 ], \"subSubObj\": { \"intVal\": 567 } } ] }"; + "{ \"intVal\": 456, \"intVector\": [ 5, 6 ], \"subSubObj\": { \"intVal\": 567 } } ], " + "\"union1\": { \"type\": \"int\", \"value\": 2 }, " + "\"union2\": { \"type\": \"SubConfig\", \"value\": { \"intVal\": 54321, \"intVector\": [ 1 ], " + "\"subSubObj\": { \"intVal\": 234 } } }, " + "\"unions\": [ " + "{ \"type\": \"int\", \"value\": 2 }, " + "{ \"type\": \"SubConfig\", \"value\": { \"intVal\": 54321, \"intVector\": [ 1 ], " + "\"subSubObj\": { \"intVal\": 234 } } } ] }"; // Floating point tolerance as a number of rounding errors const int TOLERANCE = 1; @@ -344,4 +368,23 @@ BOOST_AUTO_TEST_CASE(FromToFDTest) fs::remove(fifoPath); } +BOOST_AUTO_TEST_CASE(ConfigUnion) +{ + TestConfig testConfig; + BOOST_REQUIRE_NO_THROW(loadFromString(jsonTestString, testConfig)); + + BOOST_CHECK(testConfig.union1.is()); + BOOST_CHECK(!testConfig.union1.is()); + BOOST_CHECK_EQUAL(testConfig.union1.as(), 2); + BOOST_CHECK(!testConfig.union2.is()); + BOOST_CHECK(testConfig.union2.is()); + TestConfig::SubConfig& subConfig = testConfig.union2.as(); + BOOST_CHECK_EQUAL(subConfig.intVal, 54321); + BOOST_CHECK(testConfig.unions[0].is()); + BOOST_CHECK(testConfig.unions[1].is()); + + std::string out = saveToString(testConfig); + BOOST_CHECK_EQUAL(out, jsonTestString); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 14ad168b8ffff24f1775e497e4762d1682c544f9 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Thu, 27 Nov 2014 16:39:33 +0100 Subject: [PATCH 08/16] Support for destroying container [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I4303284b06fdebf452a040c9dfa2c1cddc0b8abf --- cli/command-line-interface.cpp | 11 +++ cli/command-line-interface.hpp | 7 ++ cli/main.cpp | 8 ++ client/security-containers-client-impl.cpp | 9 ++- client/security-containers-client.cpp | 2 +- client/security-containers-client.h | 2 +- server/common-dbus-definitions.hpp | 2 +- server/container-admin.cpp | 14 ++++ server/container-admin.hpp | 6 ++ server/container.cpp | 6 ++ server/container.hpp | 5 ++ server/containers-manager.cpp | 94 +++++++++++++++------- server/containers-manager.hpp | 17 +++- server/host-connection.cpp | 24 ++++-- server/host-connection.hpp | 15 +++- server/host-dbus-definitions.hpp | 9 ++- tests/unit_tests/client/ut-client.cpp | 2 +- tests/unit_tests/server/configs/CMakeLists.txt | 9 ++- .../empty-dbus-daemon.conf.in | 22 +++++ .../ut-containers-manager/templates/template.conf | 11 --- .../templates/template.conf.in | 16 ++++ tests/unit_tests/server/ut-containers-manager.cpp | 83 ++++++++++++------- 22 files changed, 279 insertions(+), 95 deletions(-) create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in delete mode 100644 tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf create mode 100644 tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index 0549afd..b46871d 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -154,6 +154,17 @@ void create_domain(int pos, int argc, const char** argv) one_shot(bind(vsm_create_domain, _1, argv[pos + 1], nullptr)); } +void destroy_domain(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 1) { + throw runtime_error("Not enough parameters"); + } + + one_shot(bind(vsm_destroy_domain, _1, argv[pos + 1], 1)); +} + void lock_domain(int pos, int argc, const char** argv) { using namespace std::placeholders; diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index 41f5048..360f46c 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -111,6 +111,13 @@ void set_active_container(int pos, int argc, const char** argv); void create_domain(int pos, int argc, const char** argv); /** + * Parses command line arguments and call vsm_destroy_domain + * + * @see vsm_destroy_domain + */ +void destroy_domain(int pos, int argc, const char** argv); + +/** * Parses command line arguments and call vsm_lock_domain * * @see vsm_lock_domain diff --git a/cli/main.cpp b/cli/main.cpp index 774881b..0ceb1e5 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -50,6 +50,14 @@ std::map commands = { } }, { + "destroy_domain", { + destroy_domain, + "destroy_domain container_id", + "Destroy container", + {{"container_id", "id container name"}} + } + }, + { "lock_domain", { lock_domain, "lock_domain container_id", diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 0f08a02..1a6e999 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -450,13 +450,14 @@ VsmStatus Client::vsm_create_domain(const char* id, const char* tname) noexcept } GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_ADD_CONTAINER, args_in); + return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_CONTAINER, args_in); } -VsmStatus Client::vsm_destroy_domain(const char*) noexcept +VsmStatus Client::vsm_destroy_domain(const char* id) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); - return vsm_get_status(); + assert(id); + GVariant* args_in = g_variant_new("(s)", id); + return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_CONTAINER, args_in); } VsmStatus Client::vsm_shutdown_domain(const char*) noexcept diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index b96718f..ef571c8 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -158,7 +158,7 @@ API VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tn return getClient(client).vsm_create_domain(id, tname); } -API VsmStatus vsm_destroy_domain(VsmClient client, const char* id) +API VsmStatus vsm_destroy_domain(VsmClient client, const char* id, int /*force*/) { return getClient(client).vsm_destroy_domain(id); } diff --git a/client/security-containers-client.h b/client/security-containers-client.h index b796c16..e7e738c 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -380,7 +380,7 @@ VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tname) * @param[in] force if 0 data will be kept, otherwise data will be lost * @return status of this function call */ -VsmStatus vsm_destroy_domain(VsmStatus clent, const char* id, int force); +VsmStatus vsm_destroy_domain(VsmClient clent, const char* id, int force); /** * Shutdown domain diff --git a/server/common-dbus-definitions.hpp b/server/common-dbus-definitions.hpp index 14bb037..77d0949 100644 --- a/server/common-dbus-definitions.hpp +++ b/server/common-dbus-definitions.hpp @@ -32,7 +32,7 @@ namespace security_containers { namespace api { const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden"; const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded"; -const std::string ERROR_UNKNOWN_ID = "org.tizen.containers.Error.UnknownId"; +const std::string ERROR_INVALID_ID = "org.tizen.containers.Error.InvalidId"; const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal"; const std::string METHOD_PROXY_CALL = "ProxyCall"; diff --git a/server/container-admin.cpp b/server/container-admin.cpp index ef8ae0f..65179c3 100644 --- a/server/container-admin.cpp +++ b/server/container-admin.cpp @@ -111,6 +111,15 @@ ContainerAdmin::~ContainerAdmin() { LOGD(mId << ": Destroying ContainerAdmin object..."); + if (mDestroyOnExit) { + if (!mDom.stop()) { + LOGE(mId << ": Failed to stop the container"); + } + if (!mDom.destroy()) { + LOGE(mId << ": Failed to destroy the container"); + } + } + if (!mDetachOnExit) { // Try to forcefully stop if (!mDom.stop()) { @@ -271,6 +280,11 @@ void ContainerAdmin::setDetachOnExit() mDetachOnExit = true; } +void ContainerAdmin::setDestroyOnExit() +{ + mDestroyOnExit = true; +} + std::int64_t ContainerAdmin::getSchedulerQuota() { // assert(mDom); diff --git a/server/container-admin.hpp b/server/container-admin.hpp index 79b0193..f3c9a4f 100644 --- a/server/container-admin.hpp +++ b/server/container-admin.hpp @@ -116,6 +116,11 @@ public: void setDetachOnExit(); /** + * Set if container should be destroyed on exit. + */ + void setDestroyOnExit(); + + /** * @return Scheduler CFS quota, * TODO: this function is only for UNIT TESTS */ @@ -126,6 +131,7 @@ private: lxc::LxcDomain mDom; const std::string mId; bool mDetachOnExit; + bool mDestroyOnExit; void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota); }; diff --git a/server/container.cpp b/server/container.cpp index 80decd5..c371d8a 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -240,6 +240,12 @@ void Container::setDetachOnExit() } } +void Container::setDestroyOnExit() +{ + Lock lock(mReconnectMutex); + mAdmin->setDestroyOnExit(); +} + bool Container::isRunning() { Lock lock(mReconnectMutex); diff --git a/server/container.hpp b/server/container.hpp index 76e098a..bc1303c 100644 --- a/server/container.hpp +++ b/server/container.hpp @@ -135,6 +135,11 @@ public: void setDetachOnExit(); /** + * Set if container should be destroyed on exit. + */ + void setDestroyOnExit(); + + /** * @return Is the container running? */ bool isRunning(); diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index def04c2..5a6a32b 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -101,11 +101,14 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setSetActiveContainerCallback(bind(&ContainersManager::handleSetActiveContainerCall, this, _1, _2)); - mHostConnection.setAddContainerCallback(bind(&ContainersManager::handleAddContainerCall, - this, _1, _2)); + mHostConnection.setCreateContainerCallback(bind(&ContainersManager::handleCreateContainerCall, + this, _1, _2)); + + mHostConnection.setDestroyContainerCallback(bind(&ContainersManager::handleDestroyContainerCall, + this, _1, _2)); for (auto& containerConfig : mConfig.containerConfigs) { - addContainer(containerConfig); + createContainer(containerConfig); } // check if default container exists, throw ContainerOperationException if not found @@ -143,7 +146,7 @@ ContainersManager::~ContainersManager() LOGD("ContainersManager object destroyed"); } -void ContainersManager::addContainer(const std::string& containerConfig) +void ContainersManager::createContainer(const std::string& containerConfig) { std::string baseConfigPath = utils::dirName(mConfigPath); std::string containerConfigPath = utils::getAbsolutePath(containerConfig, baseConfigPath); @@ -177,6 +180,20 @@ void ContainersManager::addContainer(const std::string& containerConfig) mContainers.insert(ContainerMap::value_type(id, std::move(c))); } +void ContainersManager::destroyContainer(const std::string& containerId) +{ + // TODO mutex for mContainers access + auto it = mContainers.find(containerId); + if (it == mContainers.end()) { + LOGE("Failed to destroy container " << containerId << ": no such container"); + throw ContainerOperationException("No such container"); + } + + // TODO give back the focus + it->second->setDestroyOnExit(); + mContainers.erase(it); +} + void ContainersManager::focus(const std::string& containerId) { /* try to access the object first to throw immediately if it doesn't exist */ @@ -440,7 +457,7 @@ void ContainersManager::handleProxyCall(const std::string& caller, ContainerMap::const_iterator targetIter = mContainers.find(target); if (targetIter == mContainers.end()) { LOGE("Target container '" << target << "' not found"); - result->setError(api::ERROR_UNKNOWN_ID, "Unknown proxy call target"); + result->setError(api::ERROR_INVALID_ID, "Unknown proxy call target"); return; } @@ -501,7 +518,7 @@ void ContainersManager::handleGetContainerInfoCall(const std::string& id, LOGI("GetContainerInfo call"); if (mContainers.count(id) == 0) { LOGE("No container with id=" << id); - result->setError(api::ERROR_UNKNOWN_ID, "No such container id"); + result->setError(api::ERROR_INVALID_ID, "No such container id"); return; } const auto& container = mContainers[id]; @@ -536,7 +553,7 @@ void ContainersManager::handleSetActiveContainerCall(const std::string& id, auto container = mContainers.find(id); if (container == mContainers.end()){ LOGE("No container with id=" << id ); - result->setError(api::ERROR_UNKNOWN_ID, "No such container id"); + result->setError(api::ERROR_INVALID_ID, "No such container id"); return; } @@ -597,33 +614,30 @@ void ContainersManager::generateNewConfig(const std::string& id, fs::perms::others_read); } -void ContainersManager::handleAddContainerCall(const std::string& id, - dbus::MethodResultBuilder::Pointer result) +void ContainersManager::handleCreateContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result) { if (id.empty()) { LOGE("Failed to add container - invalid name."); - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, - "Failed to add container - invalid name."); + result->setError(api::ERROR_INVALID_ID, "Invalid name"); return; } - LOGI("Adding container " << id); + LOGI("Creating container " << id); // TODO: This solution is temporary. It utilizes direct access to config files when creating new // containers. Update this handler when config database will appear. namespace fs = boost::filesystem; - boost::system::error_code ec; - const std::string containerPathStr = utils::createFilePath(mConfig.containersPath, "/", id, "/"); - // check if container does not exist if (mContainers.find(id) != mContainers.end()) { LOGE("Cannot create " << id << " container - already exists!"); - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, - "Cannot create " + id + " container - already exists!"); + result->setError(api::ERROR_INVALID_ID, "Already exists"); return; } + const std::string containerPathStr = utils::createFilePath(mConfig.containersPath, "/", id, "/"); + // copy container image if config contains path to image LOGT("Image path: " << mConfig.containerImagePath); if (!mConfig.containerImagePath.empty()) { @@ -633,8 +647,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, if (!utils::launchAsRoot(copyImageContentsWrapper)) { LOGE("Failed to copy container image."); - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, - "Failed to copy container image."); + result->setError(api::ERROR_INTERNAL, "Failed to copy container image."); return; } } @@ -647,7 +660,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, std::string configPath = utils::createFilePath(templateDir, "/", CONTAINER_TEMPLATE_CONFIG_PATH); std::string newConfigPath = utils::createFilePath(configDir, "/containers/", id + ".conf"); - auto removeAllWrapper = [](const std::string& path) { + auto removeAllWrapper = [](const std::string& path) -> bool { try { LOGD("Removing copied data"); fs::remove_all(fs::path(path)); @@ -662,19 +675,19 @@ void ContainersManager::handleAddContainerCall(const std::string& id, generateNewConfig(id, configPath, newConfigPath); } catch (SecurityContainersException& e) { - LOGE(e.what()); + LOGE("Generate config failed: " << e.what()); utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what()); + result->setError(api::ERROR_INTERNAL, "Failed to generate config"); return; } - LOGT("Adding new container"); + LOGT("Creating new container"); try { - addContainer(newConfigPath); + createContainer(newConfigPath); } catch (SecurityContainersException& e) { - LOGE(e.what()); + LOGE("Creating new container failed: " << e.what()); utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what()); + result->setError(api::ERROR_INTERNAL, "Failed to create container"); return; } @@ -685,11 +698,36 @@ void ContainersManager::handleAddContainerCall(const std::string& id, } else { LOGE("Failed to start container."); // TODO removeContainer - result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, - "Failed to start container."); + result->setError(api::ERROR_INTERNAL, "Failed to start container"); } }; mContainers[id]->startAsync(resultCallback); } +void ContainersManager::handleDestroyContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result) +{ + if (mContainers.find(id) == mContainers.end()) { + LOGE("Failed to destroy container - no such container id: " << id); + result->setError(api::ERROR_INVALID_ID, "No such container id"); + return; + } + + LOGI("Destroying container " << id); + + auto destroyer = [id, result, this] { + try { + destroyContainer(id); + } catch (const SecurityContainersException& e) { + LOGE("Error during container destruction: " << e.what()); + result->setError(api::ERROR_INTERNAL, "Failed to destroy container"); + return; + } + result->setVoid(); + }; + + std::thread thread(destroyer); + thread.detach(); //TODO fix it +} + } // namespace security_containers diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index 16a8cf5..70637bc 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -47,11 +47,18 @@ public: ~ContainersManager(); /** - * Add new container. + * Create new container. * * @param containerConfig config of new container */ - void addContainer(const std::string& containerConfig); + void createContainer(const std::string& containerConfig); + + /** + * Destroy container. + * + * @param containerId id of the container + */ + void destroyContainer(const std::string& containerId); /** * Focus this container, put it to the foreground. @@ -126,8 +133,10 @@ private: void handleGetContainerInfoCall(const std::string& id, dbus::MethodResultBuilder::Pointer result); void handleSetActiveContainerCall(const std::string& id, dbus::MethodResultBuilder::Pointer result); - void handleAddContainerCall(const std::string& id, - dbus::MethodResultBuilder::Pointer result); + void handleCreateContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result); + void handleDestroyContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result); }; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 1b38a9c..b7d72b7 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -135,9 +135,14 @@ void HostConnection::setSetActiveContainerCallback(const SetActiveContainerCallb mSetActiveContainerCallback = callback; } -void HostConnection::setAddContainerCallback(const AddContainerCallback& callback) +void HostConnection::setCreateContainerCallback(const CreateContainerCallback& callback) { - mAddContainerCallback = callback; + mCreateContainerCallback = callback; +} + +void HostConnection::setDestroyContainerCallback(const DestroyContainerCallback& callback) +{ + mDestroyContainerCallback = callback; } void HostConnection::onMessageCall(const std::string& objectPath, @@ -220,12 +225,21 @@ void HostConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_ADD_CONTAINER) { + if (methodName == api::host::METHOD_CREATE_CONTAINER) { + const gchar* id = NULL; + g_variant_get(parameters, "(&s)", &id); + + if (mCreateContainerCallback){ + mCreateContainerCallback(id, result); + } + } + + if (methodName == api::host::METHOD_DESTROY_CONTAINER) { const gchar* id = NULL; g_variant_get(parameters, "(&s)", &id); - if (mAddContainerCallback){ - mAddContainerCallback(id, result); + if (mDestroyContainerCallback){ + mDestroyContainerCallback(id, result); } } } diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 1dacd11..8392578 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -65,7 +65,10 @@ public: )> SetActiveContainerCallback; typedef std::function AddContainerCallback; + )> CreateContainerCallback; + typedef std::function DestroyContainerCallback; /** * Register proxy call callback @@ -105,7 +108,12 @@ public: /** * Register a callback called to create new container */ - void setAddContainerCallback(const AddContainerCallback& callback); + void setCreateContainerCallback(const CreateContainerCallback& callback); + + /** + * Register a callback called to destroy container + */ + void setDestroyContainerCallback(const DestroyContainerCallback& callback); /** * Make a proxy call @@ -129,7 +137,8 @@ private: GetActiveContainerIdCallback mGetActiveContainerIdCallback; GetContainerInfoCallback mGetContainerInfoCallback; SetActiveContainerCallback mSetActiveContainerCallback; - AddContainerCallback mAddContainerCallback; + CreateContainerCallback mCreateContainerCallback; + DestroyContainerCallback mDestroyContainerCallback; void onNameAcquired(); void onNameLost(); diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index a722aee..b7b49c4 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -37,14 +37,14 @@ const std::string OBJECT_PATH = "/org/tizen/containers/host"; const std::string INTERFACE = "org.tizen.containers.host.manager"; const std::string ERROR_CONTAINER_STOPPED = "org.tizen.containers.host.Error.ContainersStopped"; -const std::string ERROR_CONTAINER_CREATE_FAILED = "org.tizen.containers.host.Error.ContainerCreateFailed"; const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds"; const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId"; const std::string METHOD_GET_CONTAINER_INFO = "GetContainerInfo"; const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer"; -const std::string METHOD_ADD_CONTAINER = "AddContainer"; +const std::string METHOD_CREATE_CONTAINER = "CreateContainer"; +const std::string METHOD_DESTROY_CONTAINER = "DestroyContainer"; const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; @@ -77,7 +77,10 @@ const std::string DEFINITION = " " " " " " - " " + " " + " " + " " + " " " " " " " " diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index d6b3fbb..934a062 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(AddContainerTest) +BOOST_AUTO_TEST_CASE(CreateContainerTest) { const std::string newActiveContainerId = ""; diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt index 17e10a2..fc73fd4 100644 --- a/tests/unit_tests/server/configs/CMakeLists.txt +++ b/tests/unit_tests/server/configs/CMakeLists.txt @@ -24,7 +24,6 @@ FILE(GLOB server_container_CONF ut-server/containers/*.conf) FILE(GLOB manager_manager_CONF ut-containers-manager/*.conf) FILE(GLOB manager_container_CONF ut-containers-manager/containers/*.conf) -FILE(GLOB manager_admin_TEMPLATE ut-containers-manager/templates/*.conf) FILE(GLOB container_CONF ut-container/*.conf) FILE(GLOB container_container_CONF ut-container/containers/*.conf) @@ -55,6 +54,8 @@ CONFIGURE_FILE(ut-containers-manager/buggy-foreground-daemon.conf.in ${CMAKE_BINARY_DIR}/ut-containers-manager/buggy-foreground-daemon.conf @ONLY) CONFIGURE_FILE(ut-containers-manager/test-dbus-daemon.conf.in ${CMAKE_BINARY_DIR}/ut-containers-manager/test-dbus-daemon.conf @ONLY) +CONFIGURE_FILE(ut-containers-manager/empty-dbus-daemon.conf.in + ${CMAKE_BINARY_DIR}/ut-containers-manager/empty-dbus-daemon.conf @ONLY) FILE(GLOB manager_manager_CONF_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/*.conf) CONFIGURE_FILE(ut-containers-manager/containers/console1-dbus.conf.in @@ -65,6 +66,10 @@ CONFIGURE_FILE(ut-containers-manager/containers/console3-dbus.conf.in ${CMAKE_BINARY_DIR}/ut-containers-manager/containers/console3-dbus.conf @ONLY) FILE(GLOB manager_container_CONF_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/containers/*.conf) +CONFIGURE_FILE(ut-containers-manager/templates/template.conf.in + ${CMAKE_BINARY_DIR}/ut-containers-manager/templates/template.conf @ONLY) +FILE(GLOB manager_container_TEMPLATE_GEN ${CMAKE_BINARY_DIR}/ut-containers-manager/templates/*.conf) + ## Install ##################################################################### INSTALL(FILES ${server_manager_CONF} @@ -82,7 +87,7 @@ INSTALL(FILES ${manager_container_CONF} DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/containers) INSTALL(FILES ${manager_container_CONF_GEN} DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/containers) -INSTALL(FILES ${manager_admin_TEMPLATE} +INSTALL(FILES ${manager_container_TEMPLATE_GEN} DESTINATION ${SC_TEST_CONFIG_INSTALL_DIR}/server/ut-containers-manager/templates) INSTALL(FILES ${container_CONF} diff --git a/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in new file mode 100644 index 0000000..82f6c0e --- /dev/null +++ b/tests/unit_tests/server/configs/ut-containers-manager/empty-dbus-daemon.conf.in @@ -0,0 +1,22 @@ +{ + "containerConfigs" : [], + "foregroundId" : "", + "defaultId" : "", + "containersPath" : "/tmp/ut-containers", + "containerImagePath" : "", + "containerTemplatePath" : "templates", + "containerNewConfigPrefix" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/", + "runMountPointPrefix" : "", + "lxcTemplatePrefix" : "@SC_TEST_LXC_TEMPLATES_INSTALL_DIR@", + "inputConfig" : {"enabled" : false, + "device" : "/dev/doesnotexist", + "code" : 139, + "numberOfEvents" : 2, + "timeWindowMs" : 500}, + "proxyCallRules" : [{"caller" : "*", + "target" : "*", + "targetBusName" : "org.tizen.containers.tests", + "targetObjectPath" : "*", + "targetInterface" : "*", + "targetMethod" : "*"}] +} diff --git a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf deleted file mode 100644 index 1229c12..0000000 --- a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf +++ /dev/null @@ -1,11 +0,0 @@ -{ - "privilege" : 20, - "vt" : -1, - "switchToDefaultAfterTimeout" : true, - "cpuQuotaForeground" : -1, - "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-containers-manager/~NAME~-dbus", - "enableDbusIntegration" : true, - "permittedToSend" : [ "/tmp/.*" ], - "permittedToRecv" : [ "/tmp/.*" ] -} diff --git a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in new file mode 100644 index 0000000..f01cfff --- /dev/null +++ b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf.in @@ -0,0 +1,16 @@ +{ + "name" : "~NAME~", + "lxcTemplate" : "minimal-dbus1.sh", + "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-containers-manager/ut-dbus.conf --fork; read"], + "ipv4Gateway" : "", + "ipv4" : "", + "privilege" : 20, + "vt" : -1, + "switchToDefaultAfterTimeout" : true, + "enableDbusIntegration" : true, + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "runMountPoint" : "/tmp/ut-run1", + "permittedToSend" : [ "/tmp/.*" ], + "permittedToRecv" : [ "/tmp/.*" ] +} diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 399cd12..46f659f 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -62,6 +62,7 @@ namespace { const std::string TEST_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/test-daemon.conf"; const std::string TEST_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/test-dbus-daemon.conf"; +const std::string EMPTY_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/empty-dbus-daemon.conf"; const std::string BUGGY_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-daemon.conf"; const std::string BUGGY_FOREGROUND_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-foreground-daemon.conf"; const std::string BUGGY_DEFAULTID_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/server/ut-containers-manager/buggy-default-daemon.conf"; @@ -85,7 +86,7 @@ public: typedef std::function TestApiMethodCallback; - typedef std::function AddContainerResultCallback; + typedef std::function VoidResultCallback; typedef std::map Dbuses; @@ -308,8 +309,8 @@ public: } - void callAsyncMethodAddContainer(const std::string& id, - const AddContainerResultCallback& result) + void callAsyncMethodCreateContainer(const std::string& id, + const VoidResultCallback& result) { auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) { BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT)); @@ -321,7 +322,26 @@ public: mClient->callMethodAsync(api::host::BUS_NAME, api::host::OBJECT_PATH, api::host::INTERFACE, - api::host::METHOD_ADD_CONTAINER, + api::host::METHOD_CREATE_CONTAINER, + parameters, + "()", + asyncResult); + } + + void callAsyncMethodDestroyContainer(const std::string& id, + const VoidResultCallback& result) + { + auto asyncResult = [result](dbus::AsyncMethodCallResult& asyncMethodCallResult) { + BOOST_CHECK(g_variant_is_of_type(asyncMethodCallResult.get(), G_VARIANT_TYPE_UNIT)); + result(); + }; + + assert(isHost()); + GVariant* parameters = g_variant_new("(s)", id.c_str()); + mClient->callMethodAsync(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_DESTROY_CONTAINER, parameters, "()", asyncResult); @@ -938,32 +958,33 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest) DbusException); } -//TODO fix it -//BOOST_AUTO_TEST_CASE(AddContainerTest) -//{ -// const std::string newContainerId = "test1234"; -// const std::vector newContainerConfigs = { -// TEST_CONTAINER_CONF_PATH + newContainerId + ".conf", -// }; -// FileCleanerRAII cleaner(newContainerConfigs); -// -// ContainersManager cm(TEST_DBUS_CONFIG_PATH); -// cm.startAll(); -// -// Latch callDone; -// auto resultCallback = [&]() { -// callDone.set(); -// }; -// -// DbusAccessory dbus(DbusAccessory::HOST_ID); -// -// // create new container -// dbus.callAsyncMethodAddContainer(newContainerId, resultCallback); -// callDone.wait(EVENT_TIMEOUT); -// -// // focus new container -// cm.focus(newContainerId); -// BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId); -//} +BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest) +{ + const std::string newContainerId = "test1234"; + + ContainersManager cm(EMPTY_DBUS_CONFIG_PATH); + cm.startAll(); + + Latch callDone; + auto resultCallback = [&]() { + callDone.set(); + }; + + DbusAccessory dbus(DbusAccessory::HOST_ID); + + // create new container + dbus.callAsyncMethodCreateContainer(newContainerId, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + + // focus new container + cm.focus(newContainerId); + BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId); + + // destroy container + dbus.callAsyncMethodDestroyContainer(newContainerId, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + + BOOST_CHECK(cm.getRunningForegroundContainerId() == ""); +} BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 7f7ca51f217acca99c35d06c6144ca6ace55e9c2 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Thu, 27 Nov 2014 14:02:11 +0100 Subject: [PATCH 09/16] IPC: Signals [Bug/Feature] Signals in the IPC mechanism [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ie84b88ffa2956e744216d9ff7e9c227631f78e50 --- common/ipc/client.cpp | 15 ++ common/ipc/client.hpp | 67 +++++++- common/ipc/internals/processor.cpp | 185 +++++++++++++++++---- common/ipc/internals/processor.hpp | 318 ++++++++++++++++++++++++++++++------- common/ipc/service.cpp | 15 ++ common/ipc/service.hpp | 65 +++++++- common/ipc/types.hpp | 11 +- tests/unit_tests/ipc/ut-ipc.cpp | 197 ++++++++++++++--------- 8 files changed, 707 insertions(+), 166 deletions(-) diff --git a/common/ipc/client.cpp b/common/ipc/client.cpp index c1651f3..c806e7b 100644 --- a/common/ipc/client.cpp +++ b/common/ipc/client.cpp @@ -63,6 +63,11 @@ void Client::start() LOGD("Started client"); } +bool Client::isStarted() +{ + return mProcessor.isStarted(); +} + void Client::stop() { LOGD("Stopping client..."); @@ -70,6 +75,16 @@ void Client::stop() LOGD("Stopped"); } +void Client::setNewPeerCallback(const PeerCallback& newPeerCallback) +{ + mProcessor.setNewPeerCallback(newPeerCallback); +} + +void Client::setRemovedPeerCallback(const PeerCallback& removedPeerCallback) +{ + mProcessor.setRemovedPeerCallback(removedPeerCallback); +} + void Client::removeMethod(const MethodID methodID) { LOGD("Removing method id: " << methodID); diff --git a/common/ipc/client.hpp b/common/ipc/client.hpp index 7429b24..3178474 100644 --- a/common/ipc/client.hpp +++ b/common/ipc/client.hpp @@ -45,8 +45,6 @@ namespace ipc { */ class Client { public: - typedef Processor::MethodID MethodID; - /** * @param serverPath path to the server's socket */ @@ -62,11 +60,30 @@ public: void start(); /** + * @return is the communication thread running + */ + bool isStarted(); + + /** * Stops all worker thread */ void stop(); /** + * Set the callback called for each new connection to a peer + * + * @param newPeerCallback the callback + */ + void setNewPeerCallback(const PeerCallback& newPeerCallback); + + /** + * Set the callback called when connection to a peer is lost + * + * @param removedPeerCallback the callback + */ + void setRemovedPeerCallback(const PeerCallback& removedPeerCallback); + + /** * Saves the callback connected to the method id. * When a message with the given method id is received * the data will be parsed and passed to this callback. @@ -79,6 +96,19 @@ public: const typename MethodHandler::type& method); /** + * Saves the callback connected to the method id. + * When a message with the given method id is received + * the data will be parsed and passed to this callback. + * + * @param methodID API dependent id of the method + * @param SignalHandler signal handling implementation + * @tparam ReceivedDataType data type to serialize + */ + template + void addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& signal); + + /** * Removes the callback * * @param methodID API dependent id of the method @@ -112,8 +142,21 @@ public: const std::shared_ptr& data, const typename ResultHandler::type& resultCallback); + /** + * Send a signal to the peer. + * There is no return value from the peer + * Sends any data only if a peer registered this a signal + * + * @param methodID API dependent id of the method + * @param data data to sent + * @tparam SentDataType data type to send + */ + template + void signal(const MethodID methodID, + const std::shared_ptr& data); + private: - Processor::PeerID mServiceID; + PeerID mServiceID; Processor mProcessor; std::string mSocketPath; }; @@ -127,6 +170,15 @@ void Client::addMethodHandler(const MethodID methodID, LOGD("Added method with id " << methodID); } +template +void Client::addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& handler) +{ + LOGD("Adding signal with id " << methodID); + mProcessor.addSignalHandler(methodID, handler); + LOGD("Added signal with id " << methodID); +} + template std::shared_ptr Client::callSync(const MethodID methodID, const std::shared_ptr& data, @@ -150,6 +202,15 @@ void Client::callAsync(const MethodID methodID, LOGD("Async called method: " << methodID); } +template +void Client::signal(const MethodID methodID, + const std::shared_ptr& data) +{ + LOGD("Signaling: " << methodID); + mProcessor.signal(methodID, data); + LOGD("Signaled: " << methodID); +} + } // namespace ipc } // namespace security_containers diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp index 9aadfff..dc7df42 100644 --- a/common/ipc/internals/processor.cpp +++ b/common/ipc/internals/processor.cpp @@ -28,7 +28,6 @@ #include "ipc/internals/processor.hpp" #include "ipc/internals/utils.hpp" -#include #include #include #include @@ -48,7 +47,8 @@ namespace ipc { LOGE("Callback threw an error: " << e.what()); \ } -const Processor::MethodID Processor::RETURN_METHOD_ID = std::numeric_limits::max(); +const MethodID Processor::RETURN_METHOD_ID = std::numeric_limits::max(); +const MethodID Processor::REGISTER_SIGNAL_METHOD_ID = std::numeric_limits::max() - 1; Processor::Processor(const PeerCallback& newPeerCallback, const PeerCallback& removedPeerCallback, @@ -60,6 +60,11 @@ Processor::Processor(const PeerCallback& newPeerCallback, mPeerIDCounter(0) { LOGT("Creating Processor"); + using namespace std::placeholders; + + addMethodHandlerInternal(REGISTER_SIGNAL_METHOD_ID, + std::bind(&Processor::onNewSignals, this, _1, _2)); + } Processor::~Processor() @@ -73,10 +78,15 @@ Processor::~Processor() LOGT("Destroyed Processor"); } +bool Processor::isStarted() +{ + return mThread.joinable(); +} + void Processor::start() { LOGT("Starting Processor"); - if (!mThread.joinable()) { + if (!isStarted()) { mThread = std::thread(&Processor::run, this); } LOGT("Started Processor"); @@ -85,13 +95,25 @@ void Processor::start() void Processor::stop() { LOGT("Stopping Processor"); - if (mThread.joinable()) { + if (isStarted()) { mEventQueue.send(Event::FINISH); mThread.join(); } LOGT("Stopped Processor"); } +void Processor::setNewPeerCallback(const PeerCallback& newPeerCallback) +{ + Lock lock(mCallbacksMutex); + mNewPeerCallback = newPeerCallback; +} + +void Processor::setRemovedPeerCallback(const PeerCallback& removedPeerCallback) +{ + Lock lock(mCallbacksMutex); + mRemovedPeerCallback = removedPeerCallback; +} + void Processor::removeMethod(const MethodID methodID) { LOGT("Removing method " << methodID); @@ -99,7 +121,7 @@ void Processor::removeMethod(const MethodID methodID) mMethodsCallbacks.erase(methodID); } -Processor::PeerID Processor::addPeer(const std::shared_ptr& socketPtr) +PeerID Processor::addPeer(const std::shared_ptr& socketPtr) { LOGT("Adding socket"); PeerID peerID; @@ -127,7 +149,7 @@ void Processor::removePeer(const PeerID peerID) mEventQueue.send(Event::REMOVE_PEER); - auto isPeerDeleted = [&peerID, this] { + auto isPeerDeleted = [&peerID, this]()->bool { Lock lock(mSocketsMutex); return mSockets.count(peerID) == 0; }; @@ -143,6 +165,16 @@ void Processor::removePeerInternal(const PeerID peerID, Status status) { Lock lock(mSocketsMutex); mSockets.erase(peerID); + + // Remove from signal addressees + for (auto it = mSignalsPeers.begin(); it != mSignalsPeers.end();) { + it->second.remove(peerID); + if (it->second.empty()) { + it = mSignalsPeers.erase(it); + } else { + ++it; + } + } } { @@ -160,9 +192,13 @@ void Processor::removePeerInternal(const PeerID peerID, Status status) } } - if (mRemovedPeerCallback) { - // Notify about the deletion - mRemovedPeerCallback(peerID); + + { + Lock lock(mCallbacksMutex); + if (mRemovedPeerCallback) { + // Notify about the deletion + mRemovedPeerCallback(peerID); + } } resetPolling(); @@ -284,14 +320,46 @@ bool Processor::handleInput(const PeerID peerID, const Socket& socket) if (methodID == RETURN_METHOD_ID) { return onReturnValue(peerID, socket, messageID); + } else { - return onRemoteCall(peerID, socket, methodID, messageID); + Lock lock(mCallsMutex); + if (mMethodsCallbacks.count(methodID)) { + // Method + std::shared_ptr methodCallbacks = mMethodsCallbacks.at(methodID); + mCallsMutex.unlock(); + return onRemoteCall(peerID, socket, methodID, messageID, methodCallbacks); + + } else if (mSignalsCallbacks.count(methodID)) { + // Signal + std::shared_ptr signalCallbacks = mSignalsCallbacks.at(methodID); + mCallsMutex.unlock(); + return onRemoteSignal(peerID, socket, methodID, messageID, signalCallbacks); + + } else { + // Nothing + mCallsMutex.unlock(); + LOGW("No method or signal callback for methodID: " << methodID); + removePeerInternal(peerID, Status::NAUGHTY_PEER); + return true; + } } } return false; } +std::shared_ptr Processor::onNewSignals(const PeerID peerID, + std::shared_ptr& data) +{ + LOGD("New signals for peer: " << peerID); + Lock lock(mSocketsMutex); + for (MethodID methodID : data->ids) { + mSignalsPeers[methodID].push_back(peerID); + } + + return std::make_shared(); +} + bool Processor::onReturnValue(const PeerID peerID, const Socket& socket, const MessageID messageID) @@ -326,23 +394,44 @@ bool Processor::onReturnValue(const PeerID peerID, return false; } -bool Processor::onRemoteCall(const PeerID peerID, - const Socket& socket, - const MethodID methodID, - const MessageID messageID) +bool Processor::onRemoteSignal(const PeerID peerID, + const Socket& socket, + const MethodID methodID, + const MessageID messageID, + std::shared_ptr signalCallbacks) { - LOGI("Remote call; methodID: " << methodID << " messageID: " << messageID); + LOGI("Remote signal; methodID: " << methodID << " messageID: " << messageID); - std::shared_ptr methodCallbacks; + std::shared_ptr data; try { - Lock lock(mCallsMutex); - methodCallbacks = mMethodsCallbacks.at(methodID); - } catch (const std::out_of_range&) { - LOGW("No method callback for methodID: " << methodID); + LOGT("Parsing incoming data"); + data = signalCallbacks->parse(socket.getFD()); + } catch (const std::exception& e) { + LOGE("Exception during parsing: " << e.what()); + removePeerInternal(peerID, Status::PARSING_ERROR); + return true; + } + + LOGT("Signal callback for methodID: " << methodID << "; messageID: " << messageID); + try { + signalCallbacks->signal(peerID, data); + } catch (const std::exception& e) { + LOGE("Exception in method handler: " << e.what()); removePeerInternal(peerID, Status::NAUGHTY_PEER); return true; } + return false; +} + +bool Processor::onRemoteCall(const PeerID peerID, + const Socket& socket, + const MethodID methodID, + const MessageID messageID, + std::shared_ptr methodCallbacks) +{ + LOGI("Remote call; methodID: " << methodID << " messageID: " << messageID); + std::shared_ptr data; try { LOGT("Parsing incoming data"); @@ -356,7 +445,7 @@ bool Processor::onRemoteCall(const PeerID peerID, LOGT("Process callback for methodID: " << methodID << "; messageID: " << messageID); std::shared_ptr returnData; try { - returnData = methodCallbacks->method(data); + returnData = methodCallbacks->method(peerID, data); } catch (const std::exception& e) { LOGE("Exception in method handler: " << e.what()); removePeerInternal(peerID, Status::NAUGHTY_PEER); @@ -434,10 +523,44 @@ bool Processor::onNewPeer() mSockets[socketInfo.peerID] = std::move(socketInfo.socketPtr); } + + + // Broadcast the new signal to peers + LOGW("Sending handled signals"); + std::list peersIDs; + { + Lock lock(mSocketsMutex); + for (const auto kv : mSockets) { + peersIDs.push_back(kv.first); + } + } + + std::vector ids; + { + Lock lock(mSocketsMutex); + for (const auto kv : mSignalsCallbacks) { + ids.push_back(kv.first); + } + } + auto data = std::make_shared(ids); + + for (const PeerID peerID : peersIDs) { + callInternal(REGISTER_SIGNAL_METHOD_ID, + peerID, + data, + discardResultHandler); + } + LOGW("Sent handled signals"); + + resetPolling(); - if (mNewPeerCallback) { - // Notify about the new user. - mNewPeerCallback(socketInfo.peerID); + + { + Lock lock(mCallbacksMutex); + if (mNewPeerCallback) { + // Notify about the new user. + mNewPeerCallback(socketInfo.peerID); + } } return true; } @@ -456,13 +579,13 @@ bool Processor::onRemovePeer() return true; } -Processor::MessageID Processor::getNextMessageID() +MessageID Processor::getNextMessageID() { // TODO: This method of generating UIDs is buggy. To be changed. return ++mMessageIDCounter; } -Processor::PeerID Processor::getNextPeerID() +PeerID Processor::getNextPeerID() { // TODO: This method of generating UIDs is buggy. To be changed. return ++mPeerIDCounter; @@ -496,14 +619,12 @@ bool Processor::onCall() return false; } - { - // Set what to do with the return message + if (call.parse && call.process) { + // Set what to do with the return message, but only if needed Lock lock(mReturnCallbacksMutex); if (mReturnCallbacks.count(call.messageID) != 0) { LOGE("There already was a return callback for messageID: " << call.messageID); } - - // move insertion mReturnCallbacks[call.messageID] = std::move(ReturnCallbacks(call.peerID, std::move(call.parse), std::move(call.process))); @@ -544,7 +665,9 @@ void Processor::cleanCommunication() case Event::CALL: { LOGD("Event CALL after FINISH"); Call call = getCall(); - IGNORE_EXCEPTIONS(call.process(Status::CLOSING, call.data)); + if (call.process) { + IGNORE_EXCEPTIONS(call.process(Status::CLOSING, call.data)); + } break; } diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index 7554eb8..e43fe62 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -31,6 +31,7 @@ #include "ipc/types.hpp" #include "config/manager.hpp" #include "config/is-visitable.hpp" +#include "config/fields.hpp" #include "logger/logger.hpp" #include @@ -43,14 +44,16 @@ #include #include #include +#include #include #include namespace security_containers { namespace ipc { -namespace { + const unsigned int DEFAULT_MAX_NUMBER_OF_PEERS = 500; -} +const unsigned int DEFAULT_METHOD_TIMEOUT = 1000; + /** * This class wraps communication via UX sockets * @@ -66,18 +69,25 @@ const unsigned int DEFAULT_MAX_NUMBER_OF_PEERS = 500; * * TODO: * - some mutexes may not be needed +* - synchronous call to many peers +* - implement CallQueue class +* - implement HandlerStore class for storing both signals and methods +* - API for removing signals +* - implement CallbackStore - thread safe calling/setting callbacks +* - helper function for removing from unordered map */ class Processor { public: - typedef std::function PeerCallback; - typedef unsigned int PeerID; - typedef unsigned int MethodID; - typedef unsigned int MessageID; - /** - * Method ID. Used to indicate a message with the return value. + * Used to indicate a message with the return value. */ static const MethodID RETURN_METHOD_ID; + + /** + * Indicates an Processor's internal request/broadcast to register a Signal + */ + static const MethodID REGISTER_SIGNAL_METHOD_ID; + /** * Constructs the Processor, but doesn't start it. * The object is ready to add methods. @@ -101,12 +111,31 @@ public: void start(); /** + * @return is processor running + */ + bool isStarted(); + + /** * Stops the processing thread. * No incoming data will be handled after. */ void stop(); /** + * Set the callback called for each new connection to a peer + * + * @param newPeerCallback the callback + */ + void setNewPeerCallback(const PeerCallback& newPeerCallback); + + /** + * Set the callback called when connection to a peer is lost + * + * @param removedPeerCallback the callback + */ + void setRemovedPeerCallback(const PeerCallback& removedPeerCallback); + + /** * From now on socket is owned by the Processor object. * Calls the newPeerCallback. * @@ -139,6 +168,24 @@ public: const typename MethodHandler::type& process); /** + * Saves the callbacks connected to the method id. + * When a message with the given method id is received, + * the data will be passed to the serialization callback through file descriptor. + * + * Then the process callback will be called with the parsed data. + * There is no return data to send back. + * + * Adding signal sends a registering message to all peers + * + * @param methodID API dependent id of the method + * @param process data processing callback + * @tparam ReceivedDataType data type to receive + */ + template + void addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& process); + + /** * Removes the callback * * @param methodID API dependent id of the method @@ -178,11 +225,42 @@ public: const typename ResultHandler::type& process); + /** + * Send a signal to the peer. + * There is no return value from the peer + * Sends any data only if a peer registered this a signal + * + * @param methodID API dependent id of the method + * @param data data to sent + * @tparam SentDataType data type to send + */ + template + void signal(const MethodID methodID, + const std::shared_ptr& data); + + private: typedef std::function& data)> SerializeCallback; typedef std::function(int fd)> ParseCallback; typedef std::lock_guard Lock; + struct EmptyData { + CONFIG_REGISTER_EMPTY + }; + + struct RegisterSignalsMessage { + RegisterSignalsMessage() = default; + RegisterSignalsMessage(const std::vector ids) + : ids(ids) {} + + std::vector ids; + + CONFIG_REGISTER + ( + ids + ) + }; + struct Call { Call(const Call& other) = delete; Call& operator=(const Call&) = delete; @@ -210,6 +288,17 @@ private: MethodHandler::type method; }; + struct SignalHandlers { + SignalHandlers(const SignalHandlers& other) = delete; + SignalHandlers& operator=(const SignalHandlers&) = delete; + SignalHandlers() = default; + SignalHandlers(SignalHandlers&&) = default; + SignalHandlers& operator=(SignalHandlers &&) = default; + + ParseCallback parse; + SignalHandler::type signal; + }; + struct ReturnCallbacks { ReturnCallbacks(const ReturnCallbacks& other) = delete; ReturnCallbacks& operator=(const ReturnCallbacks&) = delete; @@ -269,6 +358,8 @@ private: std::mutex mCallsMutex; std::queue mCalls; std::unordered_map> mMethodsCallbacks; + std::unordered_map> mSignalsCallbacks; + std::unordered_map> mSignalsPeers; // Mutex for changing mSockets map. // Shouldn't be locked on any read/write, that could block. Just copy the ptr. @@ -281,7 +372,8 @@ private: std::mutex mReturnCallbacksMutex; std::unordered_map mReturnCallbacks; - + // Mutex for setting callbacks + std::mutex mCallbacksMutex; PeerCallback mNewPeerCallback; PeerCallback mRemovedPeerCallback; @@ -293,6 +385,24 @@ private: std::atomic mMessageIDCounter; std::atomic mPeerIDCounter; + template + void addMethodHandlerInternal(const MethodID methodID, + const typename MethodHandler::type& process); + + template + MessageID callInternal(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data); + + template + MessageID callInternal(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process); + + template + static void discardResultHandler(Status, std::shared_ptr&) {} + void run(); bool handleEvent(); bool onCall(); @@ -307,31 +417,30 @@ private: bool onRemoteCall(const PeerID peerID, const Socket& socket, const MethodID methodID, - const MessageID messageID); + const MessageID messageID, + std::shared_ptr methodCallbacks); + bool onRemoteSignal(const PeerID peerID, + const Socket& socket, + const MethodID methodID, + const MessageID messageID, + std::shared_ptr signalCallbacks); void resetPolling(); MessageID getNextMessageID(); PeerID getNextPeerID(); Call getCall(); void removePeerInternal(const PeerID peerID, Status status); + + std::shared_ptr onNewSignals(const PeerID peerID, + std::shared_ptr& data); + + void cleanCommunication(); }; template -void Processor::addMethodHandler(const MethodID methodID, - const typename MethodHandler::type& method) +void Processor::addMethodHandlerInternal(const MethodID methodID, + const typename MethodHandler::type& method) { - static_assert(config::isVisitable::value, - "Use the libConfig library"); - static_assert(config::isVisitable::value, - "Use the libConfig library"); - - if (methodID == RETURN_METHOD_ID) { - LOGE("Forbidden methodID: " << methodID); - throw IPCException("Forbidden methodID: " + std::to_string(methodID)); - } - - using namespace std::placeholders; - MethodHandlers methodCall; methodCall.parse = [](const int fd)->std::shared_ptr { @@ -344,9 +453,9 @@ void Processor::addMethodHandler(const MethodID methodID, config::saveToFD(fd, *std::static_pointer_cast(data)); }; - methodCall.method = [method](std::shared_ptr& data)->std::shared_ptr { + methodCall.method = [method](const PeerID peerID, std::shared_ptr& data)->std::shared_ptr { std::shared_ptr tmpData = std::static_pointer_cast(data); - return method(tmpData); + return method(peerID, tmpData); }; { @@ -356,39 +465,104 @@ void Processor::addMethodHandler(const MethodID methodID, } template -Processor::MessageID Processor::callAsync(const MethodID methodID, - const PeerID peerID, - const std::shared_ptr& data, - const typename ResultHandler::type& process) +void Processor::addMethodHandler(const MethodID methodID, + const typename MethodHandler::type& method) { - static_assert(config::isVisitable::value, - "Use the libConfig library"); - static_assert(config::isVisitable::value, - "Use the libConfig library"); + if (methodID == RETURN_METHOD_ID || methodID == REGISTER_SIGNAL_METHOD_ID) { + LOGE("Forbidden methodID: " << methodID); + throw IPCException("Forbidden methodID: " + std::to_string(methodID)); + } - if (!mThread.joinable()) { - LOGE("The Processor thread is not started. Can't send any data."); - throw IPCException("The Processor thread is not started. Can't send any data."); + { + Lock lock(mCallsMutex); + if (mSignalsCallbacks.count(methodID)) { + LOGE("MethodID used by a signal: " << methodID); + throw IPCException("MethodID used by a signal: " + std::to_string(methodID)); + } } - using namespace std::placeholders; + addMethodHandlerInternal(methodID, method); +} + +template +void Processor::addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& handler) +{ + if (methodID == RETURN_METHOD_ID || methodID == REGISTER_SIGNAL_METHOD_ID) { + LOGE("Forbidden methodID: " << methodID); + throw IPCException("Forbidden methodID: " + std::to_string(methodID)); + } + { + Lock lock(mCallsMutex); + if (mMethodsCallbacks.count(methodID)) { + LOGE("MethodID used by a method: " << methodID); + throw IPCException("MethodID used by a method: " + std::to_string(methodID)); + } + } + + SignalHandlers signalCall; + + signalCall.parse = [](const int fd)->std::shared_ptr { + std::shared_ptr data(new ReceivedDataType()); + config::loadFromFD(fd, *data); + return data; + }; + + signalCall.signal = [handler](const PeerID peerID, std::shared_ptr& data) { + std::shared_ptr tmpData = std::static_pointer_cast(data); + handler(peerID, tmpData); + }; + + { + Lock lock(mCallsMutex); + mSignalsCallbacks[methodID] = std::make_shared(std::move(signalCall)); + } + + if (isStarted()) { + // Broadcast the new signal to peers + std::vector ids {methodID}; + auto data = std::make_shared(ids); + + std::list peersIDs; + { + Lock lock(mSocketsMutex); + for (const auto kv : mSockets) { + peersIDs.push_back(kv.first); + } + } + + for (const PeerID peerID : peersIDs) { + callSync(REGISTER_SIGNAL_METHOD_ID, + peerID, + data, + DEFAULT_METHOD_TIMEOUT); + } + } +} + +template +MessageID Processor::callInternal(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process) +{ Call call; call.peerID = peerID; call.methodID = methodID; call.data = data; call.messageID = getNextMessageID(); + call.serialize = [](const int fd, std::shared_ptr& data)->void { + config::saveToFD(fd, *std::static_pointer_cast(data)); + }; + call.parse = [](const int fd)->std::shared_ptr { std::shared_ptr data(new ReceivedDataType()); config::loadFromFD(fd, *data); return data; }; - call.serialize = [](const int fd, std::shared_ptr& data)->void { - config::saveToFD(fd, *std::static_pointer_cast(data)); - }; - call.process = [process](Status status, std::shared_ptr& data)->void { std::shared_ptr tmpData = std::static_pointer_cast(data); return process(status, tmpData); @@ -397,13 +571,26 @@ Processor::MessageID Processor::callAsync(const MethodID methodID, { Lock lock(mCallsMutex); mCalls.push(std::move(call)); + mEventQueue.send(Event::CALL); } - mEventQueue.send(Event::CALL); - return call.messageID; } +template +MessageID Processor::callAsync(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process) +{ + if (!isStarted()) { + LOGE("The Processor thread is not started. Can't send any data."); + throw IPCException("The Processor thread is not started. Can't send any data."); + } + + return callInternal(methodID, peerID, data, process); +} + template std::shared_ptr Processor::callSync(const MethodID methodID, @@ -411,16 +598,6 @@ std::shared_ptr Processor::callSync(const MethodID methodID, const std::shared_ptr& data, unsigned int timeoutMS) { - static_assert(config::isVisitable::value, - "Use the libConfig library"); - static_assert(config::isVisitable::value, - "Use the libConfig library"); - - if (!mThread.joinable()) { - LOGE("The Processor thread is not started. Can't send any data."); - throw IPCException("The Processor thread is not started. Can't send any data."); - } - std::shared_ptr result; std::mutex mutex; @@ -467,6 +644,39 @@ std::shared_ptr Processor::callSync(const MethodID methodID, return result; } +template +void Processor::signal(const MethodID methodID, + const std::shared_ptr& data) +{ + if (!isStarted()) { + LOGE("The Processor thread is not started. Can't send any data."); + throw IPCException("The Processor thread is not started. Can't send any data."); + } + + std::list peersIDs; + { + Lock lock(mSocketsMutex); + peersIDs = mSignalsPeers[methodID]; + } + + for (const PeerID peerID : peersIDs) { + Call call; + call.peerID = peerID; + call.methodID = methodID; + call.data = data; + call.messageID = getNextMessageID(); + + call.serialize = [](const int fd, std::shared_ptr& data)->void { + config::saveToFD(fd, *std::static_pointer_cast(data)); + }; + + { + Lock lock(mCallsMutex); + mCalls.push(std::move(call)); + mEventQueue.send(Event::CALL); + } + } +} } // namespace ipc } // namespace security_containers diff --git a/common/ipc/service.cpp b/common/ipc/service.cpp index d2590d6..e845fe6 100644 --- a/common/ipc/service.cpp +++ b/common/ipc/service.cpp @@ -66,6 +66,11 @@ void Service::start() LOGD("Started server"); } +bool Service::isStarted() +{ + return mProcessor.isStarted(); +} + void Service::stop() { LOGD("Stopping server.."); @@ -74,6 +79,16 @@ void Service::stop() LOGD("Stopped"); } +void Service::setNewPeerCallback(const PeerCallback& newPeerCallback) +{ + mProcessor.setNewPeerCallback(newPeerCallback); +} + +void Service::setRemovedPeerCallback(const PeerCallback& removedPeerCallback) +{ + mProcessor.setRemovedPeerCallback(removedPeerCallback); +} + void Service::removeMethod(const MethodID methodID) { LOGD("Removing method " << methodID); diff --git a/common/ipc/service.hpp b/common/ipc/service.hpp index 873673d..ac22eb2 100644 --- a/common/ipc/service.hpp +++ b/common/ipc/service.hpp @@ -48,10 +48,6 @@ namespace ipc { */ class Service { public: - typedef Processor::PeerCallback PeerCallback; - typedef Processor::PeerID PeerID; - typedef Processor::MethodID MethodID; - /** * @param path path to the socket */ @@ -69,11 +65,30 @@ public: void start(); /** + * @return is the communication thread running + */ + bool isStarted(); + + /** * Stops all working threads */ void stop(); /** + * Set the callback called for each new connection to a peer + * + * @param newPeerCallback the callback + */ + void setNewPeerCallback(const PeerCallback& newPeerCallback); + + /** + * Set the callback called when connection to a peer is lost + * + * @param removedPeerCallback the callback + */ + void setRemovedPeerCallback(const PeerCallback& removedPeerCallback); + + /** * Saves the callback connected to the method id. * When a message with the given method id is received * the data will be parsed and passed to this callback. @@ -86,6 +101,19 @@ public: const typename MethodHandler::type& method); /** + * Saves the callback connected to the method id. + * When a message with the given method id is received + * the data will be parsed and passed to this callback. + * + * @param methodID API dependent id of the method + * @param handler handling implementation + * @tparam ReceivedDataType data type to serialize + */ + template + void addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& handler); + + /** * Removes the callback * * @param methodID API dependent id of the method @@ -120,6 +148,18 @@ public: const std::shared_ptr& data, const typename ResultHandler::type& resultCallback); + /** + * Send a signal to the peer. + * There is no return value from the peer + * Sends any data only if a peer registered this a signal + * + * @param methodID API dependent id of the method + * @param data data to sent + * @tparam SentDataType data type to send + */ + template + void signal(const MethodID methodID, + const std::shared_ptr& data); private: typedef std::lock_guard Lock; Processor mProcessor; @@ -136,6 +176,15 @@ void Service::addMethodHandler(const MethodID methodID, LOGD("Added method with id " << methodID); } +template +void Service::addSignalHandler(const MethodID methodID, + const typename SignalHandler::type& handler) +{ + LOGD("Adding signal with id " << methodID); + mProcessor.addSignalHandler(methodID, handler); + LOGD("Added signal with id " << methodID); +} + template std::shared_ptr Service::callSync(const MethodID methodID, const PeerID peerID, @@ -161,6 +210,14 @@ void Service::callAsync(const MethodID methodID, LOGD("Async called method: " << methodID << "for user: " << peerID); } +template +void Service::signal(const MethodID methodID, + const std::shared_ptr& data) +{ + LOGD("Signaling: " << methodID); + mProcessor.signal(methodID, data); + LOGD("Signaled: " << methodID); +} } // namespace ipc } // namespace security_containers diff --git a/common/ipc/types.hpp b/common/ipc/types.hpp index 1bfaa4e..6588fb0 100644 --- a/common/ipc/types.hpp +++ b/common/ipc/types.hpp @@ -34,6 +34,11 @@ namespace security_containers { namespace ipc { +typedef std::function PeerCallback; +typedef unsigned int PeerID; +typedef unsigned int MethodID; +typedef unsigned int MessageID; + enum class Status : int { OK = 0, PARSING_ERROR, @@ -50,9 +55,13 @@ void throwOnError(const Status status); template struct MethodHandler { - typedef std::function(std::shared_ptr&)> type; + typedef std::function(PeerID, std::shared_ptr&)> type; }; +template +struct SignalHandler { + typedef std::function&)> type; +}; template struct ResultHandler { diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index 5d284bd..88696fe 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -25,6 +25,7 @@ // TODO: Test connection limit // TODO: Refactor tests - function for setting up env +// TODO: Callback wrapper that waits till the callback is called #include "config.hpp" @@ -37,6 +38,7 @@ #include "config/fields.hpp" #include "logger/logger.hpp" +#include #include #include #include @@ -111,35 +113,64 @@ struct ThrowOnAcceptData { } }; -std::shared_ptr returnEmptyCallback(std::shared_ptr&) +std::shared_ptr returnEmptyCallback(const PeerID, std::shared_ptr&) { return std::shared_ptr(new EmptyData()); } -std::shared_ptr returnDataCallback(std::shared_ptr&) +std::shared_ptr returnDataCallback(const PeerID, std::shared_ptr&) { return std::shared_ptr(new SendData(1)); } -std::shared_ptr echoCallback(std::shared_ptr& data) +std::shared_ptr echoCallback(const PeerID, std::shared_ptr& data) { return data; } -std::shared_ptr longEchoCallback(std::shared_ptr& data) +std::shared_ptr longEchoCallback(const PeerID, std::shared_ptr& data) { std::this_thread::sleep_for(std::chrono::seconds(1)); return data; } -void testEcho(Client& c, const Client::MethodID methodID) +PeerID connect(Service& s, Client& c) +{ + // Connects the Client to the Service and returns Clients PeerID + + std::mutex mutex; + std::unique_lock lock(mutex); + std::condition_variable cv; + + unsigned int peerID = 0; + auto newPeerCallback = [&cv, &peerID](unsigned int newPeerID) { + peerID = newPeerID; + cv.notify_one(); + }; + + s.setNewPeerCallback(newPeerCallback); + + if (!s.isStarted()) { + s.start(); + } + + c.start(); + + BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&peerID]() { + return peerID != 0; + })); + + return peerID; +} + +void testEcho(Client& c, const MethodID methodID) { std::shared_ptr sentData(new SendData(34)); std::shared_ptr recvData = c.callSync(methodID, sentData); BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } -void testEcho(Service& s, const Client::MethodID methodID, const Service::PeerID peerID) +void testEcho(Service& s, const MethodID methodID, const PeerID peerID) { std::shared_ptr sentData(new SendData(56)); std::shared_ptr recvData = s.callSync(methodID, peerID, sentData); @@ -151,13 +182,13 @@ void testEcho(Service& s, const Client::MethodID methodID, const Service::PeerID BOOST_FIXTURE_TEST_SUITE(IPCSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { Service s(socketPath); Client c(socketPath); } -BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethodTest) +BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethod) { Service s(socketPath); @@ -179,32 +210,18 @@ BOOST_AUTO_TEST_CASE(ServiceAddRemoveMethodTest) BOOST_CHECK_THROW(testEcho(c, 2), IPCException); } -BOOST_AUTO_TEST_CASE(ClientAddRemoveMethodTest) +BOOST_AUTO_TEST_CASE(ClientAddRemoveMethod) { - std::mutex mtx; - std::unique_lock lck(mtx); - std::condition_variable cv; - unsigned int peerID = 0; - auto newPeerCallback = [&cv, &peerID](unsigned int newPeerID) { - peerID = newPeerID; - cv.notify_one(); - }; - Service s(socketPath, newPeerCallback); - s.start(); + Service s(socketPath); Client c(socketPath); - c.addMethodHandler(1, returnEmptyCallback); c.addMethodHandler(1, returnDataCallback); - c.start(); + PeerID peerID = connect(s, c); c.addMethodHandler(1, echoCallback); c.addMethodHandler(2, returnDataCallback); - BOOST_CHECK(cv.wait_for(lck, std::chrono::milliseconds(1000), [&peerID]() { - return peerID != 0; - })); - testEcho(s, 1, peerID); c.removeMethod(1); @@ -213,7 +230,7 @@ BOOST_AUTO_TEST_CASE(ClientAddRemoveMethodTest) BOOST_CHECK_THROW(testEcho(s, 1, peerID), IPCException); } -BOOST_AUTO_TEST_CASE(ServiceStartStopTest) +BOOST_AUTO_TEST_CASE(ServiceStartStop) { Service s(socketPath); @@ -228,7 +245,7 @@ BOOST_AUTO_TEST_CASE(ServiceStartStopTest) s.start(); } -BOOST_AUTO_TEST_CASE(ClientStartStopTest) +BOOST_AUTO_TEST_CASE(ClientStartStop) { Service s(socketPath); Client c(socketPath); @@ -246,7 +263,7 @@ BOOST_AUTO_TEST_CASE(ClientStartStopTest) c.stop(); } -BOOST_AUTO_TEST_CASE(SyncClientToServiceEchoTest) +BOOST_AUTO_TEST_CASE(SyncClientToServiceEcho) { Service s(socketPath); s.addMethodHandler(1, echoCallback); @@ -259,7 +276,7 @@ BOOST_AUTO_TEST_CASE(SyncClientToServiceEchoTest) testEcho(c, 2); } -BOOST_AUTO_TEST_CASE(RestartTest) +BOOST_AUTO_TEST_CASE(Restart) { Service s(socketPath); s.addMethodHandler(1, echoCallback); @@ -284,32 +301,19 @@ BOOST_AUTO_TEST_CASE(RestartTest) testEcho(c, 2); } -BOOST_AUTO_TEST_CASE(SyncServiceToClientEchoTest) +BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho) { - std::mutex mtx; - std::unique_lock lck(mtx); - std::condition_variable cv; - unsigned int peerID = 0; - auto newPeerCallback = [&cv, &peerID](unsigned int newPeerID) { - peerID = newPeerID; - cv.notify_one(); - }; - Service s(socketPath, newPeerCallback); - s.start(); + Service s(socketPath); Client c(socketPath); c.addMethodHandler(1, echoCallback); - c.start(); - - BOOST_CHECK(cv.wait_for(lck, std::chrono::milliseconds(1000), [&peerID]() { - return peerID != 0; - })); + PeerID peerID = connect(s, c); std::shared_ptr sentData(new SendData(56)); std::shared_ptr recvData = s.callSync(1, peerID, sentData); BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } -BOOST_AUTO_TEST_CASE(AsyncClientToServiceEchoTest) +BOOST_AUTO_TEST_CASE(AsyncClientToServiceEcho) { // Setup Service and Client Service s(socketPath); @@ -340,33 +344,20 @@ BOOST_AUTO_TEST_CASE(AsyncClientToServiceEchoTest) BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } -BOOST_AUTO_TEST_CASE(AsyncServiceToClientEchoTest) +BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho) { - std::mutex mtx; - std::unique_lock lck(mtx); - std::condition_variable cv; - - // Setup Service and Client - unsigned int peerID = 0; - auto newPeerCallback = [&cv, &peerID](unsigned int newPeerID) { - peerID = newPeerID; - cv.notify_one(); - }; - Service s(socketPath, newPeerCallback); - s.start(); + Service s(socketPath); Client c(socketPath); c.addMethodHandler(1, echoCallback); - c.start(); - - // Wait for the connection - BOOST_CHECK(cv.wait_for(lck, std::chrono::milliseconds(1000), [&peerID]() { - return peerID != 0; - })); + PeerID peerID = connect(s, c); // Async call std::shared_ptr sentData(new SendData(56)); std::shared_ptr recvData; + std::mutex mtx; + std::unique_lock lck(mtx); + std::condition_variable cv; auto dataBack = [&cv, &recvData](ipc::Status status, std::shared_ptr& data) { BOOST_CHECK(status == ipc::Status::OK); recvData = data; @@ -384,7 +375,7 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEchoTest) } -BOOST_AUTO_TEST_CASE(SyncTimeoutTest) +BOOST_AUTO_TEST_CASE(SyncTimeout) { Service s(socketPath); s.addMethodHandler(1, longEchoCallback); @@ -398,7 +389,7 @@ BOOST_AUTO_TEST_CASE(SyncTimeoutTest) BOOST_CHECK_THROW((c.callSync(1, sentData, 10)), IPCException); } -BOOST_AUTO_TEST_CASE(SerializationErrorTest) +BOOST_AUTO_TEST_CASE(SerializationError) { Service s(socketPath); s.addMethodHandler(1, echoCallback); @@ -413,7 +404,7 @@ BOOST_AUTO_TEST_CASE(SerializationErrorTest) } -BOOST_AUTO_TEST_CASE(ParseErrorTest) +BOOST_AUTO_TEST_CASE(ParseError) { Service s(socketPath); s.addMethodHandler(1, echoCallback); @@ -426,11 +417,11 @@ BOOST_AUTO_TEST_CASE(ParseErrorTest) BOOST_CHECK_THROW((c.callSync(1, sentData, 10000)), IPCParsingException); } -BOOST_AUTO_TEST_CASE(DisconnectedPeerErrorTest) +BOOST_AUTO_TEST_CASE(DisconnectedPeerError) { Service s(socketPath); - auto method = [](std::shared_ptr&) { + auto method = [](const PeerID, std::shared_ptr&) { return std::shared_ptr(new SendData(1)); }; @@ -462,10 +453,10 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerErrorTest) } -BOOST_AUTO_TEST_CASE(ReadTimeoutTest) +BOOST_AUTO_TEST_CASE(ReadTimeout) { Service s(socketPath); - auto longEchoCallback = [](std::shared_ptr& data) { + auto longEchoCallback = [](const PeerID, std::shared_ptr& data) { return std::shared_ptr(new LongSendData(data->intVal)); }; s.addMethodHandler(1, longEchoCallback); @@ -480,7 +471,7 @@ BOOST_AUTO_TEST_CASE(ReadTimeoutTest) } -BOOST_AUTO_TEST_CASE(WriteTimeoutTest) +BOOST_AUTO_TEST_CASE(WriteTimeout) { Service s(socketPath); s.addMethodHandler(1, echoCallback); @@ -500,6 +491,66 @@ BOOST_AUTO_TEST_CASE(WriteTimeoutTest) } +BOOST_AUTO_TEST_CASE(AddSignalInRuntime) +{ + Service s(socketPath); + Client c(socketPath); + connect(s, c); + + std::atomic_bool isHandlerACalled(false); + auto handlerA = [&isHandlerACalled](const PeerID, std::shared_ptr&) { + isHandlerACalled = true; + }; + + std::atomic_bool isHandlerBCalled(false); + auto handlerB = [&isHandlerBCalled](const PeerID, std::shared_ptr&) { + isHandlerBCalled = true; + }; + + c.addSignalHandler(1, handlerA); + c.addSignalHandler(2, handlerB); + + auto data = std::make_shared(1); + s.signal(2, data); + s.signal(1, data); + + // Wait for the signals to arrive + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + BOOST_CHECK(isHandlerACalled && isHandlerBCalled); +} + + +BOOST_AUTO_TEST_CASE(AddSignalOffline) +{ + Service s(socketPath); + Client c(socketPath); + + std::atomic_bool isHandlerACalled(false); + auto handlerA = [&isHandlerACalled](const PeerID, std::shared_ptr&) { + isHandlerACalled = true; + }; + + std::atomic_bool isHandlerBCalled(false); + auto handlerB = [&isHandlerBCalled](const PeerID, std::shared_ptr&) { + isHandlerBCalled = true; + }; + + c.addSignalHandler(1, handlerA); + c.addSignalHandler(2, handlerB); + + connect(s, c); + + // Wait for the information about the signals to propagate + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + auto data = std::make_shared(1); + s.signal(2, data); + s.signal(1, data); + + // Wait for the signals to arrive + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + BOOST_CHECK(isHandlerACalled && isHandlerBCalled); +} + // BOOST_AUTO_TEST_CASE(ConnectionLimitTest) // { -- 2.7.4 From a41c5f342fb73d6abd12298c103182bfabc979cc Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 2 Dec 2014 16:27:25 +0100 Subject: [PATCH 10/16] Fix running tests under valgrind [Bug/Feature] Running LXC commands via exec, new building flag USE_EXEC [Cause] N/A [Solution] N/A [Verification] Build with and without USE_EXEC, run tests Change-Id: I42a2745d81d309922704bd213a72727b4c613c40 --- common/lxc/domain.cpp | 160 ++++++++++++++++++++++++++++++++----- common/lxc/domain.hpp | 63 +++++++++++++++ common/utils/c-array.hpp | 73 +++++++++++++++++ common/utils/execute.cpp | 92 +++++++++++++++++++++ common/utils/execute.hpp | 40 ++++++++++ server/container-admin.cpp | 60 ++++---------- tests/unit_tests/lxc/ut-domain.cpp | 1 - 7 files changed, 422 insertions(+), 67 deletions(-) create mode 100644 common/utils/c-array.hpp create mode 100644 common/utils/execute.cpp create mode 100644 common/utils/execute.hpp diff --git a/common/lxc/domain.cpp b/common/lxc/domain.cpp index 191f405..089799d 100644 --- a/common/lxc/domain.cpp +++ b/common/lxc/domain.cpp @@ -22,10 +22,22 @@ * @brief Lxc domain */ +// Define macro USE_EXEC if you are goind to use valgrind +// TODO Consider always using exec to control lxc. Advantages: +// - 'ps' output is more descriptive with lxc-start +// - lxc library is not tested well with multithread programs +// (there are still some issues like using umask etc.) +// - it could be possible not to be uid 0 in this process +// - fork + unshare does not work with traced process (e.g. under valgrind) + #include "config.hpp" #include "logger/logger.hpp" #include "lxc/domain.hpp" #include "lxc/exception.hpp" +#ifdef USE_EXEC +#include "utils/execute.hpp" +#include "utils/c-array.hpp" +#endif #include #include @@ -39,18 +51,36 @@ namespace security_containers { namespace lxc { namespace { +#define ITEM(X) {#X, LxcDomain::State::X}, const std::map STATE_MAP = { - {"STOPPED", LxcDomain::State::STOPPED}, - {"STARTING", LxcDomain::State::STARTING}, - {"RUNNING", LxcDomain::State::RUNNING}, - {"STOPPING", LxcDomain::State::STOPPING}, - {"ABORTING", LxcDomain::State::ABORTING}, - {"FREEZING", LxcDomain::State::FREEZING}, - {"FROZEN", LxcDomain::State::FROZEN}, - {"THAWED", LxcDomain::State::THAWED} + ITEM(STOPPED) + ITEM(STARTING) + ITEM(RUNNING) + ITEM(STOPPING) + ITEM(ABORTING) + ITEM(FREEZING) + ITEM(FROZEN) + ITEM(THAWED) }; +#undef ITEM } // namespace +std::string LxcDomain::toString(State state) +{ +#define CASE(X) case LxcDomain::State::X: return #X; + switch (state) { + CASE(STOPPED) + CASE(STARTING) + CASE(RUNNING) + CASE(STOPPING) + CASE(ABORTING) + CASE(FREEZING) + CASE(FROZEN) + CASE(THAWED) + } +#undef CASE +} + LxcDomain::LxcDomain(const std::string& lxcPath, const std::string& domainName) : mContainer(nullptr) { @@ -76,7 +106,7 @@ std::string LxcDomain::getConfigItem(const std::string& key) char buffer[1024]; int len = mContainer->get_config_item(mContainer, key.c_str(), buffer, sizeof(buffer)); if (len < 0) { - LOGE("Key '" + key + "' not found in domain " + getName()); + LOGE("Key '" << key << "' not found in domain " << getName()); throw LxcException("Key not found"); } return buffer; @@ -95,20 +125,40 @@ LxcDomain::State LxcDomain::getState() bool LxcDomain::create(const std::string& templatePath, const char* const* argv) { +#ifdef USE_EXEC + utils::CStringArrayBuilder args; + args.add("lxc-create") + .add("-n").add(mContainer->name) + .add("-t").add(templatePath.c_str()) + .add("-P").add(mContainer->config_path); + + while (*argv) { + args.add(*argv++); + } + + if (!utils::executeAndWait("/usr/bin/lxc-create", args.c_array())) { + LOGE("Could not create domain " << getName()); + return false; + } + + refresh(); + return true; +#else if (!mContainer->create(mContainer, templatePath.c_str(), NULL, NULL, 0, const_cast(argv))) { - LOGE("Could not create domain " + getName()); + LOGE("Could not create domain " << getName()); return false; } return true; +#endif } bool LxcDomain::destroy() { if (!mContainer->destroy(mContainer)) { - LOGE("Could not destroy domain " + getName()); + LOGE("Could not destroy domain " << getName()); return false; } return true; @@ -116,25 +166,57 @@ bool LxcDomain::destroy() bool LxcDomain::start(const char* const* argv) { +#ifdef USE_EXEC + if (mContainer->is_running(mContainer)) { + LOGE("Already started " << getName()); + return false; + } + + utils::CStringArrayBuilder args; + args.add("lxc-start") + .add("-d") + .add("-n").add(mContainer->name) + .add("-P").add(mContainer->config_path) + .add("--"); + + while (*argv) { + args.add(*argv++); + } + + if (!utils::executeAndWait("/usr/bin/lxc-start", args.c_array())) { + LOGE("Could not start domain " << getName()); + return false; + } + + refresh(); + + // we have to check status because lxc-start runs in daemonized mode + if (!mContainer->is_running(mContainer)) { + LOGE("Could not start init in domain " << getName()); + return false; + } + return true; +#else if (mContainer->is_running(mContainer)) { - LOGE("Already started " + getName()); + LOGE("Already started " << getName()); return false; } if (!mContainer->want_daemonize(mContainer, true)) { - LOGE("Could not configure domain " + getName()); + LOGE("Could not configure domain " << getName()); return false; } if (!mContainer->start(mContainer, false, const_cast(argv))) { - LOGE("Could not start domain " + getName()); + LOGE("Could not start domain " << getName()); return false; } return true; +#endif } bool LxcDomain::stop() { if (!mContainer->stop(mContainer)) { - LOGE("Could not stop domain " + getName()); + LOGE("Could not stop domain " << getName()); return false; } return true; @@ -143,7 +225,7 @@ bool LxcDomain::stop() bool LxcDomain::reboot() { if (!mContainer->reboot(mContainer)) { - LOGE("Could not reboot domain " + getName()); + LOGE("Could not reboot domain " << getName()); return false; } return true; @@ -160,10 +242,27 @@ bool LxcDomain::shutdown(int timeout) return false; } +#ifdef USE_EXEC + utils::CStringArrayBuilder args; + std::string timeoutStr = std::to_string(timeout); + args.add("lxc-stop") + .add("-n").add(mContainer->name) + .add("-P").add(mContainer->config_path) + .add("-t").add(timeoutStr.c_str()) + .add("--nokill"); + + if (!utils::executeAndWait("/usr/bin/lxc-stop", args.c_array())) { + LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); + return false; + } + + refresh(); + return true; +#else // try shutdown by sending poweroff to init if (setRunLevel(utils::RUNLEVEL_POWEROFF)) { - if (!mContainer->wait(mContainer, "STOPPED", timeout)) { - LOGE("Could not gracefully shutdown domain " + getName() + " in " << timeout << "s"); + if (!waitForState(State::STOPPED, timeout)) { + LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); return false; } return true; @@ -172,16 +271,17 @@ bool LxcDomain::shutdown(int timeout) // fallback for other inits like bash: lxc sends 'lxc.haltsignal' signal to init if (!mContainer->shutdown(mContainer, timeout)) { - LOGE("Could not gracefully shutdown domain " + getName() + " in " << timeout << "s"); + LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); return false; } return true; +#endif } bool LxcDomain::freeze() { if (!mContainer->freeze(mContainer)) { - LOGE("Could not freeze domain " + getName()); + LOGE("Could not freeze domain " << getName()); return false; } return true; @@ -190,7 +290,16 @@ bool LxcDomain::freeze() bool LxcDomain::unfreeze() { if (!mContainer->unfreeze(mContainer)) { - LOGE("Could not unfreeze domain " + getName()); + LOGE("Could not unfreeze domain " << getName()); + return false; + } + return true; +} + +bool LxcDomain::waitForState(State state, int timeout) +{ + if (!mContainer->wait(mContainer, toString(state).c_str(), timeout)) { + LOGD("Timeout while waiting for state " << toString(state) << " of domain " << getName()); return false; } return true; @@ -216,6 +325,15 @@ bool LxcDomain::setRunLevel(int runLevel) return status == 0; } +void LxcDomain::refresh() +{ + //TODO Consider make LxcDomain state-less + std::string domainName = mContainer->name; + std::string lxcPath = mContainer->config_path; + lxc_container_put(mContainer); + mContainer = lxc_container_new(domainName.c_str(), lxcPath.c_str()); +} + } // namespace lxc } // namespace security_containers diff --git a/common/lxc/domain.hpp b/common/lxc/domain.hpp index 60ae5a4..3c45b85 100644 --- a/common/lxc/domain.hpp +++ b/common/lxc/domain.hpp @@ -50,34 +50,97 @@ public: THAWED }; + /** + * LxcDomain constructor + * @param lxcPath path where containers lives + * @param domainName name of domain + */ LxcDomain(const std::string& lxcPath, const std::string& domainName); ~LxcDomain(); LxcDomain(const LxcDomain&) = delete; LxcDomain& operator=(const LxcDomain&) = delete; + /** + * Get domain name + */ std::string getName() const; + /** + * Get item from lxc config file + * @throw LxcException if key not found + */ std::string getConfigItem(const std::string& key); + /** + * Is domain defined (created)? + */ bool isDefined(); + /** + * String representation of state + */ + static std::string toString(State state); + + /** + * Get domain state + */ State getState(); + /** + * Wait till domain is in specified state + * @return false on timeout + */ + bool waitForState(State state, int timeout); + + /** + * Create domain + * @param templatePath template from which domain will be created + * @param argv additional template arguments + */ bool create(const std::string& templatePath, const char* const* argv); + + /** + * Destroy domain + */ bool destroy(); + /** + * Start domain + * @param argv init process with arguments + */ bool start(const char* const* argv); + + /** + * Immediate stop the domain + * It kills all processes within this domain + */ bool stop(); + + /** + * Reboot domain + */ bool reboot(); + + /** + * Gracefully shutdown domain. + */ bool shutdown(int timeout); + /** + * Freeze (pause/lock) domain + */ bool freeze(); + + /** + * Unfreeze domain + */ bool unfreeze(); private: lxc_container* mContainer; bool setRunLevel(int runLevel); + void refresh(); }; diff --git a/common/utils/c-array.hpp b/common/utils/c-array.hpp new file mode 100644 index 0000000..73b037b --- /dev/null +++ b/common/utils/c-array.hpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + */ + +/** + * @file + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief C array helper + */ + +#ifndef COMMON_UTILS_C_ARRAY_HPP +#define COMMON_UTILS_C_ARRAY_HPP + +#include + +namespace security_containers { +namespace utils { + +template +class CArrayBuilder { +public: + CArrayBuilder(): mArray(1, nullptr) {} + + CArrayBuilder& add(const T& v) { + mArray.back() = v; + mArray.push_back(nullptr); + return *this; + } + + const T* c_array() const { + return mArray.data(); + } + + size_t size() const { + return mArray.size() - 1; + } + + bool empty() const { + return size() == 0; + } + + const T* begin() const { + return &*mArray.begin(); + } + + const T* end() const { + return &*(mArray.end() - 1); + } +private: + std::vector mArray; +}; + +typedef CArrayBuilder CStringArrayBuilder; + +} // namespace utils +} // namespace security_containers + + +#endif // COMMON_UTILS_C_ARRAY_HPP diff --git a/common/utils/execute.cpp b/common/utils/execute.cpp new file mode 100644 index 0000000..2f2e927 --- /dev/null +++ b/common/utils/execute.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + */ + +/** + * @file + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Execute utils + */ + +#include "config.hpp" +#include "utils/execute.hpp" +#include "logger/logger.hpp" + +#include +#include +#include + +namespace security_containers { +namespace utils { + +namespace { + +std::ostream& operator<< (std::ostream& out, const char* const* argv) +{ + if (*argv) { + argv++; //skip + } + while (*argv) { + out << " '" << *argv++ << "'"; + } + return out; +} + +} // namespace + +bool executeAndWait(const char* fname, const char* const* argv, int& status) +{ + LOGD("Execute " << fname << argv); + + pid_t pid = fork(); + if (pid == -1) { + LOGE("Fork failed"); + return false; + } + if (pid == 0) { + execv(fname, const_cast(argv)); + _exit(EXIT_FAILURE); + } + int ret = waitpid(pid, &status, 0); + if (ret != pid) { + LOGE("Waitpid failed"); + return false; + } + return true; +} + +bool executeAndWait(const char* fname, const char* const* argv) +{ + int status; + if (!executeAndWait(fname, argv, status)) { + return false; + } + if (status != EXIT_SUCCESS) { + if (WIFEXITED(status)) { + LOGW("Process " << fname << " has exited with status " << WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + LOGW("Process " << fname << " was killed by signal " << WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + LOGW("Process " << fname << " was stopped by signal " << WSTOPSIG(status)); + } + return false; + } + return true; +} + +} // namespace utils +} // namespace security_containers diff --git a/common/utils/execute.hpp b/common/utils/execute.hpp new file mode 100644 index 0000000..1fc7b29 --- /dev/null +++ b/common/utils/execute.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + */ + +/** + * @file + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Execute utils + */ + +#ifndef COMMON_UTILS_EXECUTE_HPP +#define COMMON_UTILS_EXECUTE_HPP + + +namespace security_containers { +namespace utils { + +bool executeAndWait(const char* fname, const char* const* argv); + +bool executeAndWait(const char* fname, const char* const* argv, int& status); + +} // namespace utils +} // namespace security_containers + + +#endif // COMMON_UTILS_EXECUTE_HPP diff --git a/server/container-admin.cpp b/server/container-admin.cpp index 65179c3..1d8cdee 100644 --- a/server/container-admin.cpp +++ b/server/container-admin.cpp @@ -29,6 +29,7 @@ #include "logger/logger.hpp" #include "utils/paths.hpp" +#include "utils/c-array.hpp" #include @@ -40,37 +41,6 @@ namespace { // TODO: this should be in container's configuration file const int SHUTDOWN_WAIT = 10; -class Args { -public: - Args(const std::vector& args) - { - mArgs.reserve(args.size() + 1); - for (const std::string& arg : args) { - mArgs.push_back(arg.c_str()); - } - mArgs.push_back(NULL); - } - bool empty() const - { - return mArgs.size() == 1; - } - const char* const* getAsCArray() const - { - return mArgs.data(); - } - friend std::ostream& operator<<(std::ostream& os, const Args& a) - { - for (const char* arg : a.mArgs) { - if (arg != NULL) { - os << "'" << arg << "' "; - } - } - return os; - } -private: - std::vector mArgs; -}; - } // namespace const std::uint64_t DEFAULT_CPU_SHARES = 1024; @@ -82,7 +52,8 @@ ContainerAdmin::ContainerAdmin(const std::string& containersPath, : mConfig(config), mDom(containersPath, config.name), mId(mDom.getName()), - mDetachOnExit(false) + mDetachOnExit(false), + mDestroyOnExit(false) { LOGD(mId << ": Instantiating ContainerAdmin object"); @@ -91,16 +62,16 @@ ContainerAdmin::ContainerAdmin(const std::string& containersPath, const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate, lxcTemplatePrefix); LOGI(mId << ": Creating domain from template: " << lxcTemplate); - std::vector args; + utils::CStringArrayBuilder args; if (!config.ipv4Gateway.empty()) { - args.push_back("--ipv4-gateway"); - args.push_back(config.ipv4Gateway); + args.add("--ipv4-gateway"); + args.add(config.ipv4Gateway.c_str()); } if (!config.ipv4.empty()) { - args.push_back("--ipv4"); - args.push_back(config.ipv4); + args.add("--ipv4"); + args.add(config.ipv4.c_str()); } - if (!mDom.create(lxcTemplate, Args(args).getAsCArray())) { + if (!mDom.create(lxcTemplate, args.c_array())) { throw ContainerOperationException("Could not create domain"); } } @@ -145,16 +116,15 @@ void ContainerAdmin::start() return; } - const Args args(mConfig.initWithArgs); - bool result; + utils::CStringArrayBuilder args; + for (const std::string& arg : mConfig.initWithArgs) { + args.add(arg.c_str()); + } if (args.empty()) { - result = mDom.start(NULL); - } else { - LOGD(mId << ": Init: " << args); - result = mDom.start(args.getAsCArray()); + args.add("/sbin/init"); } - if (!result) { + if (!mDom.start(args.c_array())) { throw ContainerOperationException("Could not start container"); } diff --git a/tests/unit_tests/lxc/ut-domain.cpp b/tests/unit_tests/lxc/ut-domain.cpp index a529f9f..a9942b8 100644 --- a/tests/unit_tests/lxc/ut-domain.cpp +++ b/tests/unit_tests/lxc/ut-domain.cpp @@ -161,7 +161,6 @@ BOOST_AUTO_TEST_CASE(StartHasStoppedTest) NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); waitForInit(); BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); -- 2.7.4 From 161b6dc2bb991737ee46df3bbe1714f1e190144c Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Tue, 2 Dec 2014 17:27:17 +0100 Subject: [PATCH 11/16] IPC: CallQueue [Bug/Feature] CallQueue to wrap the Calls' queue [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I9519114e1c6f2e4040e956ae54f5093646f2dfaf --- common/ipc/internals/call-queue.cpp | 66 ++++++++++++++++ common/ipc/internals/call-queue.hpp | 150 ++++++++++++++++++++++++++++++++++++ common/ipc/internals/processor.cpp | 21 +---- common/ipc/internals/processor.hpp | 81 ++++--------------- 4 files changed, 233 insertions(+), 85 deletions(-) create mode 100644 common/ipc/internals/call-queue.cpp create mode 100644 common/ipc/internals/call-queue.hpp diff --git a/common/ipc/internals/call-queue.cpp b/common/ipc/internals/call-queue.cpp new file mode 100644 index 0000000..9be7e53 --- /dev/null +++ b/common/ipc/internals/call-queue.cpp @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved +* +* Contact: Jan Olszak +* +* 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 +*/ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Managing the queue with calls + */ + +#include "config.hpp" + +#include "ipc/internals/call-queue.hpp" +#include "ipc/exception.hpp" +#include "logger/logger.hpp" + +namespace security_containers { +namespace ipc { + +CallQueue::CallQueue() + : mMessageIDCounter(0) +{ +} + +CallQueue::~CallQueue() +{ +} + +bool CallQueue::isEmpty() const +{ + return mCalls.empty(); +} + +MessageID CallQueue::getNextMessageID() +{ + // TODO: This method of generating UIDs is buggy. To be changed. + return ++mMessageIDCounter; +} + +CallQueue::Call CallQueue::pop() +{ + if (isEmpty()) { + LOGE("CallQueue is empty"); + throw IPCException("CallQueue is empty"); + } + Call call = std::move(mCalls.front()); + mCalls.pop(); + return call; +} + +} // namespace ipc +} // namespace security_containers diff --git a/common/ipc/internals/call-queue.hpp b/common/ipc/internals/call-queue.hpp new file mode 100644 index 0000000..4d1ecf6 --- /dev/null +++ b/common/ipc/internals/call-queue.hpp @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved +* +* Contact: Jan Olszak +* +* 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 +*/ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Managing the queue with calls + */ + +#ifndef COMMON_IPC_INTERNALS_CALL_QUEUE_HPP +#define COMMON_IPC_INTERNALS_CALL_QUEUE_HPP + +#include "ipc/types.hpp" +#include "config/manager.hpp" + +#include +#include + +namespace security_containers { +namespace ipc { + +/** +* Class for managing a queue of calls in the Processor +*/ +class CallQueue { +public: + typedef std::function& data)> SerializeCallback; + typedef std::function(int fd)> ParseCallback; + + struct Call { + Call(const Call& other) = delete; + Call& operator=(const Call&) = delete; + Call() = default; + Call(Call&&) = default; + + PeerID peerID; + MethodID methodID; + MessageID messageID; + std::shared_ptr data; + SerializeCallback serialize; + ParseCallback parse; + ResultHandler::type process; + }; + + CallQueue(); + ~CallQueue(); + + CallQueue(const CallQueue&) = delete; + CallQueue(CallQueue&&) = delete; + CallQueue& operator=(const CallQueue&) = delete; + + template + MessageID push(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process); + + + template + MessageID push(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data); + + Call pop(); + + bool isEmpty() const; + +private: + std::queue mCalls; + std::atomic mMessageIDCounter; + + MessageID getNextMessageID(); +}; + + +template +MessageID CallQueue::push(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data, + const typename ResultHandler::type& process) +{ + Call call; + call.methodID = methodID; + call.peerID = peerID; + call.data = data; + + MessageID messageID = getNextMessageID(); + call.messageID = messageID; + + call.serialize = [](const int fd, std::shared_ptr& data)->void { + config::saveToFD(fd, *std::static_pointer_cast(data)); + }; + + call.parse = [](const int fd)->std::shared_ptr { + std::shared_ptr data(new ReceivedDataType()); + config::loadFromFD(fd, *data); + return data; + }; + + call.process = [process](Status status, std::shared_ptr& data)->void { + std::shared_ptr tmpData = std::static_pointer_cast(data); + return process(status, tmpData); + }; + + mCalls.push(std::move(call)); + + return messageID; +} + +template +MessageID CallQueue::push(const MethodID methodID, + const PeerID peerID, + const std::shared_ptr& data) +{ + Call call; + call.methodID = methodID; + call.peerID = peerID; + call.data = data; + + MessageID messageID = getNextMessageID(); + call.messageID = messageID; + + call.serialize = [](const int fd, std::shared_ptr& data)->void { + config::saveToFD(fd, *std::static_pointer_cast(data)); + }; + + mCalls.push(std::move(call)); + + return messageID; +} + +} // namespace ipc +} // namespace security_containers + +#endif // COMMON_IPC_INTERNALS_CALL_QUEUE_HPP diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp index dc7df42..5565124 100644 --- a/common/ipc/internals/processor.cpp +++ b/common/ipc/internals/processor.cpp @@ -56,7 +56,6 @@ Processor::Processor(const PeerCallback& newPeerCallback, : mNewPeerCallback(newPeerCallback), mRemovedPeerCallback(removedPeerCallback), mMaxNumberOfPeers(maxNumberOfPeers), - mMessageIDCounter(0), mPeerIDCounter(0) { LOGT("Creating Processor"); @@ -579,34 +578,22 @@ bool Processor::onRemovePeer() return true; } -MessageID Processor::getNextMessageID() -{ - // TODO: This method of generating UIDs is buggy. To be changed. - return ++mMessageIDCounter; -} - PeerID Processor::getNextPeerID() { // TODO: This method of generating UIDs is buggy. To be changed. return ++mPeerIDCounter; } -Processor::Call Processor::getCall() +CallQueue::Call Processor::getCall() { Lock lock(mCallsMutex); - if (mCalls.empty()) { - LOGE("Calls queue empty"); - throw IPCException("Calls queue empty"); - } - Call call = std::move(mCalls.front()); - mCalls.pop(); - return call; + return mCalls.pop(); } bool Processor::onCall() { LOGT("Handle call (from another thread) to send a message."); - Call call = getCall(); + CallQueue::Call call = getCall(); std::shared_ptr socketPtr; try { @@ -664,7 +651,7 @@ void Processor::cleanCommunication() } case Event::CALL: { LOGD("Event CALL after FINISH"); - Call call = getCall(); + CallQueue::Call call = getCall(); if (call.process) { IGNORE_EXCEPTIONS(call.process(Status::CLOSING, call.data)); } diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index e43fe62..8fc17fb 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -27,10 +27,10 @@ #include "ipc/internals/socket.hpp" #include "ipc/internals/event-queue.hpp" +#include "ipc/internals/call-queue.hpp" #include "ipc/exception.hpp" #include "ipc/types.hpp" #include "config/manager.hpp" -#include "config/is-visitable.hpp" #include "config/fields.hpp" #include "logger/logger.hpp" @@ -70,11 +70,12 @@ const unsigned int DEFAULT_METHOD_TIMEOUT = 1000; * TODO: * - some mutexes may not be needed * - synchronous call to many peers -* - implement CallQueue class * - implement HandlerStore class for storing both signals and methods * - API for removing signals * - implement CallbackStore - thread safe calling/setting callbacks * - helper function for removing from unordered map +* - new way to generate UIDs +* - callbacks for serialization/parsing */ class Processor { public: @@ -261,21 +262,6 @@ private: ) }; - struct Call { - Call(const Call& other) = delete; - Call& operator=(const Call&) = delete; - Call() = default; - Call(Call&&) = default; - - PeerID peerID; - MethodID methodID; - std::shared_ptr data; - SerializeCallback serialize; - ParseCallback parse; - ResultHandler::type process; - MessageID messageID; - }; - struct MethodHandlers { MethodHandlers(const MethodHandlers& other) = delete; MethodHandlers& operator=(const MethodHandlers&) = delete; @@ -356,7 +342,7 @@ private: // Mutex for the Calls queue and the map of methods. std::mutex mCallsMutex; - std::queue mCalls; + CallQueue mCalls; std::unordered_map> mMethodsCallbacks; std::unordered_map> mSignalsCallbacks; std::unordered_map> mSignalsPeers; @@ -382,18 +368,12 @@ private: std::thread mThread; std::vector mFDs; - std::atomic mMessageIDCounter; std::atomic mPeerIDCounter; template void addMethodHandlerInternal(const MethodID methodID, const typename MethodHandler::type& process); - template - MessageID callInternal(const MethodID methodID, - const PeerID peerID, - const std::shared_ptr& data); - template MessageID callInternal(const MethodID methodID, const PeerID peerID, @@ -425,9 +405,8 @@ private: const MessageID messageID, std::shared_ptr signalCallbacks); void resetPolling(); - MessageID getNextMessageID(); PeerID getNextPeerID(); - Call getCall(); + CallQueue::Call getCall(); void removePeerInternal(const PeerID peerID, Status status); std::shared_ptr onNewSignals(const PeerID peerID, @@ -547,34 +526,11 @@ MessageID Processor::callInternal(const MethodID methodID, const std::shared_ptr& data, const typename ResultHandler::type& process) { - Call call; - call.peerID = peerID; - call.methodID = methodID; - call.data = data; - call.messageID = getNextMessageID(); - - call.serialize = [](const int fd, std::shared_ptr& data)->void { - config::saveToFD(fd, *std::static_pointer_cast(data)); - }; - - call.parse = [](const int fd)->std::shared_ptr { - std::shared_ptr data(new ReceivedDataType()); - config::loadFromFD(fd, *data); - return data; - }; - - call.process = [process](Status status, std::shared_ptr& data)->void { - std::shared_ptr tmpData = std::static_pointer_cast(data); - return process(status, tmpData); - }; + Lock lock(mCallsMutex); + MessageID messageID = mCalls.push(methodID, peerID, data, process); + mEventQueue.send(Event::CALL); - { - Lock lock(mCallsMutex); - mCalls.push(std::move(call)); - mEventQueue.send(Event::CALL); - } - - return call.messageID; + return messageID; } template @@ -660,24 +616,13 @@ void Processor::signal(const MethodID methodID, } for (const PeerID peerID : peersIDs) { - Call call; - call.peerID = peerID; - call.methodID = methodID; - call.data = data; - call.messageID = getNextMessageID(); - - call.serialize = [](const int fd, std::shared_ptr& data)->void { - config::saveToFD(fd, *std::static_pointer_cast(data)); - }; - - { - Lock lock(mCallsMutex); - mCalls.push(std::move(call)); - mEventQueue.send(Event::CALL); - } + Lock lock(mCallsMutex); + mCalls.push(methodID, peerID, data); + mEventQueue.send(Event::CALL); } } + } // namespace ipc } // namespace security_containers -- 2.7.4 From 1b846e5c49695251d97aaf3c1e2af4af12bb404d Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Wed, 3 Dec 2014 17:03:43 +0100 Subject: [PATCH 12/16] Fix compilation issue [Bug/Feature] Code does not compile under gcc 4.6 [Cause] N/A [Solution] N/A [Verification] Build Change-Id: I883ae5c04de5dafd690e4ac2c1956780f8d20725 --- common/lxc/domain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/common/lxc/domain.cpp b/common/lxc/domain.cpp index 089799d..24453a6 100644 --- a/common/lxc/domain.cpp +++ b/common/lxc/domain.cpp @@ -79,6 +79,7 @@ std::string LxcDomain::toString(State state) CASE(THAWED) } #undef CASE + throw LxcException("Invalid state"); } LxcDomain::LxcDomain(const std::string& lxcPath, const std::string& domainName) -- 2.7.4 From d4dab9bd6038657d87eebc757af4aeefd0814cc6 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Fri, 28 Nov 2014 14:50:15 +0100 Subject: [PATCH 13/16] Add stubs for provisioning [Bug/Feature] Stubs (client and server) for provisioning [Cause] N/A [Solution] N/A [Verification] Build Change-Id: Id8f4a0cb3d59fce8fed6f036b0d57f480ffff275 --- client/security-containers-client-impl.cpp | 48 ++++++++++ client/security-containers-client-impl.hpp | 25 ++++++ client/security-containers-client.cpp | 32 +++++++ client/security-containers-client.h | 72 +++++++++++++++ server/containers-manager.cpp | 44 +++++++++ server/containers-manager.hpp | 17 ++++ server/host-connection.cpp | 63 +++++++++++++ server/host-connection.hpp | 38 ++++++++ server/host-dbus-definitions.hpp | 23 +++++ tests/unit_tests/server/ut-containers-manager.cpp | 103 ++++++++++++++++++++++ 10 files changed, 465 insertions(+) diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 1a6e999..b84e903 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -569,6 +569,53 @@ VsmStatus Client::vsm_lookup_netdev_by_name(const char*, const char*, VsmNetdev* return vsm_get_status(); } +VsmStatus Client::vsm_declare_file(const char* container, + VsmFileType type, + const char *path, + int32_t flags, + mode_t mode) noexcept +{ + assert(path); + + GVariant* args_in = g_variant_new("(sisii)", container, type, path, flags, mode); + return callMethod(CONTAINER_INTERFACE, + api::host::METHOD_DECLARE_FILE, + args_in); +} + +VsmStatus Client::vsm_declare_mount(const char *source, + const char* container, + const char *target, + const char *type, + uint64_t flags, + const char *data) noexcept +{ + assert(source); + assert(target); + assert(type); + if (!data) { + data = ""; + } + + GVariant* args_in = g_variant_new("(ssssts)", source, container, target, type, flags, data); + return callMethod(CONTAINER_INTERFACE, + api::host::METHOD_DECLARE_MOUNT, + args_in); +} + +VsmStatus Client::vsm_declare_link(const char *source, + const char* container, + const char *target) noexcept +{ + assert(source); + assert(target); + + GVariant* args_in = g_variant_new("(sss)", source, container, target); + return callMethod(CONTAINER_INTERFACE, + api::host::METHOD_DECLARE_LINK, + args_in); +} + VsmStatus Client::vsm_notify_active_container(const char* application, const char* message) noexcept { assert(application); @@ -631,3 +678,4 @@ VsmStatus Client::vsm_del_notification_callback(VsmSubscriptionId subscriptionId { return signalUnsubscribe(subscriptionId); } + diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index df07099..585716d 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -248,6 +248,31 @@ public: VsmNetdev* netdev) noexcept; /** + * @see ::vsm_declare_file + */ + VsmStatus vsm_declare_file(const char* container, + VsmFileType type, + const char* path, + int32_t flags, + mode_t mode) noexcept; + + /** + * @see ::vsm_declare_mount + */ + VsmStatus vsm_declare_mount(const char* source, + const char* container, + const char* target, + const char* type, + uint64_t flags, + const char* data) noexcept; + /** + * @see ::vsm_declare_link + */ + VsmStatus vsm_declare_link(const char* source, + const char* container, + const char* target) noexcept; + + /** * @see ::vsm_notify_active_container */ VsmStatus vsm_notify_active_container(const char* application, const char* message) noexcept; diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index ef571c8..3ebede0 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -272,6 +272,37 @@ API VsmStatus vsm_lookup_netdev_by_name(VsmClient client, return getClient(client).vsm_lookup_netdev_by_name(domain, netdevId, netdev); } +API VsmStatus vsm_declare_file(VsmClient client, + const char* container, + VsmFileType type, + const char* path, + int32_t flags, + mode_t mode) +{ + return getClient(client).vsm_declare_file(container, type, path, flags, mode); +} + + +API VsmStatus vsm_declare_mount(VsmClient client, + const char* source, + const char* container, + const char* target, + const char* type, + uint64_t flags, + const char* data) +{ + return getClient(client).vsm_declare_mount(source, container, target, type, flags, data); +} + +API VsmStatus vsm_declare_link(VsmClient client, + const char* source, + const char* container, + const char* target) +{ + return getClient(client).vsm_declare_link(source, container, target); +} + + API VsmStatus vsm_notify_active_container(VsmClient client, const char* application, const char* message) @@ -297,3 +328,4 @@ API VsmStatus vsm_del_notification_callback(VsmClient client, { return getClient(client).vsm_del_notification_callback(subscriptionId); } + diff --git a/client/security-containers-client.h b/client/security-containers-client.h index e7e738c..8e404ff 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -79,6 +79,7 @@ finish: #define SECURITY_CONTAINERS_CLIENT_H #include +#include #ifdef __cplusplus extern "C" @@ -176,6 +177,15 @@ typedef struct { typedef VsmNetdevStructure* VsmNetdev; /** + * File type + */ +typedef enum { + VSMFILE_DIRECTORY, + VSMFILE_FIFO, + VSMFILE_REGULAR, +} VsmFileType; + +/** * Start glib loop. * * Do not call this function if an application creates a glib loop itself. @@ -580,6 +590,68 @@ VsmStatus vsm_lookup_netdev_by_name(VsmClient client, const char* netdevId, VsmNetdev* netdev); +/** + * Create file, directory or pipe in container + * + * Declare file, directory or pipe that will be created while container startup + * + * @param[in] client security-containers-server's client + * @param[in] type file type + * @param[in] container container id + * @param[in] path path to file + * @param[in] flags if O_CREAT bit is set then file will be created in container, + * otherwise file will by copied from host; + * it is meaningful only when O_CREAT is set + * @param[in] mode mode of file + * @return status of this function call + */ +VsmStatus vsm_declare_file(VsmClient client, + const char* container, + VsmFileType type, + const char* path, + int32_t flags, + mode_t mode); + +/** + * Create mount point in container + * + * Declare mount that will be created while container startup + * Parameters are passed to mount system function + * + * @param[in] client security-containers-server's client + * @param[in] source device path (path in host) + * @param[in] container container id + * @param[in] target mount point (path in container) + * @param[in] type filesystem type + * @param[in] flags mount flags as in mount function + * @patam[in] data additional data as in mount function + * @return status of this function call + */ +VsmStatus vsm_declare_mount(VsmClient client, + const char* source, + const char* container, + const char* target, + const char* type, + uint64_t flags, + const char* data); + +/** + * Create link in container + * + * Declare link that will be created while container startup + * Parameters are passed to link system function + * + * @param[in] client security-containers-server's client + * @param[in] source path to link source (in host) + * @param[in] container container id + * @param[in] target path to link name (in container) + * @return status of this function call + */ +VsmStatus vsm_declare_link(VsmClient client, + const char *source, + const char* container, + const char *target); + /** @} */ // Host API diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 5a6a32b..d34cb87 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -98,6 +98,15 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setGetContainerInfoCallback(bind(&ContainersManager::handleGetContainerInfoCall, this, _1, _2)); + mHostConnection.setDeclareFileCallback(bind(&ContainersManager::handleDeclareFileCall, + this, _1, _2, _3, _4, _5, _6)); + + mHostConnection.setDeclareMountCallback(bind(&ContainersManager::handleDeclareMountCall, + this, _1, _2, _3, _4, _5, _6, _7)); + + mHostConnection.setDeclareLinkCallback(bind(&ContainersManager::handleDeclareLinkCall, + this, _1, _2, _3, _4)); + mHostConnection.setSetActiveContainerCallback(bind(&ContainersManager::handleSetActiveContainerCall, this, _1, _2)); @@ -546,6 +555,41 @@ void ContainersManager::handleGetContainerInfoCall(const std::string& id, rootfsPath.string().c_str())); } +void ContainersManager::handleDeclareFileCall(const std::string& /* container */, + const int32_t& /* type */, + const std::string& /* path */, + const int32_t& /* flags */, + const int32_t& /* mode */, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("DeclareFile call"); + LOGE("Not implemeted method"); + result->setError(api::ERROR_INTERNAL, "Not implemented"); +} + +void ContainersManager::handleDeclareMountCall(const std::string& /* source */, + const std::string& /* container */, + const std::string& /* target */, + const std::string& /* type */, + const uint64_t& /* flags */, + const std::string& /* data */, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("DeclareMount call"); + LOGE("Not implemeted method"); + result->setError(api::ERROR_INTERNAL, "Not implemented"); +} + +void ContainersManager::handleDeclareLinkCall(const std::string& /* source */, + const std::string& /* container */, + const std::string& /* target */, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("DeclareLink call"); + LOGE("Not implemeted method"); + result->setError(api::ERROR_INTERNAL, "Not implemented"); +} + void ContainersManager::handleSetActiveContainerCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index 70637bc..4adaaf8 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -131,6 +131,23 @@ private: void handleGetContainerIdsCall(dbus::MethodResultBuilder::Pointer result); void handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result); void handleGetContainerInfoCall(const std::string& id, dbus::MethodResultBuilder::Pointer result); + void handleDeclareFileCall(const std::string& container, + const int32_t& type, + const std::string& path, + const int32_t& flags, + const int32_t& mode, + dbus::MethodResultBuilder::Pointer result); + void handleDeclareMountCall(const std::string& source, + const std::string& container, + const std::string& target, + const std::string& type, + const uint64_t& flags, + const std::string& data, + dbus::MethodResultBuilder::Pointer result); + void handleDeclareLinkCall(const std::string& source, + const std::string& container, + const std::string& target, + dbus::MethodResultBuilder::Pointer result); void handleSetActiveContainerCall(const std::string& id, dbus::MethodResultBuilder::Pointer result); void handleCreateContainerCall(const std::string& id, diff --git a/server/host-connection.cpp b/server/host-connection.cpp index b7d72b7..9b22f7b 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -130,6 +130,21 @@ void HostConnection::setGetContainerInfoCallback(const GetContainerInfoCallback& mGetContainerInfoCallback = callback; } +void HostConnection::setDeclareFileCallback(const DeclareFileCallback& callback) +{ + mDeclareFileCallback = callback; +} + +void HostConnection::setDeclareMountCallback(const DeclareMountCallback& callback) +{ + mDeclareMountCallback = callback; +} + +void HostConnection::setDeclareLinkCallback(const DeclareLinkCallback& callback) +{ + mDeclareLinkCallback = callback; +} + void HostConnection::setSetActiveContainerCallback(const SetActiveContainerCallback& callback) { mSetActiveContainerCallback = callback; @@ -225,6 +240,54 @@ void HostConnection::onMessageCall(const std::string& objectPath, return; } + if (methodName == api::host::METHOD_DECLARE_FILE) { + const gchar* container; + int32_t type; + const gchar* path; + int32_t flags; + int32_t mode; + g_variant_get(parameters, "(&si&sii)", &container, &type, &path, &flags, &mode); + + if (mDeclareFileCallback) { + mDeclareFileCallback(container, type, path, flags, mode, result); + } + return; + } + + if (methodName == api::host::METHOD_DECLARE_MOUNT) { + const gchar* source; + const gchar* container; + const gchar* target; + const gchar* type; + uint64_t flags; + const gchar* data; + g_variant_get(parameters, + "(&s&s&s&st&s)", + &source, + &container, + &target, + &type, + &flags, + &data); + + if (mDeclareMountCallback) { + mDeclareMountCallback(source, container, target, type, flags, data, result); + } + return; + } + + if (methodName == api::host::METHOD_DECLARE_LINK) { + const gchar* source; + const gchar* container; + const gchar* target; + g_variant_get(parameters, "(&s&s&s)", &source, &container, &target); + + if (mDeclareLinkCallback) { + mDeclareLinkCallback(source, container, target, result); + } + return; + } + if (methodName == api::host::METHOD_CREATE_CONTAINER) { const gchar* id = NULL; g_variant_get(parameters, "(&s)", &id); diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 8392578..ab13b50 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -60,6 +60,26 @@ public: typedef std::function GetContainerInfoCallback; + typedef std::function DeclareFileCallback; + typedef std::function DeclareMountCallback; + typedef std::function DeclareLinkCallback; typedef std::function SetActiveContainerCallback; @@ -101,6 +121,21 @@ public: void setGetContainerInfoCallback(const GetContainerInfoCallback& callback); /** + * Register a callback called to declare file + */ + void setDeclareFileCallback(const DeclareFileCallback& callback); + + /** + * Register a callback called to declare mount point + */ + void setDeclareMountCallback(const DeclareMountCallback& callback); + + /** + * Register a callback called to declare link + */ + void setDeclareLinkCallback(const DeclareLinkCallback& callback); + + /** * Register a callback called to set the active container */ void setSetActiveContainerCallback(const SetActiveContainerCallback& callback); @@ -136,6 +171,9 @@ private: GetContainerIdsCallback mGetContainerIdsCallback; GetActiveContainerIdCallback mGetActiveContainerIdCallback; GetContainerInfoCallback mGetContainerInfoCallback; + DeclareFileCallback mDeclareFileCallback; + DeclareMountCallback mDeclareMountCallback; + DeclareLinkCallback mDeclareLinkCallback; SetActiveContainerCallback mSetActiveContainerCallback; CreateContainerCallback mCreateContainerCallback; DestroyContainerCallback mDestroyContainerCallback; diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index b7b49c4..b61a4f8 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -42,6 +42,9 @@ const std::string METHOD_GET_CONTAINER_DBUSES = "GetContainerDbuses"; const std::string METHOD_GET_CONTAINER_ID_LIST = "GetContainerIds"; const std::string METHOD_GET_ACTIVE_CONTAINER_ID = "GetActiveContainerId"; const std::string METHOD_GET_CONTAINER_INFO = "GetContainerInfo"; +const std::string METHOD_DECLARE_FILE = "DeclareFile"; +const std::string METHOD_DECLARE_MOUNT = "DeclareMount"; +const std::string METHOD_DECLARE_LINK = "DeclareLink"; const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer"; const std::string METHOD_CREATE_CONTAINER = "CreateContainer"; const std::string METHOD_DESTROY_CONTAINER = "DestroyContainer"; @@ -74,6 +77,26 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " " " " " diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 46f659f..ef990f7 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -309,6 +309,67 @@ public: } + void callMethodDeclareFile(const std::string& container, + const int32_t& type, + const std::string& path, + const int32_t& flags, + const int32_t& mode) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(sisii)", + container.c_str(), + type, + path.c_str(), + flags, + mode); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_DECLARE_FILE, + parameters, + "()"); + } + + void callMethodDeclareMount(const std::string& source, + const std::string& container, + const std::string& target, + const std::string& type, + const uint64_t& flags, + const std::string& data) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(ssssts)", + source.c_str(), + container.c_str(), + target.c_str(), + type.c_str(), + flags, + data.c_str()); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_DECLARE_MOUNT, + parameters, + "()"); + } + + void callMethodDeclareLink(const std::string& source, + const std::string& container, + const std::string& target) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(sss)", + source.c_str(), + container.c_str(), + target.c_str()); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_DECLARE_LINK, + parameters, + "()"); + } + void callAsyncMethodCreateContainer(const std::string& id, const VoidResultCallback& result) { @@ -987,4 +1048,46 @@ BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest) BOOST_CHECK(cm.getRunningForegroundContainerId() == ""); } +BOOST_AUTO_TEST_CASE(DeclareFile) +{ + //TODO Fill after implementing + const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first; + + ContainersManager cm(TEST_CONFIG_PATH); + DbusAccessory dbus(DbusAccessory::HOST_ID); + BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareFile(container, 1, "path", 747, 777), + DbusException, + expectedMessage("Not implemented")); +} + +BOOST_AUTO_TEST_CASE(DeclareMount) +{ + //TODO Fill after implementing + const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first; + + ContainersManager cm(TEST_CONFIG_PATH); + DbusAccessory dbus(DbusAccessory::HOST_ID); + BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareMount("/fake/path1", + container, + "/fake/path2", + "tmpfs", + 77, + "fake"), + DbusException, + expectedMessage("Not implemented")); + +} + +BOOST_AUTO_TEST_CASE(DeclareLink) +{ + //TODO Fill after implementing + const std::string container = EXPECTED_DBUSES_NO_DBUS.begin()->first; + + ContainersManager cm(TEST_CONFIG_PATH); + DbusAccessory dbus(DbusAccessory::HOST_ID); + BOOST_CHECK_EXCEPTION(dbus.callMethodDeclareLink("/fake/path1", container, "/fake/path2"), + DbusException, + expectedMessage("Not implemented")); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From f568db9d5422ee787c7f2f14d2113ac5f601e238 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 4 Dec 2014 10:50:16 +0100 Subject: [PATCH 14/16] Fix: Removed comma at end of enum [Bug/Feature] Gcc 4.6 does not complie [Cause] N/A [Solution] N/A [Verification] Build Change-Id: Ic293014b3211fea8b0896a93e5336f59a3a9956f --- client/security-containers-client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 8e404ff..2e4d96b 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -182,7 +182,7 @@ typedef VsmNetdevStructure* VsmNetdev; typedef enum { VSMFILE_DIRECTORY, VSMFILE_FIFO, - VSMFILE_REGULAR, + VSMFILE_REGULAR } VsmFileType; /** -- 2.7.4 From 0314574a325461e60720db738d08bd809e9dd7ba Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 27 Nov 2014 15:05:36 +0100 Subject: [PATCH 15/16] Added lock_domain/unlock_domain to container manager [Feature] Ability to lock/unlock domain [Cause] The need for the ability to lock/unlock domains [Solution] Add lock_domain/unlock_domain function [Verification] Build, install, run Change-Id: I169f94ceef462346a33530ec467c9bb239b57d85 Signed-off-by: Dariusz Michaluk --- client/security-containers-client-impl.cpp | 16 +++-- server/common-dbus-definitions.hpp | 9 +-- server/container.cpp | 12 ++++ server/container.hpp | 10 +++ server/containers-manager.cpp | 87 +++++++++++++++++++++++ server/containers-manager.hpp | 14 ++++ server/host-connection.cpp | 29 ++++++++ server/host-connection.hpp | 18 +++++ server/host-dbus-definitions.hpp | 8 +++ tests/unit_tests/client/ut-client.cpp | 14 ++++ tests/unit_tests/server/ut-containers-manager.cpp | 54 ++++++++++++++ 11 files changed, 261 insertions(+), 10 deletions(-) diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index b84e903..aa8a796 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -472,16 +472,20 @@ VsmStatus Client::vsm_start_domain(const char*) noexcept return vsm_get_status(); } -VsmStatus Client::vsm_lock_domain(const char*) noexcept +VsmStatus Client::vsm_lock_domain(const char* id) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); - return vsm_get_status(); + assert(id); + + GVariant* args_in = g_variant_new("(s)", id); + return callMethod(HOST_INTERFACE, api::host::METHOD_LOCK_CONTAINER, args_in); } -VsmStatus Client::vsm_unlock_domain(const char*) noexcept +VsmStatus Client::vsm_unlock_domain(const char* id) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); - return vsm_get_status(); + assert(id); + + GVariant* args_in = g_variant_new("(s)", id); + return callMethod(HOST_INTERFACE, api::host::METHOD_UNLOCK_CONTAINER, args_in); } VsmStatus Client::vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback, diff --git a/server/common-dbus-definitions.hpp b/server/common-dbus-definitions.hpp index 77d0949..389f73f 100644 --- a/server/common-dbus-definitions.hpp +++ b/server/common-dbus-definitions.hpp @@ -30,10 +30,11 @@ namespace security_containers { namespace api { -const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden"; -const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded"; -const std::string ERROR_INVALID_ID = "org.tizen.containers.Error.InvalidId"; -const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal"; +const std::string ERROR_FORBIDDEN = "org.tizen.containers.Error.Forbidden"; +const std::string ERROR_FORWARDED = "org.tizen.containers.Error.Forwarded"; +const std::string ERROR_INVALID_ID = "org.tizen.containers.Error.InvalidId"; +const std::string ERROR_INVALID_STATE = "org.tizen.containers.Error.InvalidState"; +const std::string ERROR_INTERNAL = "org.tizen.containers.Error.Internal"; const std::string METHOD_PROXY_CALL = "ProxyCall"; diff --git a/server/container.cpp b/server/container.cpp index c371d8a..e1377d0 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -258,6 +258,18 @@ bool Container::isStopped() return mAdmin->isStopped(); } +void Container::suspend() +{ + Lock lock(mReconnectMutex); + mAdmin->suspend(); +} + +void Container::resume() +{ + Lock lock(mReconnectMutex); + mAdmin->resume(); +} + bool Container::isPaused() { Lock lock(mReconnectMutex); diff --git a/server/container.hpp b/server/container.hpp index bc1303c..b0264cb 100644 --- a/server/container.hpp +++ b/server/container.hpp @@ -154,6 +154,16 @@ public: bool isStopped(); /** + * Suspend container. + */ + void suspend(); + + /** + * Resume container. + */ + void resume(); + + /** * @return Is the container in a paused state? */ bool isPaused(); diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index d34cb87..c5fb04e 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -116,6 +116,12 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet mHostConnection.setDestroyContainerCallback(bind(&ContainersManager::handleDestroyContainerCall, this, _1, _2)); + mHostConnection.setLockContainerCallback(bind(&ContainersManager::handleLockContainerCall, + this, _1, _2)); + + mHostConnection.setUnlockContainerCallback(bind(&ContainersManager::handleUnlockContainerCall, + this, _1, _2)); + for (auto& containerConfig : mConfig.containerConfigs) { createContainer(containerConfig); } @@ -261,6 +267,27 @@ void ContainersManager::stopAll() } } +bool ContainersManager::isPaused(const std::string& containerId) +{ + auto iter = mContainers.find(containerId); + if (iter == mContainers.end()) { + LOGE("No such container id: " << containerId); + throw ContainerOperationException("No such container"); + } + + return iter->second->isPaused(); +} + +bool ContainersManager::isRunning(const std::string& containerId) +{ + auto iter = mContainers.find(containerId); + if (iter == mContainers.end()) { + LOGE("No such container id: " << containerId); + throw ContainerOperationException("No such container"); + } + return iter->second->isRunning(); +} + std::string ContainersManager::getRunningForegroundContainerId() { for (auto& container : mContainers) { @@ -774,4 +801,64 @@ void ContainersManager::handleDestroyContainerCall(const std::string& id, thread.detach(); //TODO fix it } +void ContainersManager::handleLockContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("LockContainer call; Id=" << id ); + auto iter = mContainers.find(id); + if (iter == mContainers.end()) { + LOGE("Failed to lock container - no such container id: " << id); + result->setError(api::ERROR_INVALID_ID, "No such container id"); + return; + } + + auto& container = *iter->second; + if (!container.isRunning()) { + LOGE("Container id=" << id << " is not running."); + result->setError(api::ERROR_INVALID_STATE, "Container is not running"); + return; + } + + LOGT("Lock container"); + try { + container.suspend(); + } catch (ContainerOperationException& e) { + LOGE(e.what()); + result->setError(api::ERROR_INTERNAL, e.what()); + return; + } + + result->setVoid(); +} + +void ContainersManager::handleUnlockContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result) +{ + LOGI("UnlockContainer call; Id=" << id ); + auto iter = mContainers.find(id); + if (iter == mContainers.end()) { + LOGE("Failed to unlock container - no such container id: " << id); + result->setError(api::ERROR_INVALID_ID, "No such container id"); + return; + } + + auto& container = *iter->second; + if (!container.isPaused()) { + LOGE("Container id=" << id << " is not paused."); + result->setError(api::ERROR_INVALID_STATE, "Container is not paused"); + return; + } + + LOGT("Unlock container"); + try { + container.resume(); + } catch (ContainerOperationException& e) { + LOGE(e.what()); + result->setError(api::ERROR_INTERNAL, e.what()); + return; + } + + result->setVoid(); +} + } // namespace security_containers diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index 4adaaf8..5f31b97 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -79,6 +79,16 @@ public: void stopAll(); /** + * @return Is the container in a paused state? + */ + bool isPaused(const std::string& containerId); + + /** + * @return Is the container running? + */ + bool isRunning(const std::string& containerId); + + /** * @return id of the currently focused/foreground container */ std::string getRunningForegroundContainerId(); @@ -154,6 +164,10 @@ private: dbus::MethodResultBuilder::Pointer result); void handleDestroyContainerCall(const std::string& id, dbus::MethodResultBuilder::Pointer result); + void handleLockContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result); + void handleUnlockContainerCall(const std::string& id, + dbus::MethodResultBuilder::Pointer result); }; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 9b22f7b..f862b55 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -160,6 +160,17 @@ void HostConnection::setDestroyContainerCallback(const DestroyContainerCallback& mDestroyContainerCallback = callback; } +void HostConnection::setLockContainerCallback(const LockContainerCallback& callback) +{ + mLockContainerCallback = callback; +} + +void HostConnection::setUnlockContainerCallback(const UnlockContainerCallback& callback) +{ + mUnlockContainerCallback = callback; +} + + void HostConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, @@ -305,6 +316,24 @@ void HostConnection::onMessageCall(const std::string& objectPath, mDestroyContainerCallback(id, result); } } + + if (methodName == api::host::METHOD_LOCK_CONTAINER) { + const gchar* id = NULL; + g_variant_get(parameters, "(&s)", &id); + + if (mLockContainerCallback){ + mLockContainerCallback(id, result); + } + } + + if (methodName == api::host::METHOD_UNLOCK_CONTAINER) { + const gchar* id = NULL; + g_variant_get(parameters, "(&s)", &id); + + if (mUnlockContainerCallback){ + mUnlockContainerCallback(id, result); + } + } } void HostConnection::proxyCallAsync(const std::string& busName, diff --git a/server/host-connection.hpp b/server/host-connection.hpp index ab13b50..0030efc 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -89,6 +89,12 @@ public: typedef std::function DestroyContainerCallback; + typedef std::function LockContainerCallback; + typedef std::function UnlockContainerCallback; /** * Register proxy call callback @@ -151,6 +157,16 @@ public: void setDestroyContainerCallback(const DestroyContainerCallback& callback); /** + * Register a callback called to lock container + */ + void setLockContainerCallback(const LockContainerCallback& callback); + + /** + * Register a callback called to unlock container + */ + void setUnlockContainerCallback(const UnlockContainerCallback& callback); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -177,6 +193,8 @@ private: SetActiveContainerCallback mSetActiveContainerCallback; CreateContainerCallback mCreateContainerCallback; DestroyContainerCallback mDestroyContainerCallback; + LockContainerCallback mLockContainerCallback; + UnlockContainerCallback mUnlockContainerCallback; void onNameAcquired(); void onNameLost(); diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index b61a4f8..1b134ea 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -48,6 +48,8 @@ const std::string METHOD_DECLARE_LINK = "DeclareLink"; const std::string METHOD_SET_ACTIVE_CONTAINER = "SetActiveContainer"; const std::string METHOD_CREATE_CONTAINER = "CreateContainer"; const std::string METHOD_DESTROY_CONTAINER = "DestroyContainer"; +const std::string METHOD_LOCK_CONTAINER = "LockContainer"; +const std::string METHOD_UNLOCK_CONTAINER = "UnlockContainer"; const std::string SIGNAL_CONTAINER_DBUS_STATE = "ContainerDbusState"; @@ -106,6 +108,12 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " + " " + " " + " " " " " " " " diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 934a062..61ed580 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -225,6 +225,20 @@ BOOST_AUTO_TEST_CASE(CreateContainerTest) vsm_client_free(client); } +BOOST_AUTO_TEST_CASE(LockUnlockContainerTest) +{ + const std::string newActiveContainerId = "ut-containers-manager-console2-dbus"; + + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + status = vsm_lock_domain(client, newActiveContainerId.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + status = vsm_unlock_domain(client, newActiveContainerId.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + vsm_client_free(client); +} + BOOST_AUTO_TEST_CASE(FileMoveRequestTest) { const std::string path = "/tmp/fake_path"; diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index ef990f7..73643a8 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -408,6 +408,30 @@ public: asyncResult); } + void callMethodLockContainer(const std::string& id) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(s)", id.c_str()); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_LOCK_CONTAINER, + parameters, + "()"); + } + + void callMethodUnlockContainer(const std::string& id) + { + assert(isHost()); + GVariant* parameters = g_variant_new("(s)", id.c_str()); + GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, + api::host::OBJECT_PATH, + api::host::INTERFACE, + api::host::METHOD_UNLOCK_CONTAINER, + parameters, + "()"); + } + private: const int mId; DbusConnection::Pointer mClient; @@ -1090,4 +1114,34 @@ BOOST_AUTO_TEST_CASE(DeclareLink) expectedMessage("Not implemented")); } +BOOST_AUTO_TEST_CASE(LockUnlockContainerTest) +{ + ContainersManager cm(TEST_DBUS_CONFIG_PATH); + cm.startAll(); + + DbusAccessory dbus(DbusAccessory::HOST_ID); + + std::vector containerIds = {"ut-containers-manager-console1-dbus", + "ut-containers-manager-console2-dbus", + "ut-containers-manager-console3-dbus"}; + + for (std::string& containerId: containerIds){ + dbus.callMethodLockContainer(containerId); + BOOST_CHECK(cm.isPaused(containerId)); + dbus.callMethodUnlockContainer(containerId); + BOOST_CHECK(cm.isRunning(containerId)); + } + + BOOST_REQUIRE_THROW(dbus.callMethodLockContainer(NON_EXISTANT_CONTAINER_ID), + DbusException); + BOOST_REQUIRE_THROW(dbus.callMethodUnlockContainer(NON_EXISTANT_CONTAINER_ID), + DbusException); + + cm.stopAll(); + BOOST_REQUIRE_THROW(dbus.callMethodLockContainer("ut-containers-manager-console1-dbus"), + DbusException); + BOOST_REQUIRE_THROW(dbus.callMethodUnlockContainer("ut-containers-manager-console1-dbus"), + DbusException); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 2d89e4343e5fe67fb267f6f910db83ee6cc5e6cf Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 2 Dec 2014 15:18:51 +0100 Subject: [PATCH 16/16] Rename domain to zone Change-Id: Ic17dd814bc8fd19848bf936bd2ffebc7da1acf6c Signed-off-by: Dariusz Michaluk --- cli/command-line-interface.cpp | 38 +++--- cli/command-line-interface.hpp | 30 ++--- cli/main.cpp | 32 +++--- client/security-containers-client-impl.cpp | 46 ++++---- client/security-containers-client-impl.hpp | 60 +++++----- client/security-containers-client.cpp | 86 +++++++------- client/security-containers-client.h | 128 ++++++++++----------- common/ipc/internals/socket.cpp | 4 +- common/ipc/internals/socket.hpp | 2 +- common/lxc/domain.cpp | 92 +++++++-------- common/lxc/domain.hpp | 44 +++---- container-daemon/CMakeLists.txt | 6 +- .../org.tizen.containers.domain.daemon.conf.in | 14 --- .../org.tizen.containers.zone.daemon.conf.in | 14 +++ container-daemon/daemon-dbus-definitions.hpp | 6 +- container-support/CMakeLists.txt | 6 +- .../configs/org.tizen.containers.domain.conf.in | 14 --- .../configs/org.tizen.containers.zone.conf.in | 14 +++ packaging/security-containers.spec | 4 +- server/container-admin.cpp | 10 +- server/container-admin.hpp | 2 +- server/container-config.hpp | 2 +- server/container-dbus-definitions.hpp | 6 +- server/host-connection.hpp | 2 +- tests/integration_tests/common/sc_test_utils.py | 2 +- .../image_tests/config_checker.py | 2 +- tests/integration_tests/image_tests/image_tests.py | 2 +- tests/unit_tests/client/ut-client.cpp | 12 +- tests/unit_tests/lxc/ut-domain.cpp | 82 ++++++------- 29 files changed, 381 insertions(+), 381 deletions(-) delete mode 100644 container-daemon/configs/org.tizen.containers.domain.daemon.conf.in create mode 100644 container-daemon/configs/org.tizen.containers.zone.daemon.conf.in delete mode 100644 container-support/configs/org.tizen.containers.domain.conf.in create mode 100644 container-support/configs/org.tizen.containers.zone.conf.in diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index b46871d..cf9c71a 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -81,7 +81,7 @@ finish: } } -ostream& operator<<(ostream& out, const VsmDomainState& state) +ostream& operator<<(ostream& out, const VsmZoneState& state) { const char* name; switch (state) { @@ -103,12 +103,12 @@ ostream& operator<<(ostream& out, const VsmDomainState& state) return out; } -ostream& operator<<(ostream& out, const VsmDomain& domain) +ostream& operator<<(ostream& out, const VsmZone& zone) { - out << "Name: " << domain->id - << "\nTerminal: " << domain->terminal - << "\nState: " << domain->state - << "\nRoot: " << domain->rootfs_path; + out << "Name: " << zone->id + << "\nTerminal: " << zone->terminal + << "\nState: " << zone->state + << "\nRoot: " << zone->rootfs_path; return out; } @@ -143,7 +143,7 @@ void set_active_container(int pos, int argc, const char** argv) one_shot(bind(vsm_set_active_container, _1, argv[pos + 1])); } -void create_domain(int pos, int argc, const char** argv) +void create_zone(int pos, int argc, const char** argv) { using namespace std::placeholders; @@ -151,10 +151,10 @@ void create_domain(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(vsm_create_domain, _1, argv[pos + 1], nullptr)); + one_shot(bind(vsm_create_zone, _1, argv[pos + 1], nullptr)); } -void destroy_domain(int pos, int argc, const char** argv) +void destroy_zone(int pos, int argc, const char** argv) { using namespace std::placeholders; @@ -162,10 +162,10 @@ void destroy_domain(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(vsm_destroy_domain, _1, argv[pos + 1], 1)); + one_shot(bind(vsm_destroy_zone, _1, argv[pos + 1], 1)); } -void lock_domain(int pos, int argc, const char** argv) +void lock_zone(int pos, int argc, const char** argv) { using namespace std::placeholders; @@ -173,10 +173,10 @@ void lock_domain(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(vsm_lock_domain, _1, argv[pos + 1])); + one_shot(bind(vsm_lock_zone, _1, argv[pos + 1])); } -void unlock_domain(int pos, int argc, const char** argv) +void unlock_zone(int pos, int argc, const char** argv) { using namespace std::placeholders; @@ -184,20 +184,20 @@ void unlock_domain(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(vsm_unlock_domain, _1, argv[pos + 1])); + one_shot(bind(vsm_unlock_zone, _1, argv[pos + 1])); } -void lookup_domain_by_id(int pos, int argc, const char** argv) +void lookup_zone_by_id(int pos, int argc, const char** argv) { using namespace std::placeholders; if (argc <= pos + 1) { throw runtime_error("Not enough parameters"); } - VsmDomain domain; - one_shot(bind(vsm_lookup_domain_by_id, _1, argv[pos + 1], &domain)); - cout << domain << endl; - vsm_domain_free(domain); + VsmZone zone; + one_shot(bind(vsm_lookup_zone_by_id, _1, argv[pos + 1], &zone)); + cout << zone << endl; + vsm_zone_free(zone); } } // namespace cli diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index 360f46c..3239a00 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -104,39 +104,39 @@ private: void set_active_container(int pos, int argc, const char** argv); /** - * Parses command line arguments and call vsm_create_domain + * Parses command line arguments and call vsm_create_zone * - * @see vsm_create_domain + * @see vsm_create_zone */ -void create_domain(int pos, int argc, const char** argv); +void create_zone(int pos, int argc, const char** argv); /** - * Parses command line arguments and call vsm_destroy_domain + * Parses command line arguments and call vsm_destroy_zone * - * @see vsm_destroy_domain + * @see vsm_destroy_zone */ -void destroy_domain(int pos, int argc, const char** argv); +void destroy_zone(int pos, int argc, const char** argv); /** - * Parses command line arguments and call vsm_lock_domain + * Parses command line arguments and call vsm_lock_zone * - * @see vsm_lock_domain + * @see vsm_lock_zone */ -void lock_domain(int pos, int argc, const char** argv); +void lock_zone(int pos, int argc, const char** argv); /** - * Parses command line arguments and call vsm_unlock_domain + * Parses command line arguments and call vsm_unlock_zone * - * @see vsm_unlock_domain + * @see vsm_unlock_zone */ -void unlock_domain(int pos, int argc, const char** argv); +void unlock_zone(int pos, int argc, const char** argv); /** - * Parses command line arguments and call vsm_lookup_domain_by_id + * Parses command line arguments and call vsm_lookup_zone_by_id * - * @see vsm_lookup_domain_by_id + * @see vsm_lookup_zone_by_id */ -void lookup_domain_by_id(int pos, int argc, const char** argv); +void lookup_zone_by_id(int pos, int argc, const char** argv); } // namespace cli diff --git a/cli/main.cpp b/cli/main.cpp index 0ceb1e5..c7ad2e6 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -42,42 +42,42 @@ std::map commands = { } }, { - "create_domain", { - create_domain, - "create_domain container_id", + "create_zone", { + create_zone, + "create_zone container_id", "Create and add container", {{"container_id", "id container name"}} } }, { - "destroy_domain", { - destroy_domain, - "destroy_domain container_id", + "destroy_zone", { + destroy_zone, + "destroy_zone container_id", "Destroy container", {{"container_id", "id container name"}} } }, { - "lock_domain", { - lock_domain, - "lock_domain container_id", + "lock_zone", { + lock_zone, + "lock_zone container_id", "Lock container", {{"container_id", "id container name"}} } }, { - "unlock_domain", { - unlock_domain, - "unlock_domain container_id", + "unlock_zone", { + unlock_zone, + "unlock_zone container_id", "Unlock container", {{"container_id", "id container name"}} } }, { - "lookup_domain_by_id", { - lookup_domain_by_id, - "lookup_domain_by_id container_id", - "Prints informations about domain", + "lookup_zone_by_id", { + lookup_zone_by_id, + "lookup_zone_by_id container_id", + "Prints informations about zone", {{"container_id", "id container name"}} } } diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index aa8a796..f96cbcc 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -88,7 +88,7 @@ void toBasic(GVariant* in, char** str) *str = buf; } -VsmDomainState getDomainState(const char* state) +VsmZoneState getZoneState(const char* state) { if (strcmp(state, "STOPPED") == 0) { return STOPPED; @@ -114,22 +114,22 @@ VsmDomainState getDomainState(const char* state) return ACTIVATING; } assert(!"UNKNOWN STATE"); - return (VsmDomainState)-1; + return (VsmZoneState)-1; } -void toBasic(GVariant* in, VsmDomain* domain) +void toBasic(GVariant* in, VsmZone* zone) { const char* id; const char* path; const char* state; int terminal; - VsmDomain vsmDomain = (VsmDomain)malloc(sizeof(*vsmDomain)); + VsmZone vsmZone = (VsmZone)malloc(sizeof(*vsmZone)); g_variant_get(in, "(siss)", &id, &terminal, &state, &path); - vsmDomain->id = strdup(id); - vsmDomain->terminal = terminal; - vsmDomain->state = getDomainState(state); - vsmDomain->rootfs_path = strdup(path); - *domain = vsmDomain; + vsmZone->id = strdup(id); + vsmZone->terminal = terminal; + vsmZone->state = getZoneState(state); + vsmZone->rootfs_path = strdup(path); + *zone = vsmZone; } template @@ -339,7 +339,7 @@ VsmStatus Client::vsm_get_container_dbuses(VsmArrayString* keys, VsmArrayString* return ret; } -VsmStatus Client::vsm_get_domain_ids(VsmArrayString* array) noexcept +VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept { assert(array); @@ -381,7 +381,7 @@ VsmStatus Client::vsm_get_active_container_id(VsmString* id) noexcept return ret; } -VsmStatus Client::vsm_lookup_domain_by_pid(int pid, VsmString* id) noexcept +VsmStatus Client::vsm_lookup_zone_by_pid(int pid, VsmString* id) noexcept { assert(id); @@ -404,10 +404,10 @@ VsmStatus Client::vsm_lookup_domain_by_pid(int pid, VsmString* id) noexcept return vsm_get_status(); } -VsmStatus Client::vsm_lookup_domain_by_id(const char* id, VsmDomain* domain) noexcept +VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept { assert(id); - assert(domain); + assert(zone); GVariant* out; GVariant* args_in = g_variant_new("(s)", id); @@ -421,13 +421,13 @@ VsmStatus Client::vsm_lookup_domain_by_id(const char* id, VsmDomain* domain) noe } GVariant* unpacked; g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, domain); + toBasic(unpacked, zone); g_variant_unref(unpacked); g_variant_unref(out); return ret; } -VsmStatus Client::vsm_lookup_domain_by_terminal_id(int, VsmString*) noexcept +VsmStatus Client::vsm_lookup_zone_by_terminal_id(int, VsmString*) noexcept { mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); return vsm_get_status(); @@ -441,7 +441,7 @@ VsmStatus Client::vsm_set_active_container(const char* id) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); } -VsmStatus Client::vsm_create_domain(const char* id, const char* tname) noexcept +VsmStatus Client::vsm_create_zone(const char* id, const char* tname) noexcept { assert(id); if (tname) { @@ -453,26 +453,26 @@ VsmStatus Client::vsm_create_domain(const char* id, const char* tname) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_CONTAINER, args_in); } -VsmStatus Client::vsm_destroy_domain(const char* id) noexcept +VsmStatus Client::vsm_destroy_zone(const char* id) noexcept { assert(id); GVariant* args_in = g_variant_new("(s)", id); return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_CONTAINER, args_in); } -VsmStatus Client::vsm_shutdown_domain(const char*) noexcept +VsmStatus Client::vsm_shutdown_zone(const char*) noexcept { mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); return vsm_get_status(); } -VsmStatus Client::vsm_start_domain(const char*) noexcept +VsmStatus Client::vsm_start_zone(const char*) noexcept { mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); return vsm_get_status(); } -VsmStatus Client::vsm_lock_domain(const char* id) noexcept +VsmStatus Client::vsm_lock_zone(const char* id) noexcept { assert(id); @@ -480,7 +480,7 @@ VsmStatus Client::vsm_lock_domain(const char* id) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_LOCK_CONTAINER, args_in); } -VsmStatus Client::vsm_unlock_domain(const char* id) noexcept +VsmStatus Client::vsm_unlock_zone(const char* id) noexcept { assert(id); @@ -513,7 +513,7 @@ VsmStatus Client::vsm_del_state_callback(VsmSubscriptionId subscriptionId) noexc return signalUnsubscribe(subscriptionId); } -VsmStatus Client::vsm_domain_grant_device(const char*, const char*, uint32_t) noexcept +VsmStatus Client::vsm_zone_grant_device(const char*, const char*, uint32_t) noexcept { mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); return vsm_get_status(); @@ -525,7 +525,7 @@ VsmStatus Client::vsm_revoke_device(const char*, const char*) noexcept return vsm_get_status(); } -VsmStatus Client::vsm_domain_get_netdevs(const char*, VsmArrayString*) noexcept +VsmStatus Client::vsm_zone_get_netdevs(const char*, VsmArrayString*) noexcept { mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); return vsm_get_status(); diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index 585716d..d4c3506 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -109,9 +109,9 @@ public: VsmStatus vsm_get_container_dbuses(VsmArrayString* keys, VsmArrayString* values) noexcept; /** - * @see ::vsm_get_domain_ids + * @see ::vsm_get_zone_ids */ - VsmStatus vsm_get_domain_ids(VsmArrayString* array) noexcept; + VsmStatus vsm_get_zone_ids(VsmArrayString* array) noexcept; /** * @see ::vsm_get_active_container_id @@ -119,19 +119,19 @@ public: VsmStatus vsm_get_active_container_id(VsmString* id) noexcept; /** - * @see ::vsm_lookup_domain_by_pid + * @see ::vsm_lookup_zone_by_pid */ - VsmStatus vsm_lookup_domain_by_pid(int pid, VsmString* id) noexcept; + VsmStatus vsm_lookup_zone_by_pid(int pid, VsmString* id) noexcept; /** - * @see ::vsm_lookup_domain_by_id + * @see ::vsm_lookup_zone_by_id */ - VsmStatus vsm_lookup_domain_by_id(const char* id, VsmDomain* domain) noexcept; + VsmStatus vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept; /** - * @see ::vsm_lookup_domain_by_terminal_id + * @see ::vsm_lookup_zone_by_terminal_id */ - VsmStatus vsm_lookup_domain_by_terminal_id(int terminal, VsmString* id) noexcept; + VsmStatus vsm_lookup_zone_by_terminal_id(int terminal, VsmString* id) noexcept; /** * @see ::vsm_set_active_container @@ -139,34 +139,34 @@ public: VsmStatus vsm_set_active_container(const char* id) noexcept; /** - * @see ::vsm_create_domain + * @see ::vsm_create_zone */ - VsmStatus vsm_create_domain(const char* id, const char* tname) noexcept; + VsmStatus vsm_create_zone(const char* id, const char* tname) noexcept; /** - * @see ::vsm_destroy_domain + * @see ::vsm_destroy_zone */ - VsmStatus vsm_destroy_domain(const char* id) noexcept; + VsmStatus vsm_destroy_zone(const char* id) noexcept; /** - * @see ::vsm_shutdown_domain + * @see ::vsm_shutdown_zone */ - VsmStatus vsm_shutdown_domain(const char* id) noexcept; + VsmStatus vsm_shutdown_zone(const char* id) noexcept; /** - * @see ::vsm_start_domain + * @see ::vsm_start_zone */ - VsmStatus vsm_start_domain(const char* id) noexcept; + VsmStatus vsm_start_zone(const char* id) noexcept; /** - * @see ::vsm_lock_domain + * @see ::vsm_lock_zone */ - VsmStatus vsm_lock_domain(const char* id) noexcept; + VsmStatus vsm_lock_zone(const char* id) noexcept; /** - * @see ::vsm_unlock_domain + * @see ::vsm_unlock_zone */ - VsmStatus vsm_unlock_domain(const char* id) noexcept; + VsmStatus vsm_unlock_zone(const char* id) noexcept; /** * @see ::vsm_add_state_callback @@ -183,7 +183,7 @@ public: /** * @see ::vsm_del_state_callback */ - VsmStatus vsm_domain_grant_device(const char* id, + VsmStatus vsm_zone_grant_device(const char* id, const char* device, uint32_t flags) noexcept; @@ -193,28 +193,28 @@ public: VsmStatus vsm_revoke_device(const char* id, const char* device) noexcept; /** - * @see ::vsm_domain_get_netdevs + * @see ::vsm_zone_get_netdevs */ - VsmStatus vsm_domain_get_netdevs(const char* domain, VsmArrayString* netdevIds) noexcept; + VsmStatus vsm_zone_get_netdevs(const char* zone, VsmArrayString* netdevIds) noexcept; /** * @see ::vsm_netdev_get_ipv4_addr */ - VsmStatus vsm_netdev_get_ipv4_addr(const char* domain, + VsmStatus vsm_netdev_get_ipv4_addr(const char* zone, const char* netdevId, struct in_addr *addr) noexcept; /** * @see ::vsm_netdev_get_ipv6_addr */ - VsmStatus vsm_netdev_get_ipv6_addr(const char* domain, + VsmStatus vsm_netdev_get_ipv6_addr(const char* zone, const char* netdevId, struct in6_addr *addr) noexcept; /** * @see ::vsm_netdev_set_ipv4_addr */ - VsmStatus vsm_netdev_set_ipv4_addr(const char* domain, + VsmStatus vsm_netdev_set_ipv4_addr(const char* zone, const char* netdevId, struct in_addr *addr, int prefix) noexcept; @@ -222,7 +222,7 @@ public: /** * @see ::vsm_netdev_set_ipv6_addr */ - VsmStatus vsm_netdev_set_ipv6_addr(const char* domain, + VsmStatus vsm_netdev_set_ipv6_addr(const char* zone, const char* netdevId, struct in6_addr *addr, int prefix) noexcept; @@ -230,7 +230,7 @@ public: /** * @see ::vsm_create_netdev */ - VsmStatus vsm_create_netdev(const char* domain, + VsmStatus vsm_create_netdev(const char* zone, VsmNetdevType netdevType, const char* target, const char* netdevId) noexcept; @@ -238,12 +238,12 @@ public: /** * @see ::vsm_destroy_netdev */ - VsmStatus vsm_destroy_netdev(const char* domain, const char* netdevId) noexcept; + VsmStatus vsm_destroy_netdev(const char* zone, const char* netdevId) noexcept; /** * @see ::vsm_lookup_netdev_by_name */ - VsmStatus vsm_lookup_netdev_by_name(const char* domain, + VsmStatus vsm_lookup_netdev_by_name(const char* zone, const char* netdevId, VsmNetdev* netdev) noexcept; diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index 3ebede0..054113e 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -88,11 +88,11 @@ API void vsm_string_free(VsmString string) free(string); } -API void vsm_domain_free(VsmDomain domain) +API void vsm_zone_free(VsmZone zone) { - free(domain->rootfs_path); - free(domain->id); - free(domain); + free(zone->rootfs_path); + free(zone->id); + free(zone); } API void vsm_netdev_free(VsmNetdev netdev) @@ -123,9 +123,9 @@ API VsmStatus vsm_get_container_dbuses(VsmClient client, VsmArrayString* keys, V return getClient(client).vsm_get_container_dbuses(keys, values); } -API VsmStatus vsm_get_domain_ids(VsmClient client, VsmArrayString* array) +API VsmStatus vsm_get_zone_ids(VsmClient client, VsmArrayString* array) { - return getClient(client).vsm_get_domain_ids(array); + return getClient(client).vsm_get_zone_ids(array); } API VsmStatus vsm_get_active_container_id(VsmClient client, VsmString* id) @@ -133,19 +133,19 @@ API VsmStatus vsm_get_active_container_id(VsmClient client, VsmString* id) return getClient(client).vsm_get_active_container_id(id); } -API VsmStatus vsm_lookup_domain_by_pid(VsmClient client, int pid, VsmString* id) +API VsmStatus vsm_lookup_zone_by_pid(VsmClient client, int pid, VsmString* id) { - return getClient(client).vsm_lookup_domain_by_pid(pid, id); + return getClient(client).vsm_lookup_zone_by_pid(pid, id); } -API VsmStatus vsm_lookup_domain_by_id(VsmClient client, const char* id, VsmDomain* domain) +API VsmStatus vsm_lookup_zone_by_id(VsmClient client, const char* id, VsmZone* zone) { - return getClient(client).vsm_lookup_domain_by_id(id, domain); + return getClient(client).vsm_lookup_zone_by_id(id, zone); } -API VsmStatus vsm_lookup_domain_by_terminal_id(VsmClient client, int terminal, VsmString* id) +API VsmStatus vsm_lookup_zone_by_terminal_id(VsmClient client, int terminal, VsmString* id) { - return getClient(client).vsm_lookup_domain_by_terminal_id(terminal, id); + return getClient(client).vsm_lookup_zone_by_terminal_id(terminal, id); } API VsmStatus vsm_set_active_container(VsmClient client, const char* id) @@ -153,34 +153,34 @@ API VsmStatus vsm_set_active_container(VsmClient client, const char* id) return getClient(client).vsm_set_active_container(id); } -API VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tname) +API VsmStatus vsm_create_zone(VsmClient client, const char* id, const char* tname) { - return getClient(client).vsm_create_domain(id, tname); + return getClient(client).vsm_create_zone(id, tname); } -API VsmStatus vsm_destroy_domain(VsmClient client, const char* id, int /*force*/) +API VsmStatus vsm_destroy_zone(VsmClient client, const char* id, int /*force*/) { - return getClient(client).vsm_destroy_domain(id); + return getClient(client).vsm_destroy_zone(id); } -API VsmStatus vsm_shutdown_domain(VsmClient client, const char* id) +API VsmStatus vsm_shutdown_zone(VsmClient client, const char* id) { - return getClient(client).vsm_shutdown_domain(id); + return getClient(client).vsm_shutdown_zone(id); } -API VsmStatus vsm_start_domain(VsmClient client, const char* id) +API VsmStatus vsm_start_zone(VsmClient client, const char* id) { - return getClient(client).vsm_start_domain(id); + return getClient(client).vsm_start_zone(id); } -API VsmStatus vsm_lock_domain(VsmClient client, const char* id) +API VsmStatus vsm_lock_zone(VsmClient client, const char* id) { - return getClient(client).vsm_lock_domain(id); + return getClient(client).vsm_lock_zone(id); } -API VsmStatus vsm_unlock_domain(VsmClient client, const char* id) +API VsmStatus vsm_unlock_zone(VsmClient client, const char* id) { - return getClient(client).vsm_unlock_domain(id); + return getClient(client).vsm_unlock_zone(id); } API VsmStatus vsm_add_state_callback(VsmClient client, @@ -196,12 +196,12 @@ API VsmStatus vsm_del_state_callback(VsmClient client, VsmSubscriptionId subscri return getClient(client).vsm_del_state_callback(subscriptionId); } -API VsmStatus vsm_domain_grant_device(VsmClient client, +API VsmStatus vsm_zone_grant_device(VsmClient client, const char* id, const char* device, uint32_t flags) { - return getClient(client).vsm_domain_grant_device(id, device, flags); + return getClient(client).vsm_zone_grant_device(id, device, flags); } API VsmStatus vsm_revoke_device(VsmClient client, const char* id, const char* device) @@ -209,67 +209,67 @@ API VsmStatus vsm_revoke_device(VsmClient client, const char* id, const char* de return getClient(client).vsm_revoke_device(id, device); } -API VsmStatus vsm_domain_get_netdevs(VsmClient client, - const char* domain, +API VsmStatus vsm_zone_get_netdevs(VsmClient client, + const char* zone, VsmArrayString* netdevIds) { - return getClient(client).vsm_domain_get_netdevs(domain, netdevIds); + return getClient(client).vsm_zone_get_netdevs(zone, netdevIds); } API VsmStatus vsm_netdev_get_ipv4_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in_addr *addr) { - return getClient(client).vsm_netdev_get_ipv4_addr(domain, netdevId, addr); + return getClient(client).vsm_netdev_get_ipv4_addr(zone, netdevId, addr); } API VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in6_addr *addr) { - return getClient(client).vsm_netdev_get_ipv6_addr(domain, netdevId, addr); + return getClient(client).vsm_netdev_get_ipv6_addr(zone, netdevId, addr); } API VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in_addr *addr, int prefix) { - return getClient(client).vsm_netdev_set_ipv4_addr(domain, netdevId, addr, prefix); + return getClient(client).vsm_netdev_set_ipv4_addr(zone, netdevId, addr, prefix); } API VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in6_addr *addr, int prefix) { - return getClient(client).vsm_netdev_set_ipv6_addr(domain, netdevId, addr, prefix); + return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix); } API VsmStatus vsm_create_netdev(VsmClient client, - const char* domain, + const char* zone, VsmNetdevType netdevType, const char* target, const char* netdevId) { - return getClient(client).vsm_create_netdev(domain, netdevType, target, netdevId); + return getClient(client).vsm_create_netdev(zone, netdevType, target, netdevId); } -API VsmStatus vsm_destroy_netdev(VsmClient client, const char* domain, const char* netdevId) +API VsmStatus vsm_destroy_netdev(VsmClient client, const char* zone, const char* netdevId) { - return getClient(client).vsm_destroy_netdev(domain, netdevId); + return getClient(client).vsm_destroy_netdev(zone, netdevId); } API VsmStatus vsm_lookup_netdev_by_name(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, VsmNetdev* netdev) { - return getClient(client).vsm_lookup_netdev_by_name(domain, netdevId, netdev); + return getClient(client).vsm_lookup_netdev_by_name(zone, netdevId, netdev); } API VsmStatus vsm_declare_file(VsmClient client, diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 2e4d96b..bafa35c 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -54,7 +54,7 @@ int main(int argc, char** argv) goto finish; } - status = vsm_get_domain_ids(client, &values); + status = vsm_get_zone_ids(client, &values); if (VSMCLIENT_SUCCESS != status) { // error! ret = 1; @@ -123,7 +123,7 @@ typedef enum { typedef unsigned int VsmSubscriptionId; /** - * States of domain + * States of zone */ typedef enum { STOPPED, @@ -137,22 +137,22 @@ typedef enum { LOCKED, MAX_STATE, ACTIVATING = 128 -} VsmDomainState; +} VsmZoneState; /** - * Domain information structure + * Zone information structure */ typedef struct { char* id; int terminal; - VsmDomainState state; + VsmZoneState state; char *rootfs_path; -} VsmDomainStructure; +} VsmZoneStructure; /** - * Domain information + * Zone information */ -typedef VsmDomainStructure* VsmDomain; +typedef VsmZoneStructure* VsmZone; /** * Netowrk device type @@ -266,11 +266,11 @@ void vsm_array_string_free(VsmArrayString astring); void vsm_string_free(VsmString string); /** - * Release VsmDomain + * Release VsmZone * - * @param domain VsmDomain + * @param zone VsmZone */ -void vsm_domain_free(VsmDomain domain); +void vsm_zone_free(VsmZone zone); /** * Release VsmNetdev @@ -318,7 +318,7 @@ VsmStatus vsm_get_container_dbuses(VsmClient client, VsmArrayString* keys, VsmAr * @return status of this function call * @remark Use vsm_array_string_free() to free memory occupied by @p array. */ -VsmStatus vsm_get_domain_ids(VsmClient client, VsmArrayString* array); +VsmStatus vsm_get_zone_ids(VsmClient client, VsmArrayString* array); /** * Get active (foreground) container name. @@ -339,29 +339,29 @@ VsmStatus vsm_get_active_container_id(VsmClient client, VsmString* id); * @return status of this function call * @remark Use @p vsm_string_free() to free memory occupied by @p id. */ -VsmStatus vsm_lookup_domain_by_pid(VsmClient client, int pid, VsmString* id); +VsmStatus vsm_lookup_zone_by_pid(VsmClient client, int pid, VsmString* id); /** - * Get domain informations of domain with given id. + * Get zone informations of zone with given id. * * @param[in] client security-containers-server's client - * @param[in] id domain name - * @param[out] domain domain informations + * @param[in] id zone name + * @param[out] zone zone informations * @return status of this function call - * @remark Use @p vsm_domain_free() to free memory occupied by @p domain + * @remark Use @p vsm_zone_free() to free memory occupied by @p zone */ -VsmStatus vsm_lookup_domain_by_id(VsmClient client, const char* id, VsmDomain* domain); +VsmStatus vsm_lookup_zone_by_id(VsmClient client, const char* id, VsmZone* zone); /** - * Get domain name with given terminal. + * Get zone name with given terminal. * * @param[in] client security-containers-server's client * @param[in] terminal terminal id - * @param[out] id domain name with given terminal + * @param[out] id zone name with given terminal * @return status of this function call * @remark Use @p vsm_string_free() to free memory occupied by @p id. */ -VsmStatus vsm_lookup_domain_by_terminal_id(VsmClient client, int terminal, VsmString* id); +VsmStatus vsm_lookup_zone_by_terminal_id(VsmClient client, int terminal, VsmString* id); /** * Set active (foreground) container. @@ -380,53 +380,53 @@ VsmStatus vsm_set_active_container(VsmClient client, const char* id); * @param[in] tname template name, NULL for default * @return status of this function call */ -VsmStatus vsm_create_domain(VsmClient client, const char* id, const char* tname); +VsmStatus vsm_create_zone(VsmClient client, const char* id, const char* tname); /** - * Remove domain + * Remove zone * * @param[in] client security-containers-server's client * @param[in] id container id * @param[in] force if 0 data will be kept, otherwise data will be lost * @return status of this function call */ -VsmStatus vsm_destroy_domain(VsmClient clent, const char* id, int force); +VsmStatus vsm_destroy_zone(VsmClient clent, const char* id, int force); /** - * Shutdown domain + * Shutdown zone * * @param[in] client security-containers-server's client - * @param[in] id domain name + * @param[in] id zone name * @return status of this function call */ -VsmStatus vsm_shutdown_domain(VsmClient client, const char* id); +VsmStatus vsm_shutdown_zone(VsmClient client, const char* id); /** - * Start domain + * Start zone * * @param[in] client security-containers-server's client - * @param[in] id domain name + * @param[in] id zone name * @return status of this function call */ -VsmStatus vsm_start_domain(VsmClient client, const char* id); +VsmStatus vsm_start_zone(VsmClient client, const char* id); /** - * Lock domain + * Lock zone * * @param[in] client security-containers-server's client - * @param[in] id domain name + * @param[in] id zone name * @return status of this function call */ -VsmStatus vsm_lock_domain(VsmClient client, const char* id); +VsmStatus vsm_lock_zone(VsmClient client, const char* id); /** - * Unlock domain + * Unlock zone * * @param[in] client security-containers-server's client - * @param[in] id domain name + * @param[in] id zone name * @return status of this function call */ -VsmStatus vsm_unlock_domain(VsmClient client, const char* id); +VsmStatus vsm_unlock_zone(VsmClient client, const char* id); /** * Register dbus state change callback function. @@ -458,13 +458,13 @@ VsmStatus vsm_del_state_callback(VsmClient client, VsmSubscriptionId subscriptio * Grant access to device * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] device device path * @param[in] flags access flags * @return status of this function call */ -VsmStatus vsm_domain_grant_device(VsmClient client, - const char* domain, +VsmStatus vsm_zone_grant_device(VsmClient client, + const char* zone, const char* device, uint32_t flags); @@ -472,34 +472,34 @@ VsmStatus vsm_domain_grant_device(VsmClient client, * Revoke access to device * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] device device path * @return status of this function call */ -VsmStatus vsm_revoke_device(VsmClient client, const char* domain, const char* device); +VsmStatus vsm_revoke_device(VsmClient client, const char* zone, const char* device); /** - * Get array of netdev from given domain + * Get array of netdev from given zone * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[out] netdevIds array of netdev id * @return status of this function call * @remark Use vsm_array_string_free() to free memory occupied by @p netdevIds. */ -VsmStatus vsm_domain_get_netdevs(VsmClient client, const char* domain, VsmArrayString* netdevIds); +VsmStatus vsm_zone_get_netdevs(VsmClient client, const char* zone, VsmArrayString* netdevIds); /** * Get ipv4 address for given netdevId * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId netdev id * @param[out] addr ipv4 address * @return status of this function call */ VsmStatus vsm_netdev_get_ipv4_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in_addr *addr); @@ -507,13 +507,13 @@ VsmStatus vsm_netdev_get_ipv4_addr(VsmClient client, * Get ipv6 address for given netdevId * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId netdev id * @param[out] addr ipv6 address * @return status of this function call */ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in6_addr *addr); @@ -521,14 +521,14 @@ VsmStatus vsm_netdev_get_ipv6_addr(VsmClient client, * Set ipv4 address for given netdevId * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId netdev id * @param[in] addr ipv4 address * @param[in] prefix bit-length of the network prefix * @return status of this function call */ VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in_addr *addr, int prefix); @@ -537,56 +537,56 @@ VsmStatus vsm_netdev_set_ipv4_addr(VsmClient client, * Set ipv6 address for given netdevId * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId netdev id * @param[in] addr ipv6 address * @param[in] prefix bit-length of the network prefix * @return status of this function call */ VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, struct in6_addr *addr, int prefix); /** - * Create netdev in domain + * Create netdev in zone * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevType netdev type - * @param[in] target TODO: this is taken form domain-control + * @param[in] target TODO: this is taken form zone-control * @param[in] netdevId network device id * @return status of this function call */ VsmStatus vsm_create_netdev(VsmClient client, - const char* domain, + const char* zone, VsmNetdevType netdevType, const char* target, const char* netdevId); /** - * Remove netdev from domain + * Remove netdev from zone * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId network device id * @return status of this function call */ -VsmStatus vsm_destroy_netdev(VsmClient client, const char* domain, const char* netdevId); +VsmStatus vsm_destroy_netdev(VsmClient client, const char* zone, const char* netdevId); /** * Get netdev informations * * @param[in] client security-containers-server's client - * @param[in] domain domain name + * @param[in] zone zone name * @param[in] netdevId network device id * @param[out] netdev netdev informations * @return status of this function call * @remark Use vsm_netdev_free() to free memory occupied by @p netdev. */ VsmStatus vsm_lookup_netdev_by_name(VsmClient client, - const char* domain, + const char* zone, const char* netdevId, VsmNetdev* netdev); @@ -657,9 +657,9 @@ VsmStatus vsm_declare_link(VsmClient client, /** - * @name Domain API + * @name Zone API * - * Functions using org.tizen.containers.domain.manager D-Bus interface. + * Functions using org.tizen.containers.zone.manager D-Bus interface. * * @{ */ @@ -722,7 +722,7 @@ VsmStatus vsm_add_notification_callback(VsmClient client, */ VsmStatus vsm_del_notification_callback(VsmClient client, VsmSubscriptionId subscriptionId); -/** @} */ // Domain API +/** @} */ // Zone API #ifdef __cplusplus } diff --git a/common/ipc/internals/socket.cpp b/common/ipc/internals/socket.cpp index 4ac977a..4db22fe 100644 --- a/common/ipc/internals/socket.cpp +++ b/common/ipc/internals/socket.cpp @@ -117,7 +117,7 @@ int Socket::getSystemdSocket(const std::string& path) return -1; } -int Socket::createDomainSocket(const std::string& path) +int Socket::createZoneSocket(const std::string& path) { // Isn't the path too long? if (path.size() >= sizeof(sockaddr_un::sun_path)) { @@ -162,7 +162,7 @@ Socket Socket::createSocket(const std::string& path) { // Initialize a socket int fd = getSystemdSocket(path); - fd = fd != -1 ? fd : createDomainSocket(path); + fd = fd != -1 ? fd : createZoneSocket(path); return Socket(fd); } diff --git a/common/ipc/internals/socket.hpp b/common/ipc/internals/socket.hpp index b7a6d40..717ba00 100644 --- a/common/ipc/internals/socket.hpp +++ b/common/ipc/internals/socket.hpp @@ -106,7 +106,7 @@ private: int mFD; mutable std::recursive_mutex mCommunicationMutex; - static int createDomainSocket(const std::string& path); + static int createZoneSocket(const std::string& path); static int getSystemdSocket(const std::string& path); }; diff --git a/common/lxc/domain.cpp b/common/lxc/domain.cpp index 24453a6..6df0317 100644 --- a/common/lxc/domain.cpp +++ b/common/lxc/domain.cpp @@ -19,7 +19,7 @@ /** * @file * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Lxc domain + * @brief Lxc zone */ // Define macro USE_EXEC if you are goind to use valgrind @@ -51,8 +51,8 @@ namespace security_containers { namespace lxc { namespace { -#define ITEM(X) {#X, LxcDomain::State::X}, - const std::map STATE_MAP = { +#define ITEM(X) {#X, LxcZone::State::X}, + const std::map STATE_MAP = { ITEM(STOPPED) ITEM(STARTING) ITEM(RUNNING) @@ -65,9 +65,9 @@ namespace { #undef ITEM } // namespace -std::string LxcDomain::toString(State state) +std::string LxcZone::toString(State state) { -#define CASE(X) case LxcDomain::State::X: return #X; +#define CASE(X) case LxcZone::State::X: return #X; switch (state) { CASE(STOPPED) CASE(STARTING) @@ -82,49 +82,49 @@ std::string LxcDomain::toString(State state) throw LxcException("Invalid state"); } -LxcDomain::LxcDomain(const std::string& lxcPath, const std::string& domainName) +LxcZone::LxcZone(const std::string& lxcPath, const std::string& zoneName) : mContainer(nullptr) { - mContainer = lxc_container_new(domainName.c_str(), lxcPath.c_str()); + mContainer = lxc_container_new(zoneName.c_str(), lxcPath.c_str()); if (!mContainer) { - LOGE("Could not initialize lxc domain " << domainName << " in path " << lxcPath); - throw LxcException("Could not initialize lxc domain"); + LOGE("Could not initialize lxc zone " << zoneName << " in path " << lxcPath); + throw LxcException("Could not initialize lxc zone"); } } -LxcDomain::~LxcDomain() +LxcZone::~LxcZone() { lxc_container_put(mContainer); } -std::string LxcDomain::getName() const +std::string LxcZone::getName() const { return mContainer->name; } -std::string LxcDomain::getConfigItem(const std::string& key) +std::string LxcZone::getConfigItem(const std::string& key) { char buffer[1024]; int len = mContainer->get_config_item(mContainer, key.c_str(), buffer, sizeof(buffer)); if (len < 0) { - LOGE("Key '" << key << "' not found in domain " << getName()); + LOGE("Key '" << key << "' not found in zone " << getName()); throw LxcException("Key not found"); } return buffer; } -bool LxcDomain::isDefined() +bool LxcZone::isDefined() { return mContainer->is_defined(mContainer); } -LxcDomain::State LxcDomain::getState() +LxcZone::State LxcZone::getState() { const std::string str = mContainer->state(mContainer); return STATE_MAP.at(str); } -bool LxcDomain::create(const std::string& templatePath, const char* const* argv) +bool LxcZone::create(const std::string& templatePath, const char* const* argv) { #ifdef USE_EXEC utils::CStringArrayBuilder args; @@ -138,7 +138,7 @@ bool LxcDomain::create(const std::string& templatePath, const char* const* argv) } if (!utils::executeAndWait("/usr/bin/lxc-create", args.c_array())) { - LOGE("Could not create domain " << getName()); + LOGE("Could not create zone " << getName()); return false; } @@ -149,23 +149,23 @@ bool LxcDomain::create(const std::string& templatePath, const char* const* argv) templatePath.c_str(), NULL, NULL, 0, const_cast(argv))) { - LOGE("Could not create domain " << getName()); + LOGE("Could not create zone " << getName()); return false; } return true; #endif } -bool LxcDomain::destroy() +bool LxcZone::destroy() { if (!mContainer->destroy(mContainer)) { - LOGE("Could not destroy domain " << getName()); + LOGE("Could not destroy zone " << getName()); return false; } return true; } -bool LxcDomain::start(const char* const* argv) +bool LxcZone::start(const char* const* argv) { #ifdef USE_EXEC if (mContainer->is_running(mContainer)) { @@ -185,7 +185,7 @@ bool LxcDomain::start(const char* const* argv) } if (!utils::executeAndWait("/usr/bin/lxc-start", args.c_array())) { - LOGE("Could not start domain " << getName()); + LOGE("Could not start zone " << getName()); return false; } @@ -193,7 +193,7 @@ bool LxcDomain::start(const char* const* argv) // we have to check status because lxc-start runs in daemonized mode if (!mContainer->is_running(mContainer)) { - LOGE("Could not start init in domain " << getName()); + LOGE("Could not start init in zone " << getName()); return false; } return true; @@ -203,43 +203,43 @@ bool LxcDomain::start(const char* const* argv) return false; } if (!mContainer->want_daemonize(mContainer, true)) { - LOGE("Could not configure domain " << getName()); + LOGE("Could not configure zone " << getName()); return false; } if (!mContainer->start(mContainer, false, const_cast(argv))) { - LOGE("Could not start domain " << getName()); + LOGE("Could not start zone " << getName()); return false; } return true; #endif } -bool LxcDomain::stop() +bool LxcZone::stop() { if (!mContainer->stop(mContainer)) { - LOGE("Could not stop domain " << getName()); + LOGE("Could not stop zone " << getName()); return false; } return true; } -bool LxcDomain::reboot() +bool LxcZone::reboot() { if (!mContainer->reboot(mContainer)) { - LOGE("Could not reboot domain " << getName()); + LOGE("Could not reboot zone " << getName()); return false; } return true; } -bool LxcDomain::shutdown(int timeout) +bool LxcZone::shutdown(int timeout) { State state = getState(); if (state == State::STOPPED) { return true; } if (state != State::RUNNING) { - LOGE("Could not gracefully shutdown domain " << getName()); + LOGE("Could not gracefully shutdown zone " << getName()); return false; } @@ -253,7 +253,7 @@ bool LxcDomain::shutdown(int timeout) .add("--nokill"); if (!utils::executeAndWait("/usr/bin/lxc-stop", args.c_array())) { - LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); + LOGE("Could not gracefully shutdown zone " << getName() << " in " << timeout << "s"); return false; } @@ -263,50 +263,50 @@ bool LxcDomain::shutdown(int timeout) // try shutdown by sending poweroff to init if (setRunLevel(utils::RUNLEVEL_POWEROFF)) { if (!waitForState(State::STOPPED, timeout)) { - LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); + LOGE("Could not gracefully shutdown zone " << getName() << " in " << timeout << "s"); return false; } return true; } - LOGW("SetRunLevel failed for domain " + getName()); + LOGW("SetRunLevel failed for zone " + getName()); // fallback for other inits like bash: lxc sends 'lxc.haltsignal' signal to init if (!mContainer->shutdown(mContainer, timeout)) { - LOGE("Could not gracefully shutdown domain " << getName() << " in " << timeout << "s"); + LOGE("Could not gracefully shutdown zone " << getName() << " in " << timeout << "s"); return false; } return true; #endif } -bool LxcDomain::freeze() +bool LxcZone::freeze() { if (!mContainer->freeze(mContainer)) { - LOGE("Could not freeze domain " << getName()); + LOGE("Could not freeze zone " << getName()); return false; } return true; } -bool LxcDomain::unfreeze() +bool LxcZone::unfreeze() { if (!mContainer->unfreeze(mContainer)) { - LOGE("Could not unfreeze domain " << getName()); + LOGE("Could not unfreeze zone " << getName()); return false; } return true; } -bool LxcDomain::waitForState(State state, int timeout) +bool LxcZone::waitForState(State state, int timeout) { if (!mContainer->wait(mContainer, toString(state).c_str(), timeout)) { - LOGD("Timeout while waiting for state " << toString(state) << " of domain " << getName()); + LOGD("Timeout while waiting for state " << toString(state) << " of zone " << getName()); return false; } return true; } -bool LxcDomain::setRunLevel(int runLevel) +bool LxcZone::setRunLevel(int runLevel) { auto callback = [](void* param) -> int { utils::RunLevel runLevel = *reinterpret_cast(param); @@ -326,13 +326,13 @@ bool LxcDomain::setRunLevel(int runLevel) return status == 0; } -void LxcDomain::refresh() +void LxcZone::refresh() { - //TODO Consider make LxcDomain state-less - std::string domainName = mContainer->name; + //TODO Consider make LxcZone state-less + std::string zoneName = mContainer->name; std::string lxcPath = mContainer->config_path; lxc_container_put(mContainer); - mContainer = lxc_container_new(domainName.c_str(), lxcPath.c_str()); + mContainer = lxc_container_new(zoneName.c_str(), lxcPath.c_str()); } diff --git a/common/lxc/domain.hpp b/common/lxc/domain.hpp index 3c45b85..55eecd8 100644 --- a/common/lxc/domain.hpp +++ b/common/lxc/domain.hpp @@ -19,7 +19,7 @@ /** * @file * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Lxc domain + * @brief Lxc zone */ #ifndef COMMON_LXC_DOMAIN_HPP @@ -37,7 +37,7 @@ namespace lxc { /** * A class wwapping lxc container */ -class LxcDomain { +class LxcZone { public: enum class State { STOPPED, @@ -51,18 +51,18 @@ public: }; /** - * LxcDomain constructor + * LxcZone constructor * @param lxcPath path where containers lives - * @param domainName name of domain + * @param zoneName name of zone */ - LxcDomain(const std::string& lxcPath, const std::string& domainName); - ~LxcDomain(); + LxcZone(const std::string& lxcPath, const std::string& zoneName); + ~LxcZone(); - LxcDomain(const LxcDomain&) = delete; - LxcDomain& operator=(const LxcDomain&) = delete; + LxcZone(const LxcZone&) = delete; + LxcZone& operator=(const LxcZone&) = delete; /** - * Get domain name + * Get zone name */ std::string getName() const; @@ -73,7 +73,7 @@ public: std::string getConfigItem(const std::string& key); /** - * Is domain defined (created)? + * Is zone defined (created)? */ bool isDefined(); @@ -83,57 +83,57 @@ public: static std::string toString(State state); /** - * Get domain state + * Get zone state */ State getState(); /** - * Wait till domain is in specified state + * Wait till zone is in specified state * @return false on timeout */ bool waitForState(State state, int timeout); /** - * Create domain - * @param templatePath template from which domain will be created + * Create zone + * @param templatePath template from which zone will be created * @param argv additional template arguments */ bool create(const std::string& templatePath, const char* const* argv); /** - * Destroy domain + * Destroy zone */ bool destroy(); /** - * Start domain + * Start zone * @param argv init process with arguments */ bool start(const char* const* argv); /** - * Immediate stop the domain - * It kills all processes within this domain + * Immediate stop the zone + * It kills all processes within this zone */ bool stop(); /** - * Reboot domain + * Reboot zone */ bool reboot(); /** - * Gracefully shutdown domain. + * Gracefully shutdown zone. */ bool shutdown(int timeout); /** - * Freeze (pause/lock) domain + * Freeze (pause/lock) zone */ bool freeze(); /** - * Unfreeze domain + * Unfreeze zone */ bool unfreeze(); private: diff --git a/container-daemon/CMakeLists.txt b/container-daemon/CMakeLists.txt index 769eb7f..d702c8e 100644 --- a/container-daemon/CMakeLists.txt +++ b/container-daemon/CMakeLists.txt @@ -42,8 +42,8 @@ TARGET_LINK_LIBRARIES(${CONTAINER_DAEMON_CODENAME} ${CONTAINER_DAEMON_DEPS_LIBRA ## Install ##################################################################### INSTALL(TARGETS ${CONTAINER_DAEMON_CODENAME} DESTINATION bin) -CONFIGURE_FILE(configs/org.tizen.containers.domain.daemon.conf.in - ${CMAKE_BINARY_DIR}/configs/org.tizen.containers.domain.daemon.conf) +CONFIGURE_FILE(configs/org.tizen.containers.zone.daemon.conf.in + ${CMAKE_BINARY_DIR}/configs/org.tizen.containers.zone.daemon.conf) -INSTALL(FILES ${CMAKE_BINARY_DIR}/configs/org.tizen.containers.domain.daemon.conf +INSTALL(FILES ${CMAKE_BINARY_DIR}/configs/org.tizen.containers.zone.daemon.conf DESTINATION /etc/dbus-1/system.d/) diff --git a/container-daemon/configs/org.tizen.containers.domain.daemon.conf.in b/container-daemon/configs/org.tizen.containers.domain.daemon.conf.in deleted file mode 100644 index e080a1d..0000000 --- a/container-daemon/configs/org.tizen.containers.domain.daemon.conf.in +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - diff --git a/container-daemon/configs/org.tizen.containers.zone.daemon.conf.in b/container-daemon/configs/org.tizen.containers.zone.daemon.conf.in new file mode 100644 index 0000000..efb60b2 --- /dev/null +++ b/container-daemon/configs/org.tizen.containers.zone.daemon.conf.in @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/container-daemon/daemon-dbus-definitions.hpp b/container-daemon/daemon-dbus-definitions.hpp index f18d87f..4580d39 100644 --- a/container-daemon/daemon-dbus-definitions.hpp +++ b/container-daemon/daemon-dbus-definitions.hpp @@ -32,9 +32,9 @@ namespace security_containers { namespace container_daemon { namespace api { -const std::string BUS_NAME = "org.tizen.containers.domain.daemon"; -const std::string OBJECT_PATH = "/org/tizen/containers/domain/daemon"; -const std::string INTERFACE = "org.tizen.containers.domain.daemon"; +const std::string BUS_NAME = "org.tizen.containers.zone.daemon"; +const std::string OBJECT_PATH = "/org/tizen/containers/zone/daemon"; +const std::string INTERFACE = "org.tizen.containers.zone.daemon"; const std::string METHOD_GAIN_FOCUS = "GainFocus"; const std::string METHOD_LOSE_FOCUS = "LoseFocus"; diff --git a/container-support/CMakeLists.txt b/container-support/CMakeLists.txt index 3b26157..79bdb9c 100644 --- a/container-support/CMakeLists.txt +++ b/container-support/CMakeLists.txt @@ -23,8 +23,8 @@ MESSAGE(STATUS "Generating makefile for the Container Support...") ## Install ##################################################################### -CONFIGURE_FILE(configs/org.tizen.containers.domain.conf.in - ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.containers.domain.conf) +CONFIGURE_FILE(configs/org.tizen.containers.zone.conf.in + ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.containers.zone.conf) -INSTALL(FILES ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.containers.domain.conf +INSTALL(FILES ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.containers.zone.conf DESTINATION /etc/dbus-1/system.d/) diff --git a/container-support/configs/org.tizen.containers.domain.conf.in b/container-support/configs/org.tizen.containers.domain.conf.in deleted file mode 100644 index 49da048..0000000 --- a/container-support/configs/org.tizen.containers.domain.conf.in +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - diff --git a/container-support/configs/org.tizen.containers.zone.conf.in b/container-support/configs/org.tizen.containers.zone.conf.in new file mode 100644 index 0000000..264e915 --- /dev/null +++ b/container-support/configs/org.tizen.containers.zone.conf.in @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index 3425c51..47833e4 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -163,7 +163,7 @@ Containers support installed inside every container. %files container-support %manifest packaging/security-containers-container-support.manifest %defattr(644,root,root,755) -/etc/dbus-1/system.d/org.tizen.containers.domain.conf +/etc/dbus-1/system.d/org.tizen.containers.zone.conf ## Container Daemon Package #################################################### @@ -180,7 +180,7 @@ Daemon running inside every container. %manifest packaging/security-containers-container-daemon.manifest %defattr(644,root,root,755) %attr(755,root,root) %{_bindir}/security-containers-container-daemon -/etc/dbus-1/system.d/org.tizen.containers.domain.daemon.conf +/etc/dbus-1/system.d/org.tizen.containers.zone.daemon.conf ## Command Line Interface ###################################################### diff --git a/server/container-admin.cpp b/server/container-admin.cpp index 1d8cdee..bd9f8f1 100644 --- a/server/container-admin.cpp +++ b/server/container-admin.cpp @@ -61,7 +61,7 @@ ContainerAdmin::ContainerAdmin(const std::string& containersPath, const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate, lxcTemplatePrefix); - LOGI(mId << ": Creating domain from template: " << lxcTemplate); + LOGI(mId << ": Creating zone from template: " << lxcTemplate); utils::CStringArrayBuilder args; if (!config.ipv4Gateway.empty()) { args.add("--ipv4-gateway"); @@ -72,7 +72,7 @@ ContainerAdmin::ContainerAdmin(const std::string& containersPath, args.add(config.ipv4.c_str()); } if (!mDom.create(lxcTemplate, args.c_array())) { - throw ContainerOperationException("Could not create domain"); + throw ContainerOperationException("Could not create zone"); } } } @@ -165,13 +165,13 @@ void ContainerAdmin::destroy() bool ContainerAdmin::isRunning() { - return mDom.getState() == lxc::LxcDomain::State::RUNNING; + return mDom.getState() == lxc::LxcZone::State::RUNNING; } bool ContainerAdmin::isStopped() { - return mDom.getState() == lxc::LxcDomain::State::STOPPED; + return mDom.getState() == lxc::LxcZone::State::STOPPED; } @@ -197,7 +197,7 @@ void ContainerAdmin::resume() bool ContainerAdmin::isPaused() { - return mDom.getState() == lxc::LxcDomain::State::FROZEN; + return mDom.getState() == lxc::LxcZone::State::FROZEN; } diff --git a/server/container-admin.hpp b/server/container-admin.hpp index f3c9a4f..67a8485 100644 --- a/server/container-admin.hpp +++ b/server/container-admin.hpp @@ -128,7 +128,7 @@ public: private: const ContainerConfig& mConfig; - lxc::LxcDomain mDom; + lxc::LxcZone mDom; const std::string mId; bool mDetachOnExit; bool mDestroyOnExit; diff --git a/server/container-config.hpp b/server/container-config.hpp index 779415d..c1ba2e9 100644 --- a/server/container-config.hpp +++ b/server/container-config.hpp @@ -81,7 +81,7 @@ struct ContainerConfig { /** * Specify, if D-Bus communication with the container will be enabled. - * Setting this value to "false" will make the domain API not work inside the container. + * Setting this value to "false" will make the zone API not work inside the container. */ bool enableDbusIntegration; diff --git a/server/container-dbus-definitions.hpp b/server/container-dbus-definitions.hpp index 0e280d4..d22c633 100644 --- a/server/container-dbus-definitions.hpp +++ b/server/container-dbus-definitions.hpp @@ -32,9 +32,9 @@ namespace security_containers { namespace api { namespace container { -const std::string BUS_NAME = "org.tizen.containers.domain"; -const std::string OBJECT_PATH = "/org/tizen/containers/domain"; -const std::string INTERFACE = "org.tizen.containers.domain.manager"; +const std::string BUS_NAME = "org.tizen.containers.zone"; +const std::string OBJECT_PATH = "/org/tizen/containers/zone"; +const std::string INTERFACE = "org.tizen.containers.zone.manager"; const std::string METHOD_NOTIFY_ACTIVE_CONTAINER = "NotifyActiveContainer"; const std::string METHOD_FILE_MOVE_REQUEST = "FileMoveRequest"; diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 0030efc..bbec909 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -112,7 +112,7 @@ public: void signalContainerDbusState(const std::string& containerId, const std::string& dbusAddress); /** - * Register a callback called to get a list of domain ids + * Register a callback called to get a list of zone ids */ void setGetContainerIdsCallback(const GetContainerIdsCallback& callback); diff --git a/tests/integration_tests/common/sc_test_utils.py b/tests/integration_tests/common/sc_test_utils.py index 4e77824..bb84f99 100644 --- a/tests/integration_tests/common/sc_test_utils.py +++ b/tests/integration_tests/common/sc_test_utils.py @@ -1,4 +1,4 @@ -'''! Module containing utilities for domain-tests +'''! Module containing utilities for zone-tests @author Lukasz Kostyra (l.kostyra@samsung.com) ''' diff --git a/tests/integration_tests/image_tests/config_checker.py b/tests/integration_tests/image_tests/config_checker.py index 6788bbe..4cc2d18 100644 --- a/tests/integration_tests/image_tests/config_checker.py +++ b/tests/integration_tests/image_tests/config_checker.py @@ -17,7 +17,7 @@ class ConfigChecker: def __parseLibvirtXML(self, path): '''! Parses libvirt's configuration in order to extract container name and path. - @param path Libvirt's domain configuration path + @param path Libvirt's zone configuration path ''' tree = ET.parse(path) root = tree.getroot() diff --git a/tests/integration_tests/image_tests/image_tests.py b/tests/integration_tests/image_tests/image_tests.py index 34e61cc6..a74c5ac 100644 --- a/tests/integration_tests/image_tests/image_tests.py +++ b/tests/integration_tests/image_tests/image_tests.py @@ -12,7 +12,7 @@ import xml.etree.ElementTree as ET SCS_USER_NAME = "security-containers" SCS_UID = 377 -DAEMON_DBUS_SOCKET_NAME = "org.tizen.containers.domain" +DAEMON_DBUS_SOCKET_NAME = "org.tizen.containers.zone" # dbus config file path relative to container's root DBUS_CONFIG_PATH = "etc/dbus-1/system.d/" + DAEMON_DBUS_SOCKET_NAME + ".conf" diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 61ed580..838f8bf 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(GetContainerIdsTest) VsmStatus status = vsm_connect(client); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); VsmArrayString values; - status = vsm_get_domain_ids(client, &values); + status = vsm_get_zone_ids(client, &values); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1), EXPECTED_DBUSES_STARTED.size()); @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(CreateContainerTest) VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - status = vsm_create_domain(client, newActiveContainerId.c_str(), NULL); + status = vsm_create_zone(client, newActiveContainerId.c_str(), NULL); BOOST_REQUIRE_EQUAL(VSMCLIENT_CUSTOM_ERROR, status); vsm_client_free(client); } @@ -232,9 +232,9 @@ BOOST_AUTO_TEST_CASE(LockUnlockContainerTest) VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - status = vsm_lock_domain(client, newActiveContainerId.c_str()); + status = vsm_lock_zone(client, newActiveContainerId.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - status = vsm_unlock_domain(client, newActiveContainerId.c_str()); + status = vsm_unlock_zone(client, newActiveContainerId.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); vsm_client_free(client); } @@ -313,7 +313,7 @@ BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest1) { VsmClient client = vsm_client_create(); VsmString container; - VsmStatus status = vsm_lookup_domain_by_pid(client, 1, &container); + VsmStatus status = vsm_lookup_zone_by_pid(client, 1, &container); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(container, std::string("host")); @@ -329,7 +329,7 @@ BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest2) VsmClient client = vsm_client_create(); for (int n = 0; n < 100000; ++n) { VsmString container; - VsmStatus status = vsm_lookup_domain_by_pid(client, n, &container); + VsmStatus status = vsm_lookup_zone_by_pid(client, n, &container); if (status == VSMCLIENT_SUCCESS) { ids.insert(container); vsm_string_free(container); diff --git a/tests/unit_tests/lxc/ut-domain.cpp b/tests/unit_tests/lxc/ut-domain.cpp index a9942b8..d618a11 100644 --- a/tests/unit_tests/lxc/ut-domain.cpp +++ b/tests/unit_tests/lxc/ut-domain.cpp @@ -20,7 +20,7 @@ /** * @file * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) - * @brief Unit tests of LxcDomain class + * @brief Unit tests of LxcZone class */ #include "config.hpp" @@ -40,7 +40,7 @@ using namespace security_containers; using namespace security_containers::lxc; const std::string LXC_PATH = "/tmp/ut-lxc/"; -const std::string DOMAIN_NAME = "ut-domain"; +const std::string ZONE_NAME = "ut-zone"; const std::string TEMPLATE = SC_TEST_LXC_TEMPLATES_INSTALL_DIR "/minimal.sh"; const char* TEMPLATE_ARGS[] = {NULL}; @@ -60,9 +60,9 @@ struct Fixture { void cleanup() { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); if (lxc.isDefined()) { - if (lxc.getState() != LxcDomain::State::STOPPED) { + if (lxc.getState() != LxcZone::State::STOPPED) { lxc.stop(); } lxc.destroy(); @@ -78,22 +78,22 @@ struct Fixture { } // namespace -BOOST_FIXTURE_TEST_SUITE(LxcDomainSuite, Fixture) +BOOST_FIXTURE_TEST_SUITE(LxcZoneSuite, Fixture) BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); } BOOST_AUTO_TEST_CASE(CreateDestroyTest) { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(!lxc.isDefined()); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); BOOST_CHECK(lxc.isDefined()); - BOOST_CHECK_EQUAL(lxc.getConfigItem("lxc.rootfs"), LXC_PATH + DOMAIN_NAME + "/rootfs"); + BOOST_CHECK_EQUAL(lxc.getConfigItem("lxc.rootfs"), LXC_PATH + ZONE_NAME + "/rootfs"); BOOST_CHECK_THROW(lxc.getConfigItem("xxx"), LxcException); BOOST_CHECK(lxc.destroy()); @@ -104,11 +104,11 @@ BOOST_AUTO_TEST_CASE(CreateDestroyTest) BOOST_AUTO_TEST_CASE(StartShutdownTest) { { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + LxcZone lxc(LXC_PATH, ZONE_NAME); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); const char* argv[] = { "/bin/sh", "-c", @@ -116,10 +116,10 @@ BOOST_AUTO_TEST_CASE(StartShutdownTest) NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); waitForInit(); BOOST_CHECK(lxc.shutdown(2)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); } @@ -127,21 +127,21 @@ BOOST_AUTO_TEST_CASE(StartShutdownTest) BOOST_AUTO_TEST_CASE(StartStopTest) { { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + LxcZone lxc(LXC_PATH, ZONE_NAME); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); const char* argv[] = { "/bin/sh", NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); BOOST_CHECK(!lxc.shutdown(1)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); BOOST_CHECK(lxc.stop()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); } @@ -149,11 +149,11 @@ BOOST_AUTO_TEST_CASE(StartStopTest) BOOST_AUTO_TEST_CASE(StartHasStoppedTest) { { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); } - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + LxcZone lxc(LXC_PATH, ZONE_NAME); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); const char* argv[] = { "/bin/sh", "-c", @@ -162,14 +162,14 @@ BOOST_AUTO_TEST_CASE(StartHasStoppedTest) }; BOOST_CHECK(lxc.start(argv)); waitForInit(); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); } BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); const char* argv[] = { "/bin/sh", @@ -178,21 +178,21 @@ BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); waitForInit(); BOOST_CHECK(lxc.freeze()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::FROZEN); + BOOST_CHECK(lxc.getState() == LxcZone::State::FROZEN); BOOST_CHECK(lxc.unfreeze()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); BOOST_CHECK(lxc.shutdown(2)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); } BOOST_AUTO_TEST_CASE(FreezeStopTest) { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); const char* argv[] = { "/bin/sh", @@ -201,21 +201,21 @@ BOOST_AUTO_TEST_CASE(FreezeStopTest) NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); waitForInit(); BOOST_CHECK(lxc.freeze()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::FROZEN); + BOOST_CHECK(lxc.getState() == LxcZone::State::FROZEN); BOOST_CHECK(!lxc.shutdown(1)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::FROZEN); + BOOST_CHECK(lxc.getState() == LxcZone::State::FROZEN); BOOST_CHECK(lxc.stop()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); } BOOST_AUTO_TEST_CASE(RepeatTest) { - LxcDomain lxc(LXC_PATH, DOMAIN_NAME); + LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); BOOST_CHECK(!lxc.create(TEMPLATE, TEMPLATE_ARGS));// forbidden const char* argv[] = { @@ -225,21 +225,21 @@ BOOST_AUTO_TEST_CASE(RepeatTest) NULL }; BOOST_CHECK(lxc.start(argv)); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); waitForInit(); BOOST_CHECK(!lxc.start(argv)); // forbidden BOOST_CHECK(lxc.freeze()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::FROZEN); + BOOST_CHECK(lxc.getState() == LxcZone::State::FROZEN); BOOST_CHECK(lxc.freeze()); // repeat is nop - BOOST_CHECK(lxc.getState() == LxcDomain::State::FROZEN); + BOOST_CHECK(lxc.getState() == LxcZone::State::FROZEN); BOOST_CHECK(lxc.unfreeze()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); BOOST_CHECK(lxc.unfreeze()); // repeat is nop - BOOST_CHECK(lxc.getState() == LxcDomain::State::RUNNING); + BOOST_CHECK(lxc.getState() == LxcZone::State::RUNNING); BOOST_CHECK(lxc.stop()); - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.stop()); // repeat is nop - BOOST_CHECK(lxc.getState() == LxcDomain::State::STOPPED); + BOOST_CHECK(lxc.getState() == LxcZone::State::STOPPED); BOOST_CHECK(lxc.destroy()); BOOST_CHECK(!lxc.isDefined()); -- 2.7.4