From 11ddb3bab10b043797aca9eaa491070aa8510f3d Mon Sep 17 00:00:00 2001
From: Piotr Bartosiewicz
Date: Thu, 18 Sep 2014 10:07:15 +0200
Subject: [PATCH 01/16] New get_container_id_by_pid API function
[Bug/Feature] Introduce new API function: sc_get_container_id_by_pid
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: I8bee78c062bcbbe29fc9e2c651989570c26869d1
---
client/security-containers-client-impl.cpp | 36 +++++++++
client/security-containers-client-impl.hpp | 5 ++
client/security-containers-client.cpp | 5 ++
client/security-containers-client.h | 11 +++
client/utils.cpp | 118 ++++++++++++++++++++++++++++
client/utils.hpp | 32 ++++++++
tests/unit_tests/client/ut-client-utils.cpp | 55 +++++++++++++
tests/unit_tests/client/ut-client.cpp | 37 +++++++++
8 files changed, 299 insertions(+)
create mode 100644 client/utils.cpp
create mode 100644 client/utils.hpp
create mode 100644 tests/unit_tests/client/ut-client-utils.cpp
diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp
index 8486ae7..a2c51ba 100644
--- a/client/security-containers-client-impl.cpp
+++ b/client/security-containers-client-impl.cpp
@@ -25,6 +25,7 @@
#include
#include "security-containers-client-impl.hpp"
+#include "utils.hpp"
#include
#include
#include
@@ -33,6 +34,7 @@
#include
#include
+#include
using namespace std;
using namespace dbus;
@@ -122,6 +124,17 @@ ScStatus toStatus(const std::exception& ex)
return SCCLIENT_OTHER_ERROR;
}
+bool readFirstLineOfFile(const std::string& path, std::string& ret)
+{
+ std::ifstream file(path);
+ if (!file) {
+ return false;
+ }
+
+ std::getline(file, ret);
+ return true;
+}
+
} //namespace
ScStatus Client::sc_start_glib_loop() noexcept
@@ -309,6 +322,29 @@ ScStatus Client::sc_get_active_container_id(ScString* id) noexcept
return ret;
}
+ScStatus Client::sc_get_container_id_by_pid(int pid, ScString* id) noexcept
+{
+ assert(id);
+
+ const std::string path = "/proc/" + std::to_string(pid) + "/cpuset";
+
+ std::string cpuset;
+ if (!readFirstLineOfFile(path, cpuset)) {
+ mStatus = Status(SCCLIENT_INVALID_ARGUMENT, "Process not found");
+ return sc_get_status();
+ }
+
+ std::string containerId;
+ if (!parseContainerIdFromCpuSet(cpuset, containerId)) {
+ mStatus = Status(SCCLIENT_OTHER_ERROR, "unknown format of cpuset");
+ return sc_get_status();
+ }
+
+ *id = strdup(containerId.c_str());
+ mStatus = Status();
+ return sc_get_status();;
+}
+
ScStatus Client::sc_set_active_container(const char* id) noexcept
{
assert(id);
diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp
index 10aecaf..f1bfacb 100644
--- a/client/security-containers-client-impl.hpp
+++ b/client/security-containers-client-impl.hpp
@@ -117,6 +117,11 @@ public:
ScStatus sc_get_active_container_id(ScString* id) noexcept;
/**
+ * @see ::sc_get_container_id_by_pid
+ */
+ ScStatus sc_get_container_id_by_pid(int pid, ScString* id) noexcept;
+
+ /**
* @see ::sc_set_active_container
*/
ScStatus sc_set_active_container(const char* id) noexcept;
diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp
index b1eb521..cb22544 100644
--- a/client/security-containers-client.cpp
+++ b/client/security-containers-client.cpp
@@ -121,6 +121,11 @@ API ScStatus sc_get_active_container_id(ScClient client, ScString* id)
return getClient(client).sc_get_active_container_id(id);
}
+API ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id)
+{
+ return getClient(client).sc_get_container_id_by_pid(pid, id);
+}
+
API ScStatus sc_set_active_container(ScClient client, const char* id)
{
return getClient(client).sc_set_active_container(id);
diff --git a/client/security-containers-client.h b/client/security-containers-client.h
index c56e9de..4d37c3c 100644
--- a/client/security-containers-client.h
+++ b/client/security-containers-client.h
@@ -247,6 +247,17 @@ ScStatus sc_get_container_ids(ScClient client, ScArrayString* array);
ScStatus sc_get_active_container_id(ScClient client, ScString* id);
/**
+ * Get container name of process with given pid.
+ *
+ * @param[in] client security-containers-server's client
+ * @param[in] pid process id
+ * @param[out] id active container name
+ * @return status of this function call
+ * @remark Use @p sc_string_free() to free memory occupied by @p id.
+ */
+ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id);
+
+/**
* Set active (foreground) container.
*
* @param[in] client security-containers-server's client
diff --git a/client/utils.cpp b/client/utils.cpp
new file mode 100644
index 0000000..98b6905
--- /dev/null
+++ b/client/utils.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 Utility functions definition
+ */
+
+#include "config.hpp"
+#include "utils.hpp"
+
+#include
+
+namespace {
+
+const std::string CPUSET_HOST = "/";
+const std::string CPUSET_LIBVIRT_PREFIX_OLD = "/machine/";
+const std::string CPUSET_LIBVIRT_SUFFIX_OLD = ".libvirt-lxc";
+const std::string CPUSET_LIBVIRT_PREFIX = "/machine.slice/machine-lxc\\x2d";
+const std::string CPUSET_LIBVIRT_SUFFIX = ".scope";
+
+bool parseOldFormat(const std::string& cpuset, std::string& id)
+{
+ // '/machine/.libvirt-lxc'
+ if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX_OLD)) {
+ return false;
+ }
+
+ if (!boost::ends_with(cpuset, CPUSET_LIBVIRT_SUFFIX_OLD)) {
+ return false;
+ }
+
+ id.assign(cpuset,
+ CPUSET_LIBVIRT_PREFIX_OLD.size(),
+ cpuset.size() - CPUSET_LIBVIRT_PREFIX_OLD.size() - CPUSET_LIBVIRT_SUFFIX_OLD.size());
+ return true;
+}
+
+inline int unhex(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ return -1;
+}
+
+void unescape(std::string& value)
+{
+ const size_t len = value.size();
+ size_t inPos = 0;
+ size_t outPos = 0;
+ while (inPos < len) {
+ const char c = value[inPos++];
+ if (c == '-') {
+ value[outPos++] = '/';
+ } else if (c == '\\' && value[inPos] == 'x') {
+ const char a = unhex(value[inPos+1]);
+ const char b = unhex(value[inPos+2]);
+ value[outPos++] = (char) ((a << 4) | b);
+ inPos += 3;
+ } else {
+ value[outPos++] = c;
+ }
+ }
+ value.resize(outPos);
+}
+
+bool parseNewFormat(const std::string& cpuset, std::string& id)
+{
+ // '/machine.slice/machine-lxc\x2d.scope'
+ if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX)) {
+ return false;
+ }
+
+ if (!boost::ends_with(cpuset, CPUSET_LIBVIRT_SUFFIX)) {
+ return false;
+ }
+
+ id = cpuset.substr(CPUSET_LIBVIRT_PREFIX.size(),
+ cpuset.size() - CPUSET_LIBVIRT_PREFIX.size() - CPUSET_LIBVIRT_SUFFIX.size());
+ unescape(id);
+ return true;
+}
+
+} // namespace
+
+bool parseContainerIdFromCpuSet(const std::string& cpuset, std::string& id)
+{
+ if (cpuset == CPUSET_HOST) {
+ id = "host";
+ return true;
+ }
+
+ return parseNewFormat(cpuset, id) || parseOldFormat(cpuset, id);
+}
+
diff --git a/client/utils.hpp b/client/utils.hpp
new file mode 100644
index 0000000..49b83c0
--- /dev/null
+++ b/client/utils.hpp
@@ -0,0 +1,32 @@
+/*
+ * 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 Utility functions declaration
+ */
+
+#ifndef SECURITY_CONTAINERS_CLIENT_UTILS_HPP
+#define SECURITY_CONTAINERS_CLIENT_UTILS_HPP
+
+#include
+
+bool parseContainerIdFromCpuSet(const std::string& cpuset, std::string& id);
+
+#endif // SECURITY_CONTAINERS_CLIENT_UTILS_HPP
diff --git a/tests/unit_tests/client/ut-client-utils.cpp b/tests/unit_tests/client/ut-client-utils.cpp
new file mode 100644
index 0000000..ac4c1fd
--- /dev/null
+++ b/tests/unit_tests/client/ut-client-utils.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 Unit tests of the client utils
+ */
+
+#include
+#include "ut.hpp"
+#include
+
+
+BOOST_AUTO_TEST_SUITE(ClientUtils)
+
+BOOST_AUTO_TEST_CASE(ParseContainerIdFromCpuSetTest)
+{
+ auto testBad = [](const std::string& input) {
+ std::string ret;
+ BOOST_CHECK(!parseContainerIdFromCpuSet(input, ret));
+ };
+
+ auto testOK = [](const std::string& input, const std::string& expected) {
+ std::string ret;
+ BOOST_CHECK(parseContainerIdFromCpuSet(input, ret));
+ BOOST_CHECK_EQUAL(expected, ret);
+ };
+
+ testBad("");
+ testBad("/foo");
+
+ testOK("/", "host");
+ testOK("/machine/a-b.libvirt-lxc", "a-b");
+ testOK("/machine.slice/machine-lxc\\x2da\\x2db.scope", "a-b");
+ testOK("/machine.slice/machine-lxc\\x2da-b.scope", "a/b");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp
index bbf2013..574be39 100644
--- a/tests/unit_tests/client/ut-client.cpp
+++ b/tests/unit_tests/client/ut-client.cpp
@@ -256,4 +256,41 @@ BOOST_AUTO_TEST_CASE(NotificationTest)
}
}
+BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest1)
+{
+ ScClient client = sc_client_create();
+ ScString container;
+ ScStatus status = sc_get_container_id_by_pid(client, 1, &container);
+ BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status);
+
+ BOOST_CHECK_EQUAL(container, std::string("host"));
+
+ sc_string_free(container);
+ sc_client_free(client);
+}
+
+BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest2)
+{
+ std::set ids;
+
+ ScClient client = sc_client_create();
+ for (int n = 0; n < 100000; ++n) {
+ ScString container;
+ ScStatus status = sc_get_container_id_by_pid(client, n, &container);
+ if (status == SCCLIENT_SUCCESS) {
+ ids.insert(container);
+ sc_string_free(container);
+ } else {
+ BOOST_WARN_MESSAGE(status == SCCLIENT_INVALID_ARGUMENT, sc_get_status_message(client));
+ }
+ }
+ sc_client_free(client);
+
+ BOOST_CHECK(ids.count("host") == 1);
+
+ for (const auto& dbus : EXPECTED_DBUSES_STARTED) {
+ BOOST_CHECK(ids.count(dbus.first) == 1);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
--
2.7.4
From ca9fe3b7e0eb6a308dd1215fd427bd97369f04ac Mon Sep 17 00:00:00 2001
From: Jan Olszak
Date: Wed, 24 Sep 2014 16:12:13 +0200
Subject: [PATCH 02/16] Adjusting tests to the changed KVStore
[Bug/Feature] Added isEmpty() and exists() functions
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: Ied7f469599cfdb31104e4f0bc1b67b8cbc2a2cc0
---
tests/unit_tests/config/ut-configuration.cpp | 22 ++++++++++++++++---
tests/unit_tests/config/ut-kvstore.cpp | 32 +++++++++++-----------------
2 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp
index 1e98d22..b205339 100644
--- a/tests/unit_tests/config/ut-configuration.cpp
+++ b/tests/unit_tests/config/ut-configuration.cpp
@@ -48,11 +48,13 @@ struct TestConfig {
};
int intVal;
+ std::vector intVector;
SubSubConfig subSubObj;
CONFIG_REGISTER
(
intVal,
+ intVector,
subSubObj
)
};
@@ -63,6 +65,7 @@ struct TestConfig {
double doubleVal;
bool boolVal;
+ std::vector emptyIntVector;
std::vector intVector;
std::vector stringVector;
std::vector doubleVector;
@@ -78,6 +81,7 @@ struct TestConfig {
doubleVal,
boolVal,
+ emptyIntVector,
intVector,
stringVector,
doubleVector,
@@ -98,12 +102,13 @@ const std::string jsonTestString =
"\"stringVal\": \"blah\", "
"\"doubleVal\": -1.234000, "
"\"boolVal\": true, "
+ "\"emptyIntVector\": [ ], "
"\"intVector\": [ 1, 2, 3 ], "
"\"stringVector\": [ \"a\", \"b\" ], "
"\"doubleVector\": [ 0.000000, 1.000000, 2.000000 ], "
- "\"subObj\": { \"intVal\": 54321, \"subSubObj\": { \"intVal\": 234 } }, "
- "\"subVector\": [ { \"intVal\": 123, \"subSubObj\": { \"intVal\": 345 } }, "
- "{ \"intVal\": 456, \"subSubObj\": { \"intVal\": 567 } } ] }";
+ "\"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 } } ] }";
// Floating point tolerance as a number of rounding errors
const int TOLERANCE = 1;
@@ -121,6 +126,8 @@ BOOST_AUTO_TEST_CASE(FromStringTest)
BOOST_CHECK_CLOSE(-1.234, testConfig.doubleVal, TOLERANCE);
BOOST_CHECK_EQUAL(true, testConfig.boolVal);
+ BOOST_REQUIRE_EQUAL(0, testConfig.emptyIntVector.size());
+
BOOST_REQUIRE_EQUAL(3, testConfig.intVector.size());
BOOST_CHECK_EQUAL(1, testConfig.intVector[0]);
BOOST_CHECK_EQUAL(2, testConfig.intVector[1]);
@@ -136,12 +143,21 @@ BOOST_AUTO_TEST_CASE(FromStringTest)
BOOST_CHECK_CLOSE(2.0, testConfig.doubleVector[2], TOLERANCE);
BOOST_CHECK_EQUAL(54321, testConfig.subObj.intVal);
+ BOOST_CHECK_EQUAL(2, testConfig.subObj.intVector.size());
+ BOOST_CHECK_EQUAL(1, testConfig.subObj.intVector[0]);
+ BOOST_CHECK_EQUAL(2, testConfig.subObj.intVector[1]);
+ BOOST_CHECK_EQUAL(234, testConfig.subObj.subSubObj.intVal);
BOOST_REQUIRE_EQUAL(2, testConfig.subVector.size());
BOOST_CHECK_EQUAL(123, testConfig.subVector[0].intVal);
BOOST_CHECK_EQUAL(456, testConfig.subVector[1].intVal);
BOOST_CHECK_EQUAL(345, testConfig.subVector[0].subSubObj.intVal);
BOOST_CHECK_EQUAL(567, testConfig.subVector[1].subSubObj.intVal);
+ BOOST_CHECK_EQUAL(3, testConfig.subVector[0].intVector[0]);
+ BOOST_CHECK_EQUAL(5, testConfig.subVector[1].intVector[0]);
+ BOOST_CHECK_EQUAL(4, testConfig.subVector[0].intVector[1]);
+ BOOST_CHECK_EQUAL(6, testConfig.subVector[1].intVector[1]);
+
}
diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp
index 66efc2b..2c9a998 100644
--- a/tests/unit_tests/config/ut-kvstore.cpp
+++ b/tests/unit_tests/config/ut-kvstore.cpp
@@ -114,33 +114,29 @@ BOOST_AUTO_TEST_CASE(EscapedCharactersTest)
std::string HARD_KEY = "[" + KEY;
BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A"));
BOOST_CHECK_NO_THROW(c.set(KEY, "B"));
- BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1);
- BOOST_CHECK_EQUAL(c.count(KEY), 1);
- BOOST_CHECK_EQUAL(c.size(), 2);
+ BOOST_CHECK(c.exists(HARD_KEY));
+ BOOST_CHECK(c.exists(KEY));
BOOST_CHECK_NO_THROW(c.clear());
HARD_KEY = "]" + KEY;
BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A"));
BOOST_CHECK_NO_THROW(c.set(KEY, "B"));
- BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1);
- BOOST_CHECK_EQUAL(c.count(KEY), 1);
- BOOST_CHECK_EQUAL(c.size(), 2);
+ BOOST_CHECK(c.exists(HARD_KEY));
+ BOOST_CHECK(c.exists(KEY));
BOOST_CHECK_NO_THROW(c.clear());
HARD_KEY = "?" + KEY;
BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A"));
BOOST_CHECK_NO_THROW(c.set(KEY, "B"));
- BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1);
- BOOST_CHECK_EQUAL(c.count(KEY), 1);
- BOOST_CHECK_EQUAL(c.size(), 2);
+ BOOST_CHECK(c.exists(HARD_KEY));
+ BOOST_CHECK(c.exists(KEY));
BOOST_CHECK_NO_THROW(c.clear());
HARD_KEY = "*" + KEY;
BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A"));
BOOST_CHECK_NO_THROW(c.set(KEY, "B"));
- BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1);
- BOOST_CHECK_EQUAL(c.count(KEY), 1);
- BOOST_CHECK_EQUAL(c.size(), 2);
+ BOOST_CHECK(c.exists(HARD_KEY));
+ BOOST_CHECK(c.exists(KEY));
}
namespace {
@@ -154,11 +150,11 @@ void testSingleValue(Fixture& f, const A& a, const B& b)
// Update
BOOST_CHECK_NO_THROW(f.c.set(KEY, b));
BOOST_CHECK_EQUAL(f.c.get(KEY), b);
- BOOST_CHECK_EQUAL(f.c.count(KEY), 1);
+ BOOST_CHECK(f.c.exists(KEY));
// Remove
BOOST_CHECK_NO_THROW(f.c.remove(KEY));
- BOOST_CHECK_EQUAL(f.c.count(KEY), 0);
+ BOOST_CHECK(!f.c.exists(KEY));
BOOST_CHECK_THROW(f.c.get(KEY), ConfigException);
}
} // namespace
@@ -182,8 +178,6 @@ void setVector(Fixture& f, std::vector vec)
BOOST_CHECK_NO_THROW(f.c.set(KEY, vec));
BOOST_CHECK_NO_THROW(storedVec = f.c.get >(KEY))
BOOST_CHECK_EQUAL_COLLECTIONS(storedVec.begin(), storedVec.end(), vec.begin(), vec.end());
- BOOST_CHECK_EQUAL(f.c.count(KEY), vec.size());
- BOOST_CHECK_EQUAL(f.c.size(), vec.size());
}
template
@@ -199,8 +193,8 @@ void testVectorOfValues(Fixture& f,
// Remove
BOOST_CHECK_NO_THROW(f.c.remove(KEY));
- BOOST_CHECK_EQUAL(f.c.count(KEY), 0);
- BOOST_CHECK_EQUAL(f.c.size(), 0);
+ BOOST_CHECK(!f.c.exists(KEY));
+ BOOST_CHECK(f.c.isEmpty());
BOOST_CHECK_THROW(f.c.get >(KEY), ConfigException);
BOOST_CHECK_THROW(f.c.get(KEY), ConfigException);
}
@@ -221,7 +215,7 @@ BOOST_AUTO_TEST_CASE(ClearTest)
std::vector vec = {"A", "B"};
BOOST_CHECK_NO_THROW(c.set(KEY, vec));
BOOST_CHECK_NO_THROW(c.clear());
- BOOST_CHECK_EQUAL(c.size(), 0);
+ BOOST_CHECK(c.isEmpty());
BOOST_CHECK_NO_THROW(c.remove(KEY));
BOOST_CHECK_THROW(c.get>(KEY), ConfigException);
--
2.7.4
From 2d2f8fe00f8c450895a2ef67a698746294d25a0b Mon Sep 17 00:00:00 2001
From: Lukasz Kostyra
Date: Thu, 25 Sep 2014 11:59:58 +0200
Subject: [PATCH 03/16] Implement switchingSequenceMonitorNotify and add VT
switching support
[Feature] switchingSequenceMonitorNotify function implementation and module to handle VT
switching
[Cause] Nothing happened when user provided input sequence to Input Monitor
[Solution] Implemented switchingSequenceMonitorNotify and added VT switching to function
ContainersManager::focus.
[Verification] Build, install, run unit tests. Tests (especially FocusTest) should pass.
Change-Id: Ie4aa7d1679bfaa5a0fdfaf238ebc14a3b8150006
---
CMakeLists.txt | 4 +
common/utils/img.cpp | 2 +-
common/utils/img.hpp | 2 +-
common/utils/vt.cpp | 86 ++++++++++++++++++++++
common/utils/vt.hpp | 36 +++++++++
packaging/security-containers.spec | 7 +-
server/CMakeLists.txt | 2 +-
server/configs/containers/business.conf | 3 +-
server/configs/containers/private.conf | 3 +-
server/container-config.hpp | 6 ++
server/container.cpp | 12 +++
server/container.hpp | 7 ++
server/containers-manager.cpp | 28 ++++++-
server/containers-manager.hpp | 6 ++
server/server.cpp | 11 ++-
.../ut-client/containers/console1-dbus.conf | 1 +
.../ut-client/containers/console2-dbus.conf | 1 +
.../ut-client/containers/console3-dbus.conf | 1 +
.../ut-container-admin/containers/buggy.conf.in | 1 +
.../ut-container-admin/containers/missing.conf | 1 +
.../containers/test-no-shutdown.conf.in | 1 +
.../ut-container-admin/containers/test.conf.in | 1 +
.../configs/ut-container/containers/buggy.conf | 1 +
.../configs/ut-container/containers/test-dbus.conf | 1 +
.../configs/ut-container/containers/test.conf | 1 +
.../containers/console1-dbus.conf | 1 +
.../ut-containers-manager/containers/console1.conf | 1 +
.../containers/console2-dbus.conf | 1 +
.../ut-containers-manager/containers/console2.conf | 1 +
.../containers/console3-dbus.conf | 1 +
.../ut-containers-manager/containers/console3.conf | 1 +
.../ut-containers-manager/templates/template.conf | 1 +
.../ut-network-admin/containers/buggy.conf.in | 1 +
.../ut-network-admin/containers/missing.conf | 1 +
.../ut-network-admin/containers/test.conf.in | 1 +
.../configs/ut-server/containers/container1.conf | 1 +
.../configs/ut-server/containers/container2.conf | 1 +
.../configs/ut-server/containers/container3.conf | 1 +
38 files changed, 228 insertions(+), 10 deletions(-)
create mode 100644 common/utils/vt.cpp
create mode 100644 common/utils/vt.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9cb880a..c8e74c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,11 +72,15 @@ ENDIF(NOT DEFINED INPUT_EVENT_GROUP)
IF(NOT DEFINED DISK_GROUP)
SET(DISK_GROUP "disk")
ENDIF(NOT DEFINED DISK_GROUP)
+IF(NOT DEFINED TTY_GROUP)
+ SET(TTY_GROUP "tty")
+ENDIF(NOT DEFINED TTY_GROUP)
ADD_DEFINITIONS(-DSECURITY_CONTAINERS_USER="${SECURITY_CONTAINERS_USER}")
ADD_DEFINITIONS(-DLIBVIRT_GROUP="${LIBVIRT_GROUP}")
ADD_DEFINITIONS(-DINPUT_EVENT_GROUP="${INPUT_EVENT_GROUP}")
ADD_DEFINITIONS(-DDISK_GROUP="${DISK_GROUP}")
+ADD_DEFINITIONS(-DTTY_GROUP="${TTY_GROUP}")
## Python packages directory ###################################################
diff --git a/common/utils/img.cpp b/common/utils/img.cpp
index 4d7de88..bc77491 100644
--- a/common/utils/img.cpp
+++ b/common/utils/img.cpp
@@ -17,7 +17,7 @@
*/
/**
- * @file img.hpp
+ * @file
* @author Lukasz Kostyra (l.kostyra@samsung.com)
* @brief Image utility functions declaration
*/
diff --git a/common/utils/img.hpp b/common/utils/img.hpp
index d42300e..db47cc6 100644
--- a/common/utils/img.hpp
+++ b/common/utils/img.hpp
@@ -17,7 +17,7 @@
*/
/**
- * @file img.hpp
+ * @file
* @author Lukasz Kostyra (l.kostyra@samsung.com)
* @brief Image utility functions declaration
*/
diff --git a/common/utils/vt.cpp b/common/utils/vt.cpp
new file mode 100644
index 0000000..22a697e
--- /dev/null
+++ b/common/utils/vt.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Lukasz Kostyra
+ *
+ * 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 Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief VT-related utility functions
+ */
+
+#include "config.hpp"
+#include "utils/vt.hpp"
+#include "logger/logger.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace {
+
+const std::string TTY_DEV = "/dev/tty0";
+
+} // namespace
+
+namespace security_containers {
+namespace utils {
+
+bool activateVT(const int& vt)
+{
+ int consoleFD = ::open(TTY_DEV.c_str(), O_WRONLY);
+ if (consoleFD < 0) {
+ LOGE("console open failed: " << errno << " (" << strerror(errno) << ")");
+ return false;
+ }
+
+ struct vt_stat vtstat;
+ vtstat.v_active = 0;
+ if (::ioctl(consoleFD, VT_GETSTATE, &vtstat)) {
+ LOGE("Failed to get vt state: " << errno << " (" << strerror(errno) << ")");
+ ::close(consoleFD);
+ return false;
+ }
+
+ if (vtstat.v_active == vt) {
+ LOGW("vt" << vt << " is already active.");
+ ::close(consoleFD);
+ return true;
+ }
+
+ // activate vt
+ if (::ioctl(consoleFD, VT_ACTIVATE, vt)) {
+ LOGE("Failed to activate vt" << vt << ": " << errno << " (" << strerror(errno) << ")");
+ ::close(consoleFD);
+ return false;
+ }
+
+ // wait until activation is finished
+ if (::ioctl(consoleFD, VT_WAITACTIVE, vt)) {
+ LOGE("Failed to wait for vt" << vt << " activation: " << errno << " (" << strerror(errno) << ")");
+ ::close(consoleFD);
+ return false;
+ }
+
+ ::close(consoleFD);
+ return true;
+}
+
+} // namespace utils
+} // namespace security_containers
diff --git a/common/utils/vt.hpp b/common/utils/vt.hpp
new file mode 100644
index 0000000..d285806
--- /dev/null
+++ b/common/utils/vt.hpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Lukasz Kostyra
+ *
+ * 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 Lukasz Kostyra (l.kostyra@samsung.com)
+ * @brief VT-related utility functions
+ */
+
+#ifndef COMMON_UTILS_VT_HPP
+#define COMMON_UTILS_VT_HPP
+
+namespace security_containers {
+namespace utils {
+
+bool activateVT(const int& vt);
+
+} // namespace utils
+} // namespace security_containers
+
+#endif // COMMON_UTILS_VT_HPP
diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec
index 97bf4d5..fc1c806 100644
--- a/packaging/security-containers.spec
+++ b/packaging/security-containers.spec
@@ -7,6 +7,8 @@
%define input_event_group video
# The group has access to /dev/loop* devices.
%define disk_group disk
+# The group that has write access to /dev/tty* devices.
+%define tty_group tty
Name: security-containers
Version: 0.1.1
@@ -71,7 +73,8 @@ between them. A process from inside a container can request a switch of context
-DSECURITY_CONTAINERS_USER=%{scs_user} \
-DLIBVIRT_GROUP=%{libvirt_group} \
-DINPUT_EVENT_GROUP=%{input_event_group} \
- -DDISK_GROUP=%{disk_group}
+ -DDISK_GROUP=%{disk_group} \
+ -DTTY_GROUP=%{tty_group}
make -k %{?jobs:-j%jobs}
%install
@@ -88,7 +91,7 @@ if [ $1 == 1 ]; then
systemctl daemon-reload || :
fi
# set needed caps on the binary to allow restart without loosing them
-setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE+ei %{_bindir}/security-containers-server
+setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE,CAP_SYS_TTY_CONFIG+ei %{_bindir}/security-containers-server
%preun
# Stop the service before uninstall
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
index 3293307..2237f52 100644
--- a/server/CMakeLists.txt
+++ b/server/CMakeLists.txt
@@ -45,4 +45,4 @@ ADD_SUBDIRECTORY(configs)
INSTALL(TARGETS ${SERVER_CODENAME} DESTINATION bin)
## Set capabilities on server executable #######################################
-INSTALL(CODE "EXECUTE_PROCESS(COMMAND setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE+ei \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/bin/${SERVER_CODENAME})")
+INSTALL(CODE "EXECUTE_PROCESS(COMMAND setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE,CAP_SYS_TTY_CONFIG+ei \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/bin/${SERVER_CODENAME})")
diff --git a/server/configs/containers/business.conf b/server/configs/containers/business.conf
index 1b3502a..600edb1 100644
--- a/server/configs/containers/business.conf
+++ b/server/configs/containers/business.conf
@@ -1,8 +1,9 @@
{
"cpuQuotaForeground" : -1,
- "cpuQuotaBackground" : 1000,
+ "cpuQuotaBackground" : 10000,
"enableDbusIntegration" : true,
"privilege" : 1,
+ "vt" : 3,
"switchToDefaultAfterTimeout" : true,
"config" : "../libvirt-config/business.xml",
"networkConfig" : "../libvirt-config/business-network.xml",
diff --git a/server/configs/containers/private.conf b/server/configs/containers/private.conf
index 62c0f18..71d4bcb 100644
--- a/server/configs/containers/private.conf
+++ b/server/configs/containers/private.conf
@@ -1,8 +1,9 @@
{
"cpuQuotaForeground" : -1,
- "cpuQuotaBackground" : 1000,
+ "cpuQuotaBackground" : 10000,
"enableDbusIntegration" : true,
"privilege" : 10,
+ "vt" : 2,
"switchToDefaultAfterTimeout" : true,
"config" : "../libvirt-config/private.xml",
"networkConfig" : "../libvirt-config/private-network.xml",
diff --git a/server/container-config.hpp b/server/container-config.hpp
index b506770..e0c6760 100644
--- a/server/container-config.hpp
+++ b/server/container-config.hpp
@@ -43,6 +43,11 @@ struct ContainerConfig {
int privilege;
/**
+ * Number of virtual terminal used by xserver inside container
+ */
+ int vt;
+
+ /**
* Allow switching to default container after timeout.
* Setting this to false will disable switching to default container after timeout.
*/
@@ -101,6 +106,7 @@ struct ContainerConfig {
CONFIG_REGISTER
(
privilege,
+ vt,
switchToDefaultAfterTimeout,
enableDbusIntegration,
config,
diff --git a/server/container.cpp b/server/container.cpp
index 494b0ae..59328db 100644
--- a/server/container.cpp
+++ b/server/container.cpp
@@ -29,6 +29,7 @@
#include "logger/logger.hpp"
#include "utils/paths.hpp"
+#include "utils/vt.hpp"
#include "config/manager.hpp"
#include
@@ -210,6 +211,17 @@ std::string Container::getDbusAddress()
return mDbusAddress;
}
+bool Container::activateVT()
+{
+ Lock lock(mReconnectMutex);
+
+ if (mConfig.vt >= 0) {
+ return utils::activateVT(mConfig.vt);
+ }
+
+ return true;
+}
+
void Container::goForeground()
{
Lock lock(mReconnectMutex);
diff --git a/server/container.hpp b/server/container.hpp
index f741464..6800f7a 100644
--- a/server/container.hpp
+++ b/server/container.hpp
@@ -101,6 +101,13 @@ public:
void stop();
/**
+ * Activate this container's VT
+ *
+ * @return Was activation successful?
+ */
+ bool activateVT();
+
+ /**
* Setup this container to be put in the foreground.
* I.e. set appropriate scheduler level.
*/
diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp
index 5dc909b..d8858ab 100644
--- a/server/containers-manager.cpp
+++ b/server/containers-manager.cpp
@@ -183,6 +183,11 @@ void ContainersManager::focus(const std::string& containerId)
/* try to access the object first to throw immediately if it doesn't exist */
ContainerMap::mapped_type& foregroundContainer = mContainers.at(containerId);
+ if (!foregroundContainer->activateVT()) {
+ LOGE("Failed to activate containers VT. Aborting focus.");
+ return;
+ }
+
for (auto& container : mContainers) {
LOGD(container.second->getId() << ": being sent to background");
container.second->goBackground();
@@ -240,10 +245,31 @@ std::string ContainersManager::getRunningForegroundContainerId()
return std::string();
}
+std::string ContainersManager::getNextToForegroundContainerId()
+{
+ // handles case where there is no next container
+ if (mContainers.size() < 2) {
+ return std::string();
+ }
+
+ for (auto it = mContainers.begin(); it != mContainers.end(); ++it) {
+ if (it->first == mConfig.foregroundId &&
+ it->second->isRunning()) {
+ auto nextIt = std::next(it);
+ if (nextIt != mContainers.end()) {
+ return nextIt->first;
+ }
+ }
+ }
+ return mContainers.begin()->first;
+}
+
void ContainersManager::switchingSequenceMonitorNotify()
{
LOGI("switchingSequenceMonitorNotify() called");
- // TODO: implement
+
+ auto nextContainerId = getNextToForegroundContainerId();
+ focus(nextContainerId);
}
diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp
index cd1194d..3cbf833 100644
--- a/server/containers-manager.hpp
+++ b/server/containers-manager.hpp
@@ -78,6 +78,12 @@ public:
std::string getRunningForegroundContainerId();
/**
+ * @return id of next to currently focused/foreground container. If currently focused container
+ * is last in container map, id of fisrt container from map is returned.
+ */
+ std::string getNextToForegroundContainerId();
+
+ /**
* Set whether ContainersManager should detach containers on exit
*/
void setContainersDetachOnExit();
diff --git a/server/server.cpp b/server/server.cpp
index 547d023..a9ad444 100644
--- a/server/server.cpp
+++ b/server/server.cpp
@@ -62,6 +62,10 @@
#error "DISK_GROUP must be defined!"
#endif
+#ifndef TTY_GROUP
+#error "TTY_GROUP must be defined!"
+#endif
+
extern char** environ;
namespace security_containers {
@@ -189,7 +193,7 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot)
// INPUT_EVENT_GROUP provides access to /dev/input/event* devices used by InputMonitor.
// DISK_GROUP provides access to /dev/loop* devices, needed when adding new container to copy
// containers image
- if (!utils::setSuppGroups({LIBVIRT_GROUP, INPUT_EVENT_GROUP, DISK_GROUP})) {
+ if (!utils::setSuppGroups({LIBVIRT_GROUP, INPUT_EVENT_GROUP, DISK_GROUP, TTY_GROUP})) {
return false;
}
@@ -197,7 +201,10 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot)
// NOTE: CAP_MAC_OVERRIDE is temporary and must be removed when "smack namespace"
// is introduced. The capability is needed to allow modify SMACK labels of
// "/var/run/containers//run" mount point.
- return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, CAP_MAC_OVERRIDE}));
+ // CAP_SYS_TTY_CONFIG is needed to activate virtual terminals through ioctl calls
+ return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN,
+ CAP_MAC_OVERRIDE,
+ CAP_SYS_TTY_CONFIG}));
}
diff --git a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf
index e16f7d6..b32dd81 100644
--- a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf
+++ b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console1-dbus.xml",
diff --git a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf
index 9aa8e51..3dda658 100644
--- a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf
+++ b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : false,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console2-dbus.xml",
diff --git a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf
index 09ef262..0128c09 100644
--- a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf
+++ b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console3-dbus.xml",
diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in
index 6a0ba2d..f9f553e 100644
--- a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in
+++ b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/buggy.xml",
diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf
index 4184401..8312204 100644
--- a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf
+++ b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "/this/is/a/missing/file/path/missing.xml",
diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in
index 995f5ff..135654c 100644
--- a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in
+++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test-no-shutdown.xml",
diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in
index a1d3d53..de566ea 100644
--- a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in
+++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test.xml",
diff --git a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf
index 5992433..d0a307e 100644
--- a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf
+++ b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "/missing/file/path/libvirt.xml",
diff --git a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf
index 6301a5a..a272aa1 100644
--- a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf
+++ b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/test-dbus.xml",
diff --git a/tests/unit_tests/server/configs/ut-container/containers/test.conf b/tests/unit_tests/server/configs/ut-container/containers/test.conf
index 111d9ee..bed56de 100644
--- a/tests/unit_tests/server/configs/ut-container/containers/test.conf
+++ b/tests/unit_tests/server/configs/ut-container/containers/test.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/test.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf
index e16f7d6..b32dd81 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console1-dbus.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf
index be47df6..884e56d 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/console1.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf
index 9aa8e51..3dda658 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : false,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console2-dbus.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf
index 4c88170..9928914 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/console2.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf
index 09ef262..0128c09 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/console3-dbus.xml",
diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf
index d6bc429..8a31b50 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf
@@ -1,5 +1,6 @@
{
"privilege" : 15,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/console3.xml",
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
index 40dcacc..aeed716 100644
--- a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf
+++ b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"config" : "../libvirt-config/~NAME~.xml",
"networkConfig" : "../libvirt-config/~NAME~-network.xml",
diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in
index 414b920..695ed15 100644
--- a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in
+++ b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "",
diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf
index 13ccc44..76492bb 100644
--- a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf
+++ b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "",
diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in
index be65ee2..990da9a 100644
--- a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in
+++ b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "",
diff --git a/tests/unit_tests/server/configs/ut-server/containers/container1.conf b/tests/unit_tests/server/configs/ut-server/containers/container1.conf
index 21fb52a..984e973 100644
--- a/tests/unit_tests/server/configs/ut-server/containers/container1.conf
+++ b/tests/unit_tests/server/configs/ut-server/containers/container1.conf
@@ -1,5 +1,6 @@
{
"privilege" : 20,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/container1.xml",
diff --git a/tests/unit_tests/server/configs/ut-server/containers/container2.conf b/tests/unit_tests/server/configs/ut-server/containers/container2.conf
index 6302a39..d340530 100644
--- a/tests/unit_tests/server/configs/ut-server/containers/container2.conf
+++ b/tests/unit_tests/server/configs/ut-server/containers/container2.conf
@@ -1,5 +1,6 @@
{
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/container2.xml",
diff --git a/tests/unit_tests/server/configs/ut-server/containers/container3.conf b/tests/unit_tests/server/configs/ut-server/containers/container3.conf
index b445156..a9d9e97 100644
--- a/tests/unit_tests/server/configs/ut-server/containers/container3.conf
+++ b/tests/unit_tests/server/configs/ut-server/containers/container3.conf
@@ -1,5 +1,6 @@
{
"privilege" : 15,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : false,
"config" : "../libvirt-config/container3.xml",
--
2.7.4
From 634bae3b8623ea01c1204613d69122e280cf08e5 Mon Sep 17 00:00:00 2001
From: Jan Olszak
Date: Fri, 3 Oct 2014 18:20:30 +0200
Subject: [PATCH 04/16] Tests of the serialization functions from libConfig
[Bug/Feature] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run tests
Change-Id: Ifa9e3397f4405cf4d9d1bcca2c891eb789cdf2ae
---
tests/unit_tests/config/ut-configuration.cpp | 26 ++++++++++++++++++++++++++
tests/unit_tests/config/ut-kvstore.cpp | 1 +
2 files changed, 27 insertions(+)
diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp
index b205339..1d72bd8 100644
--- a/tests/unit_tests/config/ut-configuration.cpp
+++ b/tests/unit_tests/config/ut-configuration.cpp
@@ -27,6 +27,9 @@
#include "ut.hpp"
#include "config/fields.hpp"
#include "config/manager.hpp"
+#include
+#include
+#include
#include
namespace fs = boost::filesystem;
@@ -316,6 +319,29 @@ BOOST_AUTO_TEST_CASE(FromToKVStoreTest)
BOOST_CHECK_EQUAL(out, jsonTestString);
fs::remove(dbPath);
+ fs::remove(dbPath + "-journal");
+}
+
+BOOST_AUTO_TEST_CASE(FromToFDTest)
+{
+ TestConfig config;
+ loadFromString(jsonTestString, config);
+ // Setup fd
+ std::string fifoPath = fs::unique_path("/tmp/fdstore-%%%%").string();
+ BOOST_CHECK(::mkfifo(fifoPath.c_str(), S_IWUSR | S_IRUSR) >= 0);
+ int fd = ::open(fifoPath.c_str(), O_RDWR);
+ BOOST_REQUIRE(fd >= 0);
+
+ // The test
+ saveToFD(fd, config);
+ TestConfig outConfig;
+ loadFromFD(fd, outConfig);
+ std::string out = saveToString(outConfig);
+ BOOST_CHECK_EQUAL(out, jsonTestString);
+
+ // Cleanup
+ BOOST_CHECK(::close(fd) >= 0);
+ fs::remove(fifoPath);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp
index 2c9a998..ba95452 100644
--- a/tests/unit_tests/config/ut-kvstore.cpp
+++ b/tests/unit_tests/config/ut-kvstore.cpp
@@ -50,6 +50,7 @@ struct Fixture {
~Fixture()
{
fs::remove(dbPath);
+ fs::remove(dbPath + "-journal");
}
};
--
2.7.4
From 7ce7abac455827aef85ae5a8f369c25ba5331d4f Mon Sep 17 00:00:00 2001
From: Lukasz Kostyra
Date: Mon, 13 Oct 2014 14:02:40 +0200
Subject: [PATCH 05/16] Allow SCS to launch without any container
[Bug] SCS segfaulted when launching without any containers provided in config.
[Cause] Some functions assumed that certain config fields should never be empty
[Solution] Additional checks to avoid segfault.
[Verification] Build, install, run tests, launch SCS without any predefined containers.
Try to switch between containers when less than two containers are present.
Change-Id: I58a69d55807f686fb168057dfb1b447707351a46
---
server/containers-manager.cpp | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp
index d8858ab..c9c7ff8 100644
--- a/server/containers-manager.cpp
+++ b/server/containers-manager.cpp
@@ -112,7 +112,7 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet
}
// check if default container exists, throw ContainerOperationException if not found
- if (mContainers.find(mConfig.defaultId) == mContainers.end()) {
+ if (!mConfig.defaultId.empty() && mContainers.find(mConfig.defaultId) == mContainers.end()) {
LOGE("Provided default container ID " << mConfig.defaultId << " is invalid.");
throw ContainerOperationException("Provided default container ID " + mConfig.defaultId +
" is invalid.");
@@ -219,9 +219,11 @@ void ContainersManager::startAll()
return c1.second->getPrivilege() < c2.second->getPrivilege();
});
- mConfig.foregroundId = foregroundIterator->second->getId();
- LOGI(mConfig.foregroundId << ": no foreground container configured, setting one with highest priority");
- foregroundIterator->second->goForeground();
+ if (foregroundIterator != mContainers.end()) {
+ mConfig.foregroundId = foregroundIterator->second->getId();
+ LOGI(mConfig.foregroundId << ": no foreground container configured, setting one with highest priority");
+ foregroundIterator->second->goForeground();
+ }
}
}
@@ -269,7 +271,10 @@ void ContainersManager::switchingSequenceMonitorNotify()
LOGI("switchingSequenceMonitorNotify() called");
auto nextContainerId = getNextToForegroundContainerId();
- focus(nextContainerId);
+
+ if (!nextContainerId.empty()) {
+ focus(nextContainerId);
+ }
}
--
2.7.4
From b87e6f2d5cce61d806fc6f120b5d50e2f2fa3940 Mon Sep 17 00:00:00 2001
From: Lukasz Kostyra
Date: Wed, 15 Oct 2014 10:13:15 +0200
Subject: [PATCH 06/16] Update missing vt field in container template
[Bug] Field 'vt' was missing in template used to add new containers.
[Cause] N/A
[Solution] N/A
[Verification] Build, install, run freshly added container. SCS should not return "missing config
field 'vt'" error.
Change-Id: Iec9633d3e8a0e727f854a166d6ab7cfc65ccdf5b
---
server/configs/templates/template.conf | 1 +
1 file changed, 1 insertion(+)
diff --git a/server/configs/templates/template.conf b/server/configs/templates/template.conf
index 17480a0..b054fb1 100644
--- a/server/configs/templates/template.conf
+++ b/server/configs/templates/template.conf
@@ -2,6 +2,7 @@
"cpuQuotaForeground" : -1,
"cpuQuotaBackground" : 1000,
"privilege" : 10,
+ "vt" : -1,
"switchToDefaultAfterTimeout" : true,
"enableDbusIntegration" : true,
"config" : "../libvirt-config/~NAME~.xml",
--
2.7.4
From f3330a0e728c9421629d082121f3e3123550e2a9 Mon Sep 17 00:00:00 2001
From: Lukasz Kostyra
Date: Mon, 13 Oct 2014 14:49:29 +0200
Subject: [PATCH 07/16] Adjust configuration files for Tizen:Common profile
[Feature] Configuration files modified for Tizen:Common profile.
[Cause] Tizen:Common devices use different configuration than M0 devices.
[Solution] Change configuration files.
[Verification] Build, install on Tizen:Common device, run tests.
Change-Id: Ib1db585f99ba4e8feecd1defa76de277e3fead0b
---
packaging/security-containers.spec | 2 +-
server/configs/daemon.conf | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec
index fc1c806..3905904 100644
--- a/packaging/security-containers.spec
+++ b/packaging/security-containers.spec
@@ -4,7 +4,7 @@
%define libvirt_group libvirt
# The group that has read and write access to /dev/input/event* devices.
# It may vary between platforms.
-%define input_event_group video
+%define input_event_group input
# The group has access to /dev/loop* devices.
%define disk_group disk
# The group that has write access to /dev/tty* devices.
diff --git a/server/configs/daemon.conf b/server/configs/daemon.conf
index db85284..dbfac95 100644
--- a/server/configs/daemon.conf
+++ b/server/configs/daemon.conf
@@ -8,9 +8,9 @@
"foregroundId" : "private",
"defaultId" : "private",
"inputConfig" : {"enabled" : true,
- "device" : "gpio-keys",
+ "device" : "gpio_keys.6",
"code" : 139,
- "numberOfEvents" : 3,
+ "numberOfEvents" : 1,
"timeWindowMs" : 500},
"proxyCallRules" : []
}
--
2.7.4
From e243eeb1fb3358b321dce9903865257ddaed8e23 Mon Sep 17 00:00:00 2001
From: Mateusz Malicki
Date: Thu, 9 Oct 2014 19:10:11 +0200
Subject: [PATCH 08/16] Command line interface to SCS
[Feature] Command line interface to SCS
[Cause] Need to manage SCS from shell
[Solution] Binary that use libsecurity-containers
[Verification] Build, install, execute security-containers-cli (switch container),
check SCS logs.
Change-Id: Ia6cc1cc00295e19befd2e0987900b69e2d4e7bd3
---
CMakeLists.txt | 2 +
cli/CMakeLists.txt | 37 ++++++++++++
cli/command-line-interface.cpp | 115 +++++++++++++++++++++++++++++++++++++
cli/command-line-interface.hpp | 109 +++++++++++++++++++++++++++++++++++
cli/main.cpp | 74 ++++++++++++++++++++++++
doc/doxygen.cfg | 2 +-
packaging/security-containers.spec | 14 +++++
7 files changed, 352 insertions(+), 1 deletion(-)
create mode 100644 cli/CMakeLists.txt
create mode 100644 cli/command-line-interface.cpp
create mode 100644 cli/command-line-interface.hpp
create mode 100644 cli/main.cpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c8e74c6..f824f8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,6 +99,7 @@ SET(CONTAINER_SUPPORT_FOLDER ${PROJECT_SOURCE_DIR}/container-support)
SET(CONTAINER_DAEMON_FOLDER ${PROJECT_SOURCE_DIR}/container-daemon)
SET(TESTS_FOLDER ${PROJECT_SOURCE_DIR}/tests)
SET(UNIT_TESTS_FOLDER ${TESTS_FOLDER}/unit_tests)
+SET(CLI_FOLDER ${PROJECT_SOURCE_DIR}/cli)
IF(NOT DEFINED SYSCONF_INSTALL_DIR)
SET(SYSCONF_INSTALL_DIR "/etc")
@@ -132,4 +133,5 @@ ADD_SUBDIRECTORY(${SERVER_FOLDER})
ADD_SUBDIRECTORY(${CONTAINER_SUPPORT_FOLDER})
ADD_SUBDIRECTORY(${CONTAINER_DAEMON_FOLDER})
ADD_SUBDIRECTORY(${TESTS_FOLDER})
+ADD_SUBDIRECTORY(${CLI_FOLDER})
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
new file mode 100644
index 0000000..076dd94
--- /dev/null
+++ b/cli/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# 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 CMakeLists.txt
+# @author Mateusz Malicki (m.malicki2@samsung.com)
+#
+
+MESSAGE(STATUS "Generating makefile for the command line interface...")
+FILE(GLOB cli_SRCS *.cpp *.hpp)
+
+## Setup target ################################################################
+SET(CLI_CODENAME "${PROJECT_NAME}-cli")
+ADD_EXECUTABLE(${CLI_CODENAME} ${cli_SRCS})
+
+
+## Link libraries ##############################################################
+PKG_CHECK_MODULES(LIB_DEPS REQUIRED security-containers)
+
+INCLUDE_DIRECTORIES(${CLIENT_FOLDER})
+INCLUDE_DIRECTORIES(${COMMON_FOLDER})
+TARGET_LINK_LIBRARIES(${CLI_CODENAME} ${LIB_DEPS_LIBRARIES} ${PROJECT_NAME})
+
+
+## Install #####################################################################
+INSTALL(TARGETS ${CLI_CODENAME} DESTINATION bin)
diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp
new file mode 100644
index 0000000..02c867f
--- /dev/null
+++ b/cli/command-line-interface.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Mateusz Malicki
+ *
+ * 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 Mateusz Malicki (m.malicki2@samsung.com)
+ * @brief Definition of CommandLineInterface class
+ */
+
+#include "config.hpp"
+#include "command-line-interface.hpp"
+#include
+
+#include