From 67c0aa5c4ea021326fd0d1565143543e29f468a2 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 24 Nov 2014 15:33:27 +0100 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 10/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 11/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 From 04037c5efb30168559c8193c5afae0fec799ee7a Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Thu, 4 Dec 2014 11:49:49 +0100 Subject: [PATCH 12/16] Rename domain to zone in files names Change-Id: If4e79cb41a4af6398ca27ba4c434554dbc090c16 Signed-off-by: Dariusz Michaluk --- common/lxc/{domain.cpp => zone.cpp} | 2 +- common/lxc/{domain.hpp => zone.hpp} | 6 +++--- server/container-admin.hpp | 2 +- tests/unit_tests/lxc/{ut-domain.cpp => ut-zone.cpp} | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename common/lxc/{domain.cpp => zone.cpp} (99%) rename common/lxc/{domain.hpp => zone.hpp} (97%) rename tests/unit_tests/lxc/{ut-domain.cpp => ut-zone.cpp} (99%) diff --git a/common/lxc/domain.cpp b/common/lxc/zone.cpp similarity index 99% rename from common/lxc/domain.cpp rename to common/lxc/zone.cpp index 6df0317..c7736f5 100644 --- a/common/lxc/domain.cpp +++ b/common/lxc/zone.cpp @@ -32,7 +32,7 @@ #include "config.hpp" #include "logger/logger.hpp" -#include "lxc/domain.hpp" +#include "lxc/zone.hpp" #include "lxc/exception.hpp" #ifdef USE_EXEC #include "utils/execute.hpp" diff --git a/common/lxc/domain.hpp b/common/lxc/zone.hpp similarity index 97% rename from common/lxc/domain.hpp rename to common/lxc/zone.hpp index 55eecd8..6ea5e3a 100644 --- a/common/lxc/domain.hpp +++ b/common/lxc/zone.hpp @@ -22,8 +22,8 @@ * @brief Lxc zone */ -#ifndef COMMON_LXC_DOMAIN_HPP -#define COMMON_LXC_DOMAIN_HPP +#ifndef COMMON_LXC_ZONE_HPP +#define COMMON_LXC_ZONE_HPP #include @@ -148,4 +148,4 @@ private: } // namespace security_containers -#endif // COMMON_LXC_DOMAIN_HPP +#endif // COMMON_LXC_ZONE_HPP diff --git a/server/container-admin.hpp b/server/container-admin.hpp index 67a8485..c40f30c 100644 --- a/server/container-admin.hpp +++ b/server/container-admin.hpp @@ -27,7 +27,7 @@ #define SERVER_CONTAINER_ADMIN_HPP #include "container-config.hpp" -#include "lxc/domain.hpp" +#include "lxc/zone.hpp" namespace security_containers { diff --git a/tests/unit_tests/lxc/ut-domain.cpp b/tests/unit_tests/lxc/ut-zone.cpp similarity index 99% rename from tests/unit_tests/lxc/ut-domain.cpp rename to tests/unit_tests/lxc/ut-zone.cpp index d618a11..bf8779d 100644 --- a/tests/unit_tests/lxc/ut-domain.cpp +++ b/tests/unit_tests/lxc/ut-zone.cpp @@ -26,7 +26,7 @@ #include "config.hpp" #include "ut.hpp" -#include "lxc/domain.hpp" +#include "lxc/zone.hpp" #include "lxc/exception.hpp" #include "utils/scoped-dir.hpp" -- 2.7.4 From 610fb48d7123e47db1ac23a02b0536ee209162a1 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Thu, 4 Dec 2014 13:03:24 +0100 Subject: [PATCH 13/16] Unit tests configs refactor [Bug/Feature] There was no possibility to test adding multiple zones using templates [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ie5ea1c2c2a227e0bb4ed9d02aa2965e5b2443f44 --- .../ut-client/containers/console1-dbus.conf.in | 4 +- .../ut-client/containers/console2-dbus.conf.in | 4 +- .../ut-client/containers/console3-dbus.conf.in | 4 +- tests/unit_tests/client/ut-client.cpp | 14 ++-- .../{minimal-dbus1.sh => minimal-dbus.sh} | 2 +- tests/unit_tests/lxc/templates/minimal-dbus2.sh | 76 ---------------------- tests/unit_tests/lxc/templates/minimal-dbus3.sh | 76 ---------------------- .../ut-container/containers/test-dbus.conf.in | 4 +- .../containers/console1-dbus.conf.in | 4 +- .../containers/console2-dbus.conf.in | 4 +- .../containers/console3-dbus.conf.in | 4 +- .../templates/template.conf.in | 4 +- tests/unit_tests/server/ut-container.cpp | 2 +- tests/unit_tests/server/ut-containers-manager.cpp | 18 ++--- 14 files changed, 30 insertions(+), 190 deletions(-) rename tests/unit_tests/lxc/templates/{minimal-dbus1.sh => minimal-dbus.sh} (95%) delete mode 100755 tests/unit_tests/lxc/templates/minimal-dbus2.sh delete mode 100755 tests/unit_tests/lxc/templates/minimal-dbus3.sh 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 bf8d1fc..267a812 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console1-dbus", - "lxcTemplate" : "minimal-dbus1.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run1", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console1-dbus", "permittedToSend" : [ "/tmp/.*", "/etc/secret2" ], "permittedToRecv" : [ "/tmp/.*" ] } 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 73ff1b3..f050525 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console2-dbus", - "lxcTemplate" : "minimal-dbus2.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run2", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console2-dbus", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ] } 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 c8a0a01..b78ac71 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console3-dbus", - "lxcTemplate" : "minimal-dbus3.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run3", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console3-dbus", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*" ] } diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 838f8bf..1240e51 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -63,17 +63,13 @@ struct Loop { struct Fixture { Loop loop; utils::ScopedDir mContainersPathGuard; - utils::ScopedDir mRun1Guard; - utils::ScopedDir mRun2Guard; - utils::ScopedDir mRun3Guard; + utils::ScopedDir mRunGuard; ContainersManager cm; Fixture() : mContainersPathGuard(CONTAINERS_PATH) - , mRun1Guard("/tmp/ut-run1") - , mRun2Guard("/tmp/ut-run2") - , mRun3Guard("/tmp/ut-run3") + , mRunGuard("/tmp/ut-run") , cm(TEST_DBUS_CONFIG_PATH) { cm.startAll(); @@ -84,15 +80,15 @@ const int EVENT_TIMEOUT = 5000; ///< ms const std::map EXPECTED_DBUSES_STARTED = { { "ut-containers-manager-console1-dbus", - "unix:path=/tmp/ut-run1/dbus/system_bus_socket" + "unix:path=/tmp/ut-run/ut-containers-manager-console1-dbus/dbus/system_bus_socket" }, { "ut-containers-manager-console2-dbus", - "unix:path=/tmp/ut-run2/dbus/system_bus_socket" + "unix:path=/tmp/ut-run/ut-containers-manager-console2-dbus/dbus/system_bus_socket" }, { "ut-containers-manager-console3-dbus", - "unix:path=/tmp/ut-run3/dbus/system_bus_socket" + "unix:path=/tmp/ut-run/ut-containers-manager-console3-dbus/dbus/system_bus_socket" } }; diff --git a/tests/unit_tests/lxc/templates/minimal-dbus1.sh b/tests/unit_tests/lxc/templates/minimal-dbus.sh similarity index 95% rename from tests/unit_tests/lxc/templates/minimal-dbus1.sh rename to tests/unit_tests/lxc/templates/minimal-dbus.sh index ff1f2de..82c76e8 100755 --- a/tests/unit_tests/lxc/templates/minimal-dbus1.sh +++ b/tests/unit_tests/lxc/templates/minimal-dbus.sh @@ -65,7 +65,7 @@ lxc.mount.entry = /lib lib none ro,bind 0 0 lxc.mount.entry = /sbin sbin none ro,bind 0 0 lxc.mount.entry = /usr usr none ro,rbind 0 0 lxc.mount.entry = /opt opt none ro,rbind 0 0 -lxc.mount.entry = /tmp/ut-run1 var/run none rw,bind 0 0 +lxc.mount.entry = /tmp/ut-run/${name} var/run none rw,bind 0 0 EOF if [ "$(uname -m)" = "x86_64" ]; then diff --git a/tests/unit_tests/lxc/templates/minimal-dbus2.sh b/tests/unit_tests/lxc/templates/minimal-dbus2.sh deleted file mode 100755 index 86984b7..0000000 --- a/tests/unit_tests/lxc/templates/minimal-dbus2.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -echo UnitTest 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 - -# Prepare container rootfs -ROOTFS_DIRS="\ -${rootfs}/bin \ -${rootfs}/dev \ -${rootfs}/dev/pts \ -${rootfs}/etc \ -${rootfs}/home \ -${rootfs}/lib \ -${rootfs}/lib64 \ -${rootfs}/proc \ -${rootfs}/root \ -${rootfs}/run \ -${rootfs}/sbin \ -${rootfs}/sys \ -${rootfs}/tmp \ -${rootfs}/usr \ -${rootfs}/opt \ -${rootfs}/var \ -${rootfs}/var/run -" -/bin/mkdir ${ROOTFS_DIRS} - -# 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.haltsignal = SIGTERM - -lxc.pts = 256 -lxc.tty = 0 - -lxc.cgroup.devices.deny = a - -lxc.mount.auto = proc sys cgroup -lxc.mount.entry = /bin bin none ro,bind 0 0 -lxc.mount.entry = /etc etc none ro,bind 0 0 -lxc.mount.entry = /lib lib none ro,bind 0 0 -lxc.mount.entry = /sbin sbin none ro,bind 0 0 -lxc.mount.entry = /usr usr none ro,rbind 0 0 -lxc.mount.entry = /opt opt none ro,rbind 0 0 -lxc.mount.entry = /tmp/ut-run2 var/run none rw,bind 0 0 -EOF - -if [ "$(uname -m)" = "x86_64" ]; then -cat <> $path/config -lxc.mount.entry = /lib64 lib64 none ro,bind 0 0 -EOF -fi - diff --git a/tests/unit_tests/lxc/templates/minimal-dbus3.sh b/tests/unit_tests/lxc/templates/minimal-dbus3.sh deleted file mode 100755 index 034b4fd..0000000 --- a/tests/unit_tests/lxc/templates/minimal-dbus3.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/bash - -echo UnitTest 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 - -# Prepare container rootfs -ROOTFS_DIRS="\ -${rootfs}/bin \ -${rootfs}/dev \ -${rootfs}/dev/pts \ -${rootfs}/etc \ -${rootfs}/home \ -${rootfs}/lib \ -${rootfs}/lib64 \ -${rootfs}/proc \ -${rootfs}/root \ -${rootfs}/run \ -${rootfs}/sbin \ -${rootfs}/sys \ -${rootfs}/tmp \ -${rootfs}/usr \ -${rootfs}/opt \ -${rootfs}/var \ -${rootfs}/var/run -" -/bin/mkdir ${ROOTFS_DIRS} - -# 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.haltsignal = SIGTERM - -lxc.pts = 256 -lxc.tty = 0 - -lxc.cgroup.devices.deny = a - -lxc.mount.auto = proc sys cgroup -lxc.mount.entry = /bin bin none ro,bind 0 0 -lxc.mount.entry = /etc etc none ro,bind 0 0 -lxc.mount.entry = /lib lib none ro,bind 0 0 -lxc.mount.entry = /sbin sbin none ro,bind 0 0 -lxc.mount.entry = /usr usr none ro,rbind 0 0 -lxc.mount.entry = /opt opt none ro,rbind 0 0 -lxc.mount.entry = /tmp/ut-run3 var/run none rw,bind 0 0 -EOF - -if [ "$(uname -m)" = "x86_64" ]; then -cat <> $path/config -lxc.mount.entry = /lib64 lib64 none ro,bind 0 0 -EOF -fi - 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 f8e60f6..ed9a976 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 @@ -1,6 +1,6 @@ { "name" : "ut-container-test-dbus", - "lxcTemplate" : "minimal-dbus1.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run1", + "runMountPoint" : "/tmp/ut-run/ut-container-test-dbus", "permittedToSend" : [], "permittedToRecv" : [] } 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 bf8d1fc..267a812 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console1-dbus", - "lxcTemplate" : "minimal-dbus1.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run1", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console1-dbus", "permittedToSend" : [ "/tmp/.*", "/etc/secret2" ], "permittedToRecv" : [ "/tmp/.*" ] } 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 73ff1b3..f050525 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console2-dbus", - "lxcTemplate" : "minimal-dbus2.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run2", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console2-dbus", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*", "/etc/secret1" ] } 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 c8a0a01..b78ac71 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 @@ -1,6 +1,6 @@ { "name" : "ut-containers-manager-console3-dbus", - "lxcTemplate" : "minimal-dbus3.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run3", + "runMountPoint" : "/tmp/ut-run/ut-containers-manager-console3-dbus", "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 index f01cfff..7c35446 100644 --- 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 @@ -1,6 +1,6 @@ { "name" : "~NAME~", - "lxcTemplate" : "minimal-dbus1.sh", + "lxcTemplate" : "minimal-dbus.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" : "", @@ -10,7 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, - "runMountPoint" : "/tmp/ut-run1", + "runMountPoint" : "/tmp/ut-run/~NAME~", "permittedToSend" : [ "/tmp/.*" ], "permittedToRecv" : [ "/tmp/.*" ] } diff --git a/tests/unit_tests/server/ut-container.cpp b/tests/unit_tests/server/ut-container.cpp index c42b80d..3cb676e 100644 --- a/tests/unit_tests/server/ut-container.cpp +++ b/tests/unit_tests/server/ut-container.cpp @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(StartStopTest) BOOST_AUTO_TEST_CASE(DbusConnectionTest) { - mRunGuard.create("/tmp/ut-run1"); // the same path as in lxc template + mRunGuard.create("/tmp/ut-run"); // the same path as in lxc template auto c = create(TEST_DBUS_CONFIG_PATH); c->start(); diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 73643a8..6d64c83 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -449,8 +449,8 @@ private: if (isHost()) { return "unix:path=/var/run/dbus/system_bus_socket"; } - return "unix:path=/tmp/ut-run" + std::to_string(mId) + - "/dbus/system_bus_socket"; + return "unix:path=/tmp/ut-run/ut-containers-manager-console" + std::to_string(mId) + + "-dbus/dbus/system_bus_socket"; } }; @@ -485,15 +485,11 @@ struct Fixture { security_containers::utils::ScopedGlibLoop mLoop; utils::ScopedDir mContainersPathGuard; - utils::ScopedDir mRun1Guard; - utils::ScopedDir mRun2Guard; - utils::ScopedDir mRun3Guard; + utils::ScopedDir mRunGuard; Fixture() : mContainersPathGuard(CONTAINERS_PATH) - , mRun1Guard("/tmp/ut-run1") - , mRun2Guard("/tmp/ut-run2") - , mRun3Guard("/tmp/ut-run3") + , mRunGuard("/tmp/ut-run") {} }; @@ -906,11 +902,11 @@ namespace { const DbusAccessory::Dbuses EXPECTED_DBUSES_STARTED = { {"ut-containers-manager-console1-dbus", - "unix:path=/tmp/ut-run1/dbus/system_bus_socket"}, + "unix:path=/tmp/ut-run/ut-containers-manager-console1-dbus/dbus/system_bus_socket"}, {"ut-containers-manager-console2-dbus", - "unix:path=/tmp/ut-run2/dbus/system_bus_socket"}, + "unix:path=/tmp/ut-run/ut-containers-manager-console2-dbus/dbus/system_bus_socket"}, {"ut-containers-manager-console3-dbus", - "unix:path=/tmp/ut-run3/dbus/system_bus_socket"}}; + "unix:path=/tmp/ut-run/ut-containers-manager-console3-dbus/dbus/system_bus_socket"}}; } // namespace BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) -- 2.7.4 From ac0a215826052e4c0e1e88b446579aea841206ed Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Fri, 5 Dec 2014 15:57:49 +0100 Subject: [PATCH 14/16] Fix ipc threading issues [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I0f403bdb9dd535186a7c1fa10a486da265858ad7 --- common/ipc/internals/processor.cpp | 6 ++--- common/ipc/internals/processor.hpp | 2 +- tests/unit_tests/ipc/ut-ipc.cpp | 48 ++++++++++++++++++++------------------ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp index 5565124..b134b08 100644 --- a/common/ipc/internals/processor.cpp +++ b/common/ipc/internals/processor.cpp @@ -325,18 +325,18 @@ bool Processor::handleInput(const PeerID peerID, const Socket& socket) if (mMethodsCallbacks.count(methodID)) { // Method std::shared_ptr methodCallbacks = mMethodsCallbacks.at(methodID); - mCallsMutex.unlock(); + lock.unlock(); return onRemoteCall(peerID, socket, methodID, messageID, methodCallbacks); } else if (mSignalsCallbacks.count(methodID)) { // Signal std::shared_ptr signalCallbacks = mSignalsCallbacks.at(methodID); - mCallsMutex.unlock(); + lock.unlock(); return onRemoteSignal(peerID, socket, methodID, messageID, signalCallbacks); } else { // Nothing - mCallsMutex.unlock(); + lock.unlock(); LOGW("No method or signal callback for methodID: " << methodID); removePeerInternal(peerID, Status::NAUGHTY_PEER); return true; diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index 8fc17fb..da2a5b9 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -243,7 +243,7 @@ public: private: typedef std::function& data)> SerializeCallback; typedef std::function(int fd)> ParseCallback; - typedef std::lock_guard Lock; + typedef std::unique_lock Lock; struct EmptyData { CONFIG_REGISTER_EMPTY diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index 88696fe..b8b9e95 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -102,14 +102,12 @@ struct ThrowOnAcceptData { template void accept(Visitor) { - LOGE("Serialization and parsing failed"); - throw std::exception(); + throw std::runtime_error("intentional failure in accept"); } template void accept(Visitor) const { - LOGE("Const Serialization and parsing failed"); - throw std::exception(); + throw std::runtime_error("intentional failure in accept const"); } }; @@ -139,11 +137,11 @@ 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 peerID = 0; + auto newPeerCallback = [&cv, &peerID, &mutex](const PeerID newPeerID) { + std::unique_lock lock(mutex); peerID = newPeerID; cv.notify_one(); }; @@ -156,6 +154,7 @@ PeerID connect(Service& s, Client& c) c.start(); + std::unique_lock lock(mutex); BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&peerID]() { return peerID != 0; })); @@ -322,22 +321,23 @@ BOOST_AUTO_TEST_CASE(AsyncClientToServiceEcho) Client c(socketPath); c.start(); - std::mutex mtx; - std::unique_lock lck(mtx); + std::mutex mutex; std::condition_variable cv; //Async call std::shared_ptr sentData(new SendData(34)); std::shared_ptr recvData; - auto dataBack = [&cv, &recvData](ipc::Status status, std::shared_ptr& data) { + auto dataBack = [&cv, &recvData, &mutex](ipc::Status status, std::shared_ptr& data) { BOOST_CHECK(status == ipc::Status::OK); + std::unique_lock lock(mutex); recvData = data; cv.notify_one(); }; c.callAsync(1, sentData, dataBack); // Wait for the response - BOOST_CHECK(cv.wait_for(lck, std::chrono::milliseconds(100), [&recvData]() { + std::unique_lock lock(mutex); + BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(100), [&recvData]() { return static_cast(recvData); })); @@ -355,11 +355,11 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho) std::shared_ptr sentData(new SendData(56)); std::shared_ptr recvData; - std::mutex mtx; - std::unique_lock lck(mtx); + std::mutex mutex; std::condition_variable cv; - auto dataBack = [&cv, &recvData](ipc::Status status, std::shared_ptr& data) { + auto dataBack = [&cv, &recvData, &mutex](ipc::Status status, std::shared_ptr& data) { BOOST_CHECK(status == ipc::Status::OK); + std::unique_lock lock(mutex); recvData = data; cv.notify_one(); }; @@ -367,7 +367,8 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho) s.callAsync(1, peerID, sentData, dataBack); // Wait for the response - BOOST_CHECK(cv.wait_for(lck, std::chrono::milliseconds(1000), [&recvData]() { + std::unique_lock lock(mutex); + BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&recvData]() { return recvData.get() != nullptr; })); @@ -386,7 +387,7 @@ BOOST_AUTO_TEST_CASE(SyncTimeout) std::shared_ptr sentData(new SendData(78)); - BOOST_CHECK_THROW((c.callSync(1, sentData, 10)), IPCException); + BOOST_CHECK_THROW((c.callSync(1, sentData, 10)), IPCException); //TODO it fails from time to time } BOOST_AUTO_TEST_CASE(SerializationError) @@ -432,12 +433,12 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError) Client c(socketPath); c.start(); - std::mutex mtx; - std::unique_lock lck(mtx); + std::mutex mutex; std::condition_variable cv; ipc::Status retStatus = ipc::Status::UNDEFINED; - auto dataBack = [&cv, &retStatus](ipc::Status status, std::shared_ptr&) { + auto dataBack = [&cv, &retStatus, &mutex](ipc::Status status, std::shared_ptr&) { + std::unique_lock lock(mutex); retStatus = status; cv.notify_one(); }; @@ -446,10 +447,11 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError) c.callAsync(1, sentData, dataBack); // Wait for the response - BOOST_CHECK(cv.wait_for(lck, std::chrono::seconds(10), [&retStatus]() { + std::unique_lock lock(mutex); + BOOST_CHECK(cv.wait_for(lock, std::chrono::seconds(10), [&retStatus]() { return retStatus != ipc::Status::UNDEFINED; })); - BOOST_CHECK(retStatus == ipc::Status::PEER_DISCONNECTED); + BOOST_CHECK(retStatus == ipc::Status::PEER_DISCONNECTED); //TODO it fails from time to time } @@ -515,7 +517,7 @@ BOOST_AUTO_TEST_CASE(AddSignalInRuntime) s.signal(1, data); // Wait for the signals to arrive - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for BOOST_CHECK(isHandlerACalled && isHandlerBCalled); } @@ -547,7 +549,7 @@ BOOST_AUTO_TEST_CASE(AddSignalOffline) s.signal(1, data); // Wait for the signals to arrive - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); //TODO wait_for BOOST_CHECK(isHandlerACalled && isHandlerBCalled); } -- 2.7.4 From b550c251c29c804983f019305b6e7574b2f7b585 Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Mon, 8 Dec 2014 12:52:32 +0100 Subject: [PATCH 15/16] Fix some other threading issues [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I89b35811644f424773c007bb7d13d622ba57ac48 --- common/lxc/zone.cpp | 4 +- common/utils/environment.cpp | 18 +++---- common/utils/execute.cpp | 17 ++++--- common/utils/execute.hpp | 3 ++ tests/unit_tests/server/ut-containers-manager.cpp | 60 +++++++++++------------ tests/unit_tests/utils/scoped-daemon.cpp | 37 ++++++++------ tests/unit_tests/utils/scoped-daemon.hpp | 2 +- 7 files changed, 78 insertions(+), 63 deletions(-) diff --git a/common/lxc/zone.cpp b/common/lxc/zone.cpp index c7736f5..f4ad3e4 100644 --- a/common/lxc/zone.cpp +++ b/common/lxc/zone.cpp @@ -34,8 +34,8 @@ #include "logger/logger.hpp" #include "lxc/zone.hpp" #include "lxc/exception.hpp" -#ifdef USE_EXEC #include "utils/execute.hpp" +#ifdef USE_EXEC #include "utils/c-array.hpp" #endif @@ -320,7 +320,7 @@ bool LxcZone::setRunLevel(int runLevel) return false; } int status; - if (waitpid(pid, &status, 0) < 0) { + if (!utils::waitPid(pid, status)) { return false; } return status == 0; diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index 73c7057..aec70c1 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -25,6 +25,7 @@ #include "config.hpp" #include "utils/environment.hpp" +#include "utils/execute.hpp" #include "logger/logger.hpp" #include @@ -96,29 +97,28 @@ bool launchAsRoot(const std::function& func) if (pid == 0) { if (::setuid(0) < 0) { LOGW("Failed to become root: " << strerror(errno)); - ::exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } try { if (!func()) { LOGE("Failed to successfully execute func"); - ::exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } } catch (const std::exception& e) { LOGE("Failed to successfully execute func: " << e.what()); - ::exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); } - ::exit(EXIT_SUCCESS); + _exit(EXIT_SUCCESS); } - int result; - if (::waitpid(pid, &result, 0) < 0) { - LOGE("waitpid failed: " << strerror(errno)); + int status; + if (!waitPid(pid, status)) { return false; } - if (result != 0) { - LOGE("Function launched as root failed with result " << result); + if (status != 0) { + LOGE("Function launched as root exited with status " << status); return false; } diff --git a/common/utils/execute.cpp b/common/utils/execute.cpp index 2f2e927..6511456 100644 --- a/common/utils/execute.cpp +++ b/common/utils/execute.cpp @@ -61,12 +61,7 @@ bool executeAndWait(const char* fname, const char* const* argv, int& status) execv(fname, const_cast(argv)); _exit(EXIT_FAILURE); } - int ret = waitpid(pid, &status, 0); - if (ret != pid) { - LOGE("Waitpid failed"); - return false; - } - return true; + return waitPid(pid, status); } bool executeAndWait(const char* fname, const char* const* argv) @@ -88,5 +83,15 @@ bool executeAndWait(const char* fname, const char* const* argv) return true; } +bool waitPid(pid_t pid, int& status) +{ + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) { + return false; + } + } + return true; +} + } // namespace utils } // namespace security_containers diff --git a/common/utils/execute.hpp b/common/utils/execute.hpp index 1fc7b29..3256ee2 100644 --- a/common/utils/execute.hpp +++ b/common/utils/execute.hpp @@ -25,6 +25,7 @@ #ifndef COMMON_UTILS_EXECUTE_HPP #define COMMON_UTILS_EXECUTE_HPP +#include namespace security_containers { namespace utils { @@ -33,6 +34,8 @@ bool executeAndWait(const char* fname, const char* const* argv); bool executeAndWait(const char* fname, const char* const* argv, int& status); +bool waitPid(pid_t pid, int& status); + } // namespace utils } // namespace security_containers diff --git a/tests/unit_tests/server/ut-containers-manager.cpp b/tests/unit_tests/server/ut-containers-manager.cpp index 6d64c83..ac4a898 100644 --- a/tests/unit_tests/server/ut-containers-manager.cpp +++ b/tests/unit_tests/server/ut-containers-manager.cpp @@ -460,27 +460,6 @@ std::function expectedMessage(const std::string& me }; } -class FileCleanerRAII { -public: - FileCleanerRAII(const std::vector& filePathsToClean): - mFilePathsToClean(filePathsToClean) - { } - - ~FileCleanerRAII() - { - namespace fs = boost::filesystem; - for (const auto& file : mFilePathsToClean) { - fs::path f(file); - if (fs::exists(f)) { - fs::remove(f); - } - } - } - -private: - const std::vector mFilePathsToClean; -}; - struct Fixture { security_containers::utils::ScopedGlibLoop mLoop; @@ -1041,11 +1020,15 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest) BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest) { - const std::string newContainerId = "test1234"; + const std::string container1 = "test1"; + const std::string container2 = "test2"; + const std::string container3 = "test3"; ContainersManager cm(EMPTY_DBUS_CONFIG_PATH); cm.startAll(); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), ""); + Latch callDone; auto resultCallback = [&]() { callDone.set(); @@ -1053,19 +1036,36 @@ BOOST_AUTO_TEST_CASE(CreateDestroyContainerTest) DbusAccessory dbus(DbusAccessory::HOST_ID); - // create new container - dbus.callAsyncMethodCreateContainer(newContainerId, resultCallback); + // create container1 + dbus.callAsyncMethodCreateContainer(container1, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - // focus new container - cm.focus(newContainerId); - BOOST_CHECK(cm.getRunningForegroundContainerId() == newContainerId); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container1); - // destroy container - dbus.callAsyncMethodDestroyContainer(newContainerId, resultCallback); + // create container2 + dbus.callAsyncMethodCreateContainer(container2, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container2); //TODO is this valid? - BOOST_CHECK(cm.getRunningForegroundContainerId() == ""); + // create container3 + dbus.callAsyncMethodCreateContainer(container3, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container3); + + // destroy container2 + dbus.callAsyncMethodDestroyContainer(container2, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container3); + + // destroy container3 + dbus.callAsyncMethodDestroyContainer(container3, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + //BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), container1);//TODO fix it + + // destroy container1 + dbus.callAsyncMethodDestroyContainer(container1, resultCallback); + BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); + BOOST_CHECK_EQUAL(cm.getRunningForegroundContainerId(), ""); } BOOST_AUTO_TEST_CASE(DeclareFile) diff --git a/tests/unit_tests/utils/scoped-daemon.cpp b/tests/unit_tests/utils/scoped-daemon.cpp index 21fea83..db85375 100644 --- a/tests/unit_tests/utils/scoped-daemon.cpp +++ b/tests/unit_tests/utils/scoped-daemon.cpp @@ -25,6 +25,7 @@ #include "config.hpp" #include "utils/scoped-daemon.hpp" +#include "utils/execute.hpp" #include "logger/logger.hpp" @@ -69,17 +70,17 @@ namespace { volatile pid_t daemonPid = -1;// available in launcher process only; -void startDaemon(const char* path, const char* const argv[]) +bool startDaemon(const char* path, const char* const argv[]) { execv(path, const_cast(argv)); perror("exec failed"); + return false; } -void waitForDaemon() +bool waitForDaemon() { - if (waitpid(daemonPid, NULL, 0) == -1) { - perror("wait for daemon failed"); - } + int status; + return waitPid(daemonPid, status); } void launcherSignalHandler(int sig) @@ -108,21 +109,22 @@ void cleanupProcess() signal(SIGHUP, SIG_DFL); } -void startByLauncher(const char* path, const char* const argv[]) +bool startByLauncher(const char* path, const char* const argv[]) { cleanupProcess(); daemonPid = fork(); if (daemonPid == -1) { perror("fork failed"); - return; + return false; } if (daemonPid == 0) { - startDaemon(path, argv); - _exit(1); + if (!startDaemon(path, argv)) { + return false; + } } registerLauncherSignalHandler(); registerParentDiedNotification(); - waitForDaemon(); + return waitForDaemon(); } } // namespace @@ -147,12 +149,13 @@ void ScopedDaemon::start(const char* path, const char* const argv[], const bool throw std::runtime_error("fork failed"); } if (mPid == 0) { + bool ret; if (useLauncher) { - startByLauncher(path, argv); + ret = startByLauncher(path, argv); } else { - startDaemon(path, argv); + ret = startDaemon(path, argv); } - _exit(0); + _exit(ret ? EXIT_SUCCESS : EXIT_FAILURE); } } @@ -164,8 +167,12 @@ void ScopedDaemon::stop() if (kill(mPid, SIGTERM) == -1) { LOGE("kill failed"); } - if (waitpid(mPid, NULL, 0) == -1) { - LOGE("waitpid failed"); + int status; + if (!waitPid(mPid, status)) { + throw std::runtime_error("waitpid failed"); + } + if (status != EXIT_SUCCESS) { + LOGW("process exit with status " << status); } mPid = -1; } diff --git a/tests/unit_tests/utils/scoped-daemon.hpp b/tests/unit_tests/utils/scoped-daemon.hpp index 89e630c..b3eab29 100644 --- a/tests/unit_tests/utils/scoped-daemon.hpp +++ b/tests/unit_tests/utils/scoped-daemon.hpp @@ -50,7 +50,7 @@ public: * @param argv arguments passed to the daemon * @param useLauncher use additional launcher process */ - void start(const char* path, const char* const argv[], const bool useLauncher = true); + void start(const char* path, const char* const argv[], const bool useLauncher = false); /** * Stops a daemon by sending SIGTERM and waits for a process. -- 2.7.4 From 316605cca8c654878acfc67deb5a62103be2822b Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Mon, 8 Dec 2014 13:41:39 +0100 Subject: [PATCH 16/16] IPC: Replace PeerID witch peer's file descriptor [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I30203990d9c9c3a58515d2fe09b074072122c156 --- common/ipc/client.cpp | 2 +- common/ipc/client.hpp | 6 +- common/ipc/internals/call-queue.hpp | 14 ++-- common/ipc/internals/processor.cpp | 134 ++++++++++++++++-------------------- common/ipc/internals/processor.hpp | 100 +++++++++++++-------------- common/ipc/service.hpp | 18 ++--- common/ipc/types.hpp | 14 ++-- tests/unit_tests/ipc/ut-ipc.cpp | 54 +++++++-------- 8 files changed, 165 insertions(+), 177 deletions(-) diff --git a/common/ipc/client.cpp b/common/ipc/client.cpp index c806e7b..8b0e458 100644 --- a/common/ipc/client.cpp +++ b/common/ipc/client.cpp @@ -55,7 +55,7 @@ void Client::start() // Initialize the connection with the server LOGD("Connecting to " + mSocketPath); auto socketPtr = std::make_shared(Socket::connectSocket(mSocketPath)); - mServiceID = mProcessor.addPeer(socketPtr); + mServiceFD = mProcessor.addPeer(socketPtr); // Start listening mProcessor.start(); diff --git a/common/ipc/client.hpp b/common/ipc/client.hpp index 3178474..6f8b049 100644 --- a/common/ipc/client.hpp +++ b/common/ipc/client.hpp @@ -156,7 +156,7 @@ public: const std::shared_ptr& data); private: - PeerID mServiceID; + FileDescriptor mServiceFD; Processor mProcessor; std::string mSocketPath; }; @@ -185,7 +185,7 @@ std::shared_ptr Client::callSync(const MethodID methodID, unsigned int timeoutMS) { LOGD("Sync calling method: " << methodID); - return mProcessor.callSync(methodID, mServiceID, data, timeoutMS); + return mProcessor.callSync(methodID, mServiceFD, data, timeoutMS); } template @@ -196,7 +196,7 @@ void Client::callAsync(const MethodID methodID, LOGD("Async calling method: " << methodID); mProcessor.callAsync(methodID, - mServiceID, + mServiceFD, data, resultCallback); LOGD("Async called method: " << methodID); diff --git a/common/ipc/internals/call-queue.hpp b/common/ipc/internals/call-queue.hpp index 4d1ecf6..7911d7a 100644 --- a/common/ipc/internals/call-queue.hpp +++ b/common/ipc/internals/call-queue.hpp @@ -48,7 +48,7 @@ public: Call() = default; Call(Call&&) = default; - PeerID peerID; + FileDescriptor peerFD; MethodID methodID; MessageID messageID; std::shared_ptr data; @@ -66,14 +66,14 @@ public: template MessageID push(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process); template MessageID push(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data); Call pop(); @@ -90,13 +90,13 @@ private: template MessageID CallQueue::push(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process) { Call call; call.methodID = methodID; - call.peerID = peerID; + call.peerFD = peerFD; call.data = data; MessageID messageID = getNextMessageID(); @@ -124,12 +124,12 @@ MessageID CallQueue::push(const MethodID methodID, template MessageID CallQueue::push(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data) { Call call; call.methodID = methodID; - call.peerID = peerID; + call.peerFD = peerFD; call.data = data; MessageID messageID = getNextMessageID(); diff --git a/common/ipc/internals/processor.cpp b/common/ipc/internals/processor.cpp index b134b08..7ac378e 100644 --- a/common/ipc/internals/processor.cpp +++ b/common/ipc/internals/processor.cpp @@ -55,8 +55,7 @@ Processor::Processor(const PeerCallback& newPeerCallback, const unsigned int maxNumberOfPeers) : mNewPeerCallback(newPeerCallback), mRemovedPeerCallback(removedPeerCallback), - mMaxNumberOfPeers(maxNumberOfPeers), - mPeerIDCounter(0) + mMaxNumberOfPeers(maxNumberOfPeers) { LOGT("Creating Processor"); using namespace std::placeholders; @@ -120,37 +119,37 @@ void Processor::removeMethod(const MethodID methodID) mMethodsCallbacks.erase(methodID); } -PeerID Processor::addPeer(const std::shared_ptr& socketPtr) +FileDescriptor Processor::addPeer(const std::shared_ptr& socketPtr) { LOGT("Adding socket"); - PeerID peerID; + FileDescriptor peerFD; { Lock lock(mSocketsMutex); - peerID = getNextPeerID(); - SocketInfo socketInfo(peerID, std::move(socketPtr)); + peerFD = socketPtr->getFD(); + SocketInfo socketInfo(peerFD, std::move(socketPtr)); mNewSockets.push(std::move(socketInfo)); } - LOGI("New peer added. Id: " << peerID); + LOGI("New peer added. Id: " << peerFD); mEventQueue.send(Event::ADD_PEER); - return peerID; + return peerFD; } -void Processor::removePeer(const PeerID peerID) +void Processor::removePeer(const FileDescriptor peerFD) { std::shared_ptr conditionPtr(new std::condition_variable()); { Lock lock(mSocketsMutex); - RemovePeerRequest request(peerID, conditionPtr); + RemovePeerRequest request(peerFD, conditionPtr); mPeersToDelete.push(std::move(request)); } mEventQueue.send(Event::REMOVE_PEER); - auto isPeerDeleted = [&peerID, this]()->bool { + auto isPeerDeleted = [&peerFD, this]()->bool { Lock lock(mSocketsMutex); - return mSockets.count(peerID) == 0; + return mSockets.count(peerFD) == 0; }; std::mutex mutex; @@ -158,16 +157,16 @@ void Processor::removePeer(const PeerID peerID) conditionPtr->wait(lock, isPeerDeleted); } -void Processor::removePeerInternal(const PeerID peerID, Status status) +void Processor::removePeerInternal(const FileDescriptor peerFD, Status status) { - LOGW("Removing peer. ID: " << peerID); + LOGW("Removing peer. ID: " << peerFD); { Lock lock(mSocketsMutex); - mSockets.erase(peerID); + mSockets.erase(peerFD); // Remove from signal addressees for (auto it = mSignalsPeers.begin(); it != mSignalsPeers.end();) { - it->second.remove(peerID); + it->second.remove(peerFD); if (it->second.empty()) { it = mSignalsPeers.erase(it); } else { @@ -182,7 +181,7 @@ void Processor::removePeerInternal(const PeerID peerID, Status status) std::shared_ptr data; for (auto it = mReturnCallbacks.begin(); it != mReturnCallbacks.end();) { - if (it->second.peerID == peerID) { + if (it->second.peerFD == peerFD) { IGNORE_EXCEPTIONS(it->second.process(status, data)); it = mReturnCallbacks.erase(it); } else { @@ -196,7 +195,7 @@ void Processor::removePeerInternal(const PeerID peerID, Status status) Lock lock(mCallbacksMutex); if (mRemovedPeerCallback) { // Notify about the deletion - mRemovedPeerCallback(peerID); + mRemovedPeerCallback(peerFD); } } @@ -264,22 +263,21 @@ void Processor::run() bool Processor::handleLostConnections() { - std::list peersToRemove; + std::vector peersToRemove; { Lock lock(mSocketsMutex); - auto socketIt = mSockets.begin(); - for (unsigned int i = 1; i < mFDs.size(); ++i, ++socketIt) { + for (unsigned int i = 1; i < mFDs.size(); ++i) { if (mFDs[i].revents & POLLHUP) { - LOGI("Lost connection to peer: " << socketIt->first); + LOGI("Lost connection to peer: " << mFDs[i].fd); mFDs[i].revents &= ~(POLLHUP); - peersToRemove.push_back(socketIt->first); + peersToRemove.push_back(mFDs[i].fd); } } } - for (const PeerID peerID : peersToRemove) { - removePeerInternal(peerID, Status::PEER_DISCONNECTED); + for (const FileDescriptor peerFD : peersToRemove) { + removePeerInternal(peerFD, Status::PEER_DISCONNECTED); } return !peersToRemove.empty(); @@ -287,27 +285,26 @@ bool Processor::handleLostConnections() bool Processor::handleInputs() { - std::list> > peersWithInput; + std::vector> socketsWithInput; { Lock lock(mSocketsMutex); - auto socketIt = mSockets.begin(); - for (unsigned int i = 1; i < mFDs.size(); ++i, ++socketIt) { + for (unsigned int i = 1; i < mFDs.size(); ++i) { if (mFDs[i].revents & POLLIN) { mFDs[i].revents &= ~(POLLIN); - peersWithInput.push_back(*socketIt); + socketsWithInput.push_back(mSockets[mFDs[i].fd]); } } } bool pollChanged = false; // Handle input outside the critical section - for (const auto& peer : peersWithInput) { - pollChanged = pollChanged || handleInput(peer.first, *peer.second); + for (const auto& socketPtr : socketsWithInput) { + pollChanged = pollChanged || handleInput(*socketPtr); } return pollChanged; } -bool Processor::handleInput(const PeerID peerID, const Socket& socket) +bool Processor::handleInput(const Socket& socket) { LOGT("Handle incoming data"); MethodID methodID; @@ -318,7 +315,7 @@ bool Processor::handleInput(const PeerID peerID, const Socket& socket) socket.read(&messageID, sizeof(messageID)); if (methodID == RETURN_METHOD_ID) { - return onReturnValue(peerID, socket, messageID); + return onReturnValue(socket, messageID); } else { Lock lock(mCallsMutex); @@ -326,19 +323,19 @@ bool Processor::handleInput(const PeerID peerID, const Socket& socket) // Method std::shared_ptr methodCallbacks = mMethodsCallbacks.at(methodID); lock.unlock(); - return onRemoteCall(peerID, socket, methodID, messageID, methodCallbacks); + return onRemoteCall(socket, methodID, messageID, methodCallbacks); } else if (mSignalsCallbacks.count(methodID)) { // Signal std::shared_ptr signalCallbacks = mSignalsCallbacks.at(methodID); lock.unlock(); - return onRemoteSignal(peerID, socket, methodID, messageID, signalCallbacks); + return onRemoteSignal(socket, methodID, messageID, signalCallbacks); } else { // Nothing lock.unlock(); LOGW("No method or signal callback for methodID: " << methodID); - removePeerInternal(peerID, Status::NAUGHTY_PEER); + removePeerInternal(socket.getFD(), Status::NAUGHTY_PEER); return true; } } @@ -347,20 +344,19 @@ bool Processor::handleInput(const PeerID peerID, const Socket& socket) return false; } -std::shared_ptr Processor::onNewSignals(const PeerID peerID, +std::shared_ptr Processor::onNewSignals(const FileDescriptor peerFD, std::shared_ptr& data) { - LOGD("New signals for peer: " << peerID); + LOGD("New signals for peer: " << peerFD); Lock lock(mSocketsMutex); for (MethodID methodID : data->ids) { - mSignalsPeers[methodID].push_back(peerID); + mSignalsPeers[methodID].push_back(peerFD); } return std::make_shared(); } -bool Processor::onReturnValue(const PeerID peerID, - const Socket& socket, +bool Processor::onReturnValue(const Socket& socket, const MessageID messageID) { LOGI("Return value for messageID: " << messageID); @@ -372,7 +368,7 @@ bool Processor::onReturnValue(const PeerID peerID, mReturnCallbacks.erase(messageID); } catch (const std::out_of_range&) { LOGW("No return callback for messageID: " << messageID); - removePeerInternal(peerID, Status::NAUGHTY_PEER); + removePeerInternal(socket.getFD(), Status::NAUGHTY_PEER); return true; } @@ -383,7 +379,7 @@ bool Processor::onReturnValue(const PeerID peerID, } catch (const std::exception& e) { LOGE("Exception during parsing: " << e.what()); IGNORE_EXCEPTIONS(returnCallbacks.process(Status::PARSING_ERROR, data)); - removePeerInternal(peerID, Status::PARSING_ERROR); + removePeerInternal(socket.getFD(), Status::PARSING_ERROR); return true; } @@ -393,8 +389,7 @@ bool Processor::onReturnValue(const PeerID peerID, return false; } -bool Processor::onRemoteSignal(const PeerID peerID, - const Socket& socket, +bool Processor::onRemoteSignal(const Socket& socket, const MethodID methodID, const MessageID messageID, std::shared_ptr signalCallbacks) @@ -407,24 +402,23 @@ bool Processor::onRemoteSignal(const PeerID peerID, data = signalCallbacks->parse(socket.getFD()); } catch (const std::exception& e) { LOGE("Exception during parsing: " << e.what()); - removePeerInternal(peerID, Status::PARSING_ERROR); + removePeerInternal(socket.getFD(), Status::PARSING_ERROR); return true; } LOGT("Signal callback for methodID: " << methodID << "; messageID: " << messageID); try { - signalCallbacks->signal(peerID, data); + signalCallbacks->signal(socket.getFD(), data); } catch (const std::exception& e) { LOGE("Exception in method handler: " << e.what()); - removePeerInternal(peerID, Status::NAUGHTY_PEER); + removePeerInternal(socket.getFD(), Status::NAUGHTY_PEER); return true; } return false; } -bool Processor::onRemoteCall(const PeerID peerID, - const Socket& socket, +bool Processor::onRemoteCall(const Socket& socket, const MethodID methodID, const MessageID messageID, std::shared_ptr methodCallbacks) @@ -437,17 +431,17 @@ bool Processor::onRemoteCall(const PeerID peerID, data = methodCallbacks->parse(socket.getFD()); } catch (const std::exception& e) { LOGE("Exception during parsing: " << e.what()); - removePeerInternal(peerID, Status::PARSING_ERROR); + removePeerInternal(socket.getFD(), Status::PARSING_ERROR); return true; } LOGT("Process callback for methodID: " << methodID << "; messageID: " << messageID); std::shared_ptr returnData; try { - returnData = methodCallbacks->method(peerID, data); + returnData = methodCallbacks->method(socket.getFD(), data); } catch (const std::exception& e) { LOGE("Exception in method handler: " << e.what()); - removePeerInternal(peerID, Status::NAUGHTY_PEER); + removePeerInternal(socket.getFD(), Status::NAUGHTY_PEER); return true; } @@ -460,7 +454,7 @@ bool Processor::onRemoteCall(const PeerID peerID, methodCallbacks->serialize(socket.getFD(), returnData); } catch (const std::exception& e) { LOGE("Exception during serialization: " << e.what()); - removePeerInternal(peerID, Status::SERIALIZATION_ERROR); + removePeerInternal(socket.getFD(), Status::SERIALIZATION_ERROR); return true; } @@ -512,21 +506,21 @@ bool Processor::onNewPeer() mNewSockets.pop(); if (mSockets.size() > mMaxNumberOfPeers) { - LOGE("There are too many peers. I don't accept the connection with " << socketInfo.peerID); + LOGE("There are too many peers. I don't accept the connection with " << socketInfo.peerFD); return false; } - if (mSockets.count(socketInfo.peerID) != 0) { - LOGE("There already was a socket for peerID: " << socketInfo.peerID); + if (mSockets.count(socketInfo.peerFD) != 0) { + LOGE("There already was a socket for peerFD: " << socketInfo.peerFD); return false; } - mSockets[socketInfo.peerID] = std::move(socketInfo.socketPtr); + mSockets[socketInfo.peerFD] = std::move(socketInfo.socketPtr); } // Broadcast the new signal to peers LOGW("Sending handled signals"); - std::list peersIDs; + std::list peersIDs; { Lock lock(mSocketsMutex); for (const auto kv : mSockets) { @@ -543,9 +537,9 @@ bool Processor::onNewPeer() } auto data = std::make_shared(ids); - for (const PeerID peerID : peersIDs) { + for (const FileDescriptor peerFD : peersIDs) { callInternal(REGISTER_SIGNAL_METHOD_ID, - peerID, + peerFD, data, discardResultHandler); } @@ -558,7 +552,7 @@ bool Processor::onNewPeer() Lock lock(mCallbacksMutex); if (mNewPeerCallback) { // Notify about the new user. - mNewPeerCallback(socketInfo.peerID); + mNewPeerCallback(socketInfo.peerFD); } } return true; @@ -573,17 +567,11 @@ bool Processor::onRemovePeer() mPeersToDelete.pop(); } - removePeerInternal(request.peerID, Status::REMOVED_PEER); + removePeerInternal(request.peerFD, Status::REMOVED_PEER); request.conditionPtr->notify_all(); return true; } -PeerID Processor::getNextPeerID() -{ - // TODO: This method of generating UIDs is buggy. To be changed. - return ++mPeerIDCounter; -} - CallQueue::Call Processor::getCall() { Lock lock(mCallsMutex); @@ -599,9 +587,9 @@ bool Processor::onCall() try { // Get the peer's socket Lock lock(mSocketsMutex); - socketPtr = mSockets.at(call.peerID); + socketPtr = mSockets.at(call.peerFD); } catch (const std::out_of_range&) { - LOGE("Peer disconnected. No socket with a peerID: " << call.peerID); + LOGE("Peer disconnected. No socket with a peerFD: " << call.peerFD); IGNORE_EXCEPTIONS(call.process(Status::PEER_DISCONNECTED, call.data)); return false; } @@ -612,7 +600,7 @@ bool Processor::onCall() if (mReturnCallbacks.count(call.messageID) != 0) { LOGE("There already was a return callback for messageID: " << call.messageID); } - mReturnCallbacks[call.messageID] = std::move(ReturnCallbacks(call.peerID, + mReturnCallbacks[call.messageID] = std::move(ReturnCallbacks(call.peerFD, std::move(call.parse), std::move(call.process))); } @@ -634,7 +622,7 @@ bool Processor::onCall() mReturnCallbacks.erase(call.messageID); } - removePeerInternal(call.peerID, Status::SERIALIZATION_ERROR); + removePeerInternal(call.peerFD, Status::SERIALIZATION_ERROR); return true; } diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index da2a5b9..476e662 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -35,8 +35,6 @@ #include "logger/logger.hpp" #include - -#include #include #include #include @@ -76,6 +74,9 @@ const unsigned int DEFAULT_METHOD_TIMEOUT = 1000; * - helper function for removing from unordered map * - new way to generate UIDs * - callbacks for serialization/parsing +* - store Sockets in a vector, maybe SocketStore? +* +* */ class Processor { public: @@ -141,16 +142,16 @@ public: * Calls the newPeerCallback. * * @param socketPtr pointer to the new socket - * @return peerID of the new socket + * @return peerFD of the new socket */ - PeerID addPeer(const std::shared_ptr& socketPtr); + FileDescriptor addPeer(const std::shared_ptr& socketPtr); /** * Request removing peer and wait * - * @param peerID id of the peer + * @param peerFD id of the peer */ - void removePeer(const PeerID peerID); + void removePeer(const FileDescriptor peerFD); /** * Saves the callbacks connected to the method id. @@ -197,7 +198,7 @@ public: * Synchronous method call. * * @param methodID API dependent id of the method - * @param peerID id of the peer + * @param peerFD id of the peer * @param data data to sent * @param timeoutMS how long to wait for the return value before throw * @tparam SentDataType data type to send @@ -205,7 +206,7 @@ public: */ template std::shared_ptr callSync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, unsigned int timeoutMS = 500); @@ -213,7 +214,7 @@ public: * Asynchronous method call * * @param methodID API dependent id of the method - * @param peerID id of the peer + * @param peerFD id of the peer * @param data data to sent * @param process callback processing the return data * @tparam SentDataType data type to send @@ -221,7 +222,7 @@ public: */ template MessageID callAsync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process); @@ -292,10 +293,10 @@ private: ReturnCallbacks(ReturnCallbacks&&) = default; ReturnCallbacks& operator=(ReturnCallbacks &&) = default; - ReturnCallbacks(PeerID peerID, const ParseCallback& parse, const ResultHandler::type& process) - : peerID(peerID), parse(parse), process(process) {} + ReturnCallbacks(FileDescriptor peerFD, const ParseCallback& parse, const ResultHandler::type& process) + : peerFD(peerFD), parse(parse), process(process) {} - PeerID peerID; + FileDescriptor peerFD; ParseCallback parse; ResultHandler::type process; }; @@ -307,10 +308,10 @@ private: SocketInfo(SocketInfo&&) = default; SocketInfo& operator=(SocketInfo &&) = default; - SocketInfo(const PeerID peerID, const std::shared_ptr& socketPtr) - : peerID(peerID), socketPtr(socketPtr) {} + SocketInfo(const FileDescriptor peerFD, const std::shared_ptr& socketPtr) + : peerFD(peerFD), socketPtr(socketPtr) {} - PeerID peerID; + FileDescriptor peerFD; std::shared_ptr socketPtr; }; @@ -321,11 +322,11 @@ private: RemovePeerRequest(RemovePeerRequest&&) = default; RemovePeerRequest& operator=(RemovePeerRequest &&) = default; - RemovePeerRequest(const PeerID peerID, + RemovePeerRequest(const FileDescriptor peerFD, const std::shared_ptr& conditionPtr) - : peerID(peerID), conditionPtr(conditionPtr) {} + : peerFD(peerFD), conditionPtr(conditionPtr) {} - PeerID peerID; + FileDescriptor peerFD; std::shared_ptr conditionPtr; }; @@ -345,12 +346,13 @@ private: CallQueue mCalls; std::unordered_map> mMethodsCallbacks; std::unordered_map> mSignalsCallbacks; - std::unordered_map> mSignalsPeers; + std::unordered_map> mSignalsPeers; // Mutex for changing mSockets map. // Shouldn't be locked on any read/write, that could block. Just copy the ptr. std::mutex mSocketsMutex; - std::unordered_map > mSockets; + std::unordered_map > mSockets; + std::vector mFDs; std::queue mNewSockets; std::queue mPeersToDelete; @@ -366,9 +368,6 @@ private: unsigned int mMaxNumberOfPeers; std::thread mThread; - std::vector mFDs; - - std::atomic mPeerIDCounter; template void addMethodHandlerInternal(const MethodID methodID, @@ -376,7 +375,7 @@ private: template MessageID callInternal(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process); @@ -390,26 +389,23 @@ private: bool onRemovePeer(); bool handleLostConnections(); bool handleInputs(); - bool handleInput(const PeerID peerID, const Socket& socket); - bool onReturnValue(const PeerID peerID, - const Socket& socket, + bool handleInput(const Socket& socket); + bool onReturnValue(const Socket& socket, const MessageID messageID); - bool onRemoteCall(const PeerID peerID, - const Socket& socket, + bool onRemoteCall(const Socket& socket, const MethodID methodID, const MessageID messageID, std::shared_ptr methodCallbacks); - bool onRemoteSignal(const PeerID peerID, - const Socket& socket, + bool onRemoteSignal(const Socket& socket, const MethodID methodID, const MessageID messageID, std::shared_ptr signalCallbacks); void resetPolling(); - PeerID getNextPeerID(); + FileDescriptor getNextFileDescriptor(); CallQueue::Call getCall(); - void removePeerInternal(const PeerID peerID, Status status); + void removePeerInternal(const FileDescriptor peerFD, Status status); - std::shared_ptr onNewSignals(const PeerID peerID, + std::shared_ptr onNewSignals(const FileDescriptor peerFD, std::shared_ptr& data); @@ -432,9 +428,9 @@ void Processor::addMethodHandlerInternal(const MethodID methodID, config::saveToFD(fd, *std::static_pointer_cast(data)); }; - methodCall.method = [method](const PeerID peerID, std::shared_ptr& data)->std::shared_ptr { + methodCall.method = [method](const FileDescriptor peerFD, std::shared_ptr& data)->std::shared_ptr { std::shared_ptr tmpData = std::static_pointer_cast(data); - return method(peerID, tmpData); + return method(peerFD, tmpData); }; { @@ -488,9 +484,9 @@ void Processor::addSignalHandler(const MethodID methodID, return data; }; - signalCall.signal = [handler](const PeerID peerID, std::shared_ptr& data) { + signalCall.signal = [handler](const FileDescriptor peerFD, std::shared_ptr& data) { std::shared_ptr tmpData = std::static_pointer_cast(data); - handler(peerID, tmpData); + handler(peerFD, tmpData); }; { @@ -503,7 +499,7 @@ void Processor::addSignalHandler(const MethodID methodID, std::vector ids {methodID}; auto data = std::make_shared(ids); - std::list peersIDs; + std::list peersIDs; { Lock lock(mSocketsMutex); for (const auto kv : mSockets) { @@ -511,9 +507,9 @@ void Processor::addSignalHandler(const MethodID methodID, } } - for (const PeerID peerID : peersIDs) { + for (const FileDescriptor peerFD : peersIDs) { callSync(REGISTER_SIGNAL_METHOD_ID, - peerID, + peerFD, data, DEFAULT_METHOD_TIMEOUT); } @@ -522,12 +518,12 @@ void Processor::addSignalHandler(const MethodID methodID, template MessageID Processor::callInternal(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process) { Lock lock(mCallsMutex); - MessageID messageID = mCalls.push(methodID, peerID, data, process); + MessageID messageID = mCalls.push(methodID, peerFD, data, process); mEventQueue.send(Event::CALL); return messageID; @@ -535,7 +531,7 @@ MessageID Processor::callInternal(const MethodID methodID, template MessageID Processor::callAsync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& process) { @@ -544,13 +540,13 @@ MessageID Processor::callAsync(const MethodID methodID, throw IPCException("The Processor thread is not started. Can't send any data."); } - return callInternal(methodID, peerID, data, process); + return callInternal(methodID, peerFD, data, process); } template std::shared_ptr Processor::callSync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, unsigned int timeoutMS) { @@ -568,7 +564,7 @@ std::shared_ptr Processor::callSync(const MethodID methodID, }; MessageID messageID = callAsync(methodID, - peerID, + peerFD, data, process); @@ -586,7 +582,7 @@ std::shared_ptr Processor::callSync(const MethodID methodID, } } if (isTimeout) { - removePeer(peerID); + removePeer(peerFD); LOGE("Function call timeout; methodID: " << methodID); throw IPCTimeoutException("Function call timeout; methodID: " + std::to_string(methodID)); } else { @@ -609,15 +605,15 @@ void Processor::signal(const MethodID methodID, throw IPCException("The Processor thread is not started. Can't send any data."); } - std::list peersIDs; + std::list peersIDs; { Lock lock(mSocketsMutex); peersIDs = mSignalsPeers[methodID]; } - for (const PeerID peerID : peersIDs) { + for (const FileDescriptor peerFD : peersIDs) { Lock lock(mCallsMutex); - mCalls.push(methodID, peerID, data); + mCalls.push(methodID, peerFD, data); mEventQueue.send(Event::CALL); } } diff --git a/common/ipc/service.hpp b/common/ipc/service.hpp index ac22eb2..317311d 100644 --- a/common/ipc/service.hpp +++ b/common/ipc/service.hpp @@ -129,7 +129,7 @@ public: */ template std::shared_ptr callSync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, unsigned int timeoutMS = 500); @@ -144,7 +144,7 @@ public: */ template void callAsync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& resultCallback); @@ -187,27 +187,27 @@ void Service::addSignalHandler(const MethodID methodID, template std::shared_ptr Service::callSync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, unsigned int timeoutMS) { - LOGD("Sync calling method: " << methodID << " for user: " << peerID); - return mProcessor.callSync(methodID, peerID, data, timeoutMS); + LOGD("Sync calling method: " << methodID << " for user: " << peerFD); + return mProcessor.callSync(methodID, peerFD, data, timeoutMS); } template void Service::callAsync(const MethodID methodID, - const PeerID peerID, + const FileDescriptor peerFD, const std::shared_ptr& data, const typename ResultHandler::type& resultCallback) { - LOGD("Async calling method: " << methodID << " for user: " << peerID); + LOGD("Async calling method: " << methodID << " for user: " << peerFD); mProcessor.callAsync(methodID, - peerID, + peerFD, data, resultCallback); - LOGD("Async called method: " << methodID << "for user: " << peerID); + LOGD("Async called method: " << methodID << "for user: " << peerFD); } template diff --git a/common/ipc/types.hpp b/common/ipc/types.hpp index 6588fb0..5fe9188 100644 --- a/common/ipc/types.hpp +++ b/common/ipc/types.hpp @@ -34,11 +34,12 @@ namespace security_containers { namespace ipc { -typedef std::function PeerCallback; -typedef unsigned int PeerID; +typedef int FileDescriptor; typedef unsigned int MethodID; typedef unsigned int MessageID; +typedef std::function PeerCallback; + enum class Status : int { OK = 0, PARSING_ERROR, @@ -55,17 +56,20 @@ void throwOnError(const Status status); template struct MethodHandler { - typedef std::function(PeerID, std::shared_ptr&)> type; + typedef std::function(FileDescriptor peerFD, + std::shared_ptr& data)> type; }; template struct SignalHandler { - typedef std::function&)> type; + typedef std::function& data)> type; }; template struct ResultHandler { - typedef std::function&)> type; + typedef std::function& resultData)> type; }; } // namespace ipc diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index b8b9e95..679f3df 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -111,38 +111,38 @@ struct ThrowOnAcceptData { } }; -std::shared_ptr returnEmptyCallback(const PeerID, std::shared_ptr&) +std::shared_ptr returnEmptyCallback(const FileDescriptor, std::shared_ptr&) { return std::shared_ptr(new EmptyData()); } -std::shared_ptr returnDataCallback(const PeerID, std::shared_ptr&) +std::shared_ptr returnDataCallback(const FileDescriptor, std::shared_ptr&) { return std::shared_ptr(new SendData(1)); } -std::shared_ptr echoCallback(const PeerID, std::shared_ptr& data) +std::shared_ptr echoCallback(const FileDescriptor, std::shared_ptr& data) { return data; } -std::shared_ptr longEchoCallback(const PeerID, std::shared_ptr& data) +std::shared_ptr longEchoCallback(const FileDescriptor, std::shared_ptr& data) { std::this_thread::sleep_for(std::chrono::seconds(1)); return data; } -PeerID connect(Service& s, Client& c) +FileDescriptor connect(Service& s, Client& c) { - // Connects the Client to the Service and returns Clients PeerID + // Connects the Client to the Service and returns Clients FileDescriptor std::mutex mutex; std::condition_variable cv; - PeerID peerID = 0; - auto newPeerCallback = [&cv, &peerID, &mutex](const PeerID newPeerID) { + FileDescriptor peerFD = 0; + auto newPeerCallback = [&cv, &peerFD, &mutex](const FileDescriptor newFileDescriptor) { std::unique_lock lock(mutex); - peerID = newPeerID; + peerFD = newFileDescriptor; cv.notify_one(); }; @@ -155,11 +155,11 @@ PeerID connect(Service& s, Client& c) c.start(); std::unique_lock lock(mutex); - BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&peerID]() { - return peerID != 0; + BOOST_CHECK(cv.wait_for(lock, std::chrono::milliseconds(1000), [&peerFD]() { + return peerFD != 0; })); - return peerID; + return peerFD; } void testEcho(Client& c, const MethodID methodID) @@ -169,10 +169,10 @@ void testEcho(Client& c, const MethodID methodID) BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } -void testEcho(Service& s, const MethodID methodID, const PeerID peerID) +void testEcho(Service& s, const MethodID methodID, const FileDescriptor peerFD) { std::shared_ptr sentData(new SendData(56)); - std::shared_ptr recvData = s.callSync(methodID, peerID, sentData); + std::shared_ptr recvData = s.callSync(methodID, peerFD, sentData); BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } @@ -216,17 +216,17 @@ BOOST_AUTO_TEST_CASE(ClientAddRemoveMethod) c.addMethodHandler(1, returnEmptyCallback); c.addMethodHandler(1, returnDataCallback); - PeerID peerID = connect(s, c); + FileDescriptor peerFD = connect(s, c); c.addMethodHandler(1, echoCallback); c.addMethodHandler(2, returnDataCallback); - testEcho(s, 1, peerID); + testEcho(s, 1, peerFD); c.removeMethod(1); c.removeMethod(2); - BOOST_CHECK_THROW(testEcho(s, 1, peerID), IPCException); + BOOST_CHECK_THROW(testEcho(s, 1, peerFD), IPCException); } BOOST_AUTO_TEST_CASE(ServiceStartStop) @@ -305,10 +305,10 @@ BOOST_AUTO_TEST_CASE(SyncServiceToClientEcho) Service s(socketPath); Client c(socketPath); c.addMethodHandler(1, echoCallback); - PeerID peerID = connect(s, c); + FileDescriptor peerFD = connect(s, c); std::shared_ptr sentData(new SendData(56)); - std::shared_ptr recvData = s.callSync(1, peerID, sentData); + std::shared_ptr recvData = s.callSync(1, peerFD, sentData); BOOST_CHECK_EQUAL(recvData->intVal, sentData->intVal); } @@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho) Service s(socketPath); Client c(socketPath); c.addMethodHandler(1, echoCallback); - PeerID peerID = connect(s, c); + FileDescriptor peerFD = connect(s, c); // Async call std::shared_ptr sentData(new SendData(56)); @@ -364,7 +364,7 @@ BOOST_AUTO_TEST_CASE(AsyncServiceToClientEcho) cv.notify_one(); }; - s.callAsync(1, peerID, sentData, dataBack); + s.callAsync(1, peerFD, sentData, dataBack); // Wait for the response std::unique_lock lock(mutex); @@ -422,7 +422,7 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError) { Service s(socketPath); - auto method = [](const PeerID, std::shared_ptr&) { + auto method = [](const FileDescriptor, std::shared_ptr&) { return std::shared_ptr(new SendData(1)); }; @@ -458,7 +458,7 @@ BOOST_AUTO_TEST_CASE(DisconnectedPeerError) BOOST_AUTO_TEST_CASE(ReadTimeout) { Service s(socketPath); - auto longEchoCallback = [](const PeerID, std::shared_ptr& data) { + auto longEchoCallback = [](const FileDescriptor, std::shared_ptr& data) { return std::shared_ptr(new LongSendData(data->intVal)); }; s.addMethodHandler(1, longEchoCallback); @@ -500,12 +500,12 @@ BOOST_AUTO_TEST_CASE(AddSignalInRuntime) connect(s, c); std::atomic_bool isHandlerACalled(false); - auto handlerA = [&isHandlerACalled](const PeerID, std::shared_ptr&) { + auto handlerA = [&isHandlerACalled](const FileDescriptor, std::shared_ptr&) { isHandlerACalled = true; }; std::atomic_bool isHandlerBCalled(false); - auto handlerB = [&isHandlerBCalled](const PeerID, std::shared_ptr&) { + auto handlerB = [&isHandlerBCalled](const FileDescriptor, std::shared_ptr&) { isHandlerBCalled = true; }; @@ -528,12 +528,12 @@ BOOST_AUTO_TEST_CASE(AddSignalOffline) Client c(socketPath); std::atomic_bool isHandlerACalled(false); - auto handlerA = [&isHandlerACalled](const PeerID, std::shared_ptr&) { + auto handlerA = [&isHandlerACalled](const FileDescriptor, std::shared_ptr&) { isHandlerACalled = true; }; std::atomic_bool isHandlerBCalled(false); - auto handlerB = [&isHandlerBCalled](const PeerID, std::shared_ptr&) { + auto handlerB = [&isHandlerBCalled](const FileDescriptor, std::shared_ptr&) { isHandlerBCalled = true; }; -- 2.7.4