--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
+ *
+ * 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 Implementation of a class for communication transport between container and server
+ */
+
+#include "container-connection-transport.hpp"
+#include "exception.hpp"
+
+#include "utils/file-wait.hpp"
+#include "utils/fs.hpp"
+#include "log/logger.hpp"
+
+
+namespace security_containers {
+
+namespace {
+
+// Timeout in ms for waiting for dbus transport.
+// Should be very long to ensure dbus in container is ready.
+const unsigned int TRANSPORT_READY_TIMEOUT = 2 * 60 * 1000;
+
+} // namespace
+
+
+ContainerConnectionTransport::ContainerConnectionTransport(const std::string& runMountPoint)
+ : mRunMountPoint(runMountPoint)
+{
+ if (runMountPoint.empty()) {
+ return;
+ }
+ if (!utils::createDirectories(runMountPoint, 0755)) {
+ LOGE("Initialization failed: could not create " << runMountPoint);
+ throw ContainerConnectionException("Could not create: " + runMountPoint);
+ }
+
+ // try to umount if already mounted
+ utils::umount(runMountPoint);
+
+ if (!utils::mountTmpfs(runMountPoint)) {
+ LOGE("Initialization failed: could not mount " << runMountPoint);
+ throw ContainerConnectionException("Could not mount: " + runMountPoint);
+ }
+}
+
+
+ContainerConnectionTransport::~ContainerConnectionTransport()
+{
+ if (!mRunMountPoint.empty()) {
+ if (!utils::umount(mRunMountPoint)) {
+ LOGE("Deinitialization failed: could not umount " << mRunMountPoint);
+ }
+ }
+}
+
+
+std::string ContainerConnectionTransport::acquireAddress()
+{
+ if (mRunMountPoint.empty()) {
+ return std::string();
+ }
+
+ const std::string dbusPath = mRunMountPoint + "/dbus/system_bus_socket";
+
+ // TODO This should be done asynchronously.
+ LOGT("Waiting for " << dbusPath);
+ utils::waitForFile(dbusPath, TRANSPORT_READY_TIMEOUT);
+
+ return "unix:path=" + dbusPath;
+}
+
+
+} // namespace security_containers
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Piotr Bartosiewicz <p.bartosiewi@partner.samsung.com>
+ *
+ * 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 Declaration of a class for communication transport between container and server
+ */
+
+
+#ifndef SERVER_CONTAINER_CONNECTION_TRANSPORT_HPP
+#define SERVER_CONTAINER_CONNECTION_TRANSPORT_HPP
+
+#include "dbus/connection.hpp"
+
+
+namespace security_containers {
+
+
+/**
+ * This class provides a communication transport between container and server.
+ * The object lifecycle should cover lifecycle of a container.
+ */
+class ContainerConnectionTransport {
+public:
+ ContainerConnectionTransport(const std::string& runMountPoint);
+ ~ContainerConnectionTransport();
+
+ /**
+ * Gets dbus addres. Will block until address is available.
+ */
+ std::string acquireAddress();
+
+private:
+ std::string mRunMountPoint;
+};
+
+
+} // namespace security_containers
+
+
+#endif // SERVER_CONTAINER_CONNECTION_TRANSPORT_HPP
/**
* @file
* @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- * @brief Implementation of class for communication between container and server
+ * @brief Implementation of a class for communication between container and server
*/
#include "container-connection.hpp"
#include "container-dbus-definitions.hpp"
#include "exception.hpp"
-#include "utils/file-wait.hpp"
-#include "utils/fs.hpp"
-#include "utils/paths.hpp"
#include "log/logger.hpp"
namespace {
-// Timeout in ms for waiting for dbus transport.
-// Should be very long to ensure dbus in container is ready.
-const unsigned int TRANSPORT_READY_TIMEOUT = 2 * 60 * 1000;
-
// Timeout in ms for waiting for dbus name.
// Can happen if glib loop is busy or not present.
const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000;
ContainerConnection::~ContainerConnection()
{
- deinitialize();
-}
-
-
-void ContainerConnection::initialize(const std::string& runMountPoint)
-{
- if (runMountPoint.empty()) {
- return;
- }
- if (!utils::createDirectories(runMountPoint, 0755)) {
- LOGE("Initialization failed: could not create " << runMountPoint);
- throw ContainerConnectionException("Could not create: " + runMountPoint);
- }
-
- // try to umount if already mounted
- utils::umount(runMountPoint);
-
- if (!utils::mountTmpfs(runMountPoint)) {
- LOGE("Initialization failed: could not mount " << runMountPoint);
- throw ContainerConnectionException("Could not mount: " + runMountPoint);
- }
-
- mRunMountPoint = runMountPoint;
-}
-
-void ContainerConnection::deinitialize()
-{
- if (!mRunMountPoint.empty()) {
- if (!utils::umount(mRunMountPoint)) {
- LOGE("Deinitialization failed: could not umount " << mRunMountPoint);
- }
- mRunMountPoint.clear();
- }
}
-void ContainerConnection::connect()
+void ContainerConnection::connect(const std::string& address)
{
- if (mRunMountPoint.empty()) {
+ if (address.empty()) {
LOGW("The connection to the container is disabled");
return;
}
- const std::string dbusPath = mRunMountPoint + "/dbus/system_bus_socket";
-
- // TODO This should be done asynchronously.
- LOGT("Waiting for " << dbusPath);
- utils::waitForFile(dbusPath, TRANSPORT_READY_TIMEOUT);
- LOGT("Connecting to DBUS");
- mDbusConnection = dbus::DbusConnection::create("unix:path=" + dbusPath);
+ LOGT("Connecting to DBUS on " << address);
+ mDbusConnection = dbus::DbusConnection::create(address);
LOGT("Setting DBUS name");
mDbusConnection->setName(api::BUS_NAME,
/**
* @file
* @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- * @brief Declaration of the class for communication between container and server
+ * @brief Declaration of a class for communication between container and server
*/
ContainerConnection();
~ContainerConnection();
- //TODO Move initialize, deinitialize and related stuff to separate class
-
- /**
- * Should be called every time just before container is created.
- */
- void initialize(const std::string& runMountPoint);
-
- /**
- * Should be called every time after container is destroyed.
- */
- void deinitialize();
-
/**
* Connect to container.
*/
- void connect();
+ void connect(const std::string& address);
/**
* Disconnect from container.
const std::string& message);
private:
- std::string mRunMountPoint;
dbus::DbusConnection::Pointer mDbusConnection;
std::mutex mNameMutex;
std::condition_variable mNameCondition;
void Container::start()
{
- mConnection.initialize(mConfig.runMountPoint);
+ mConnectionTransport.reset(new ContainerConnectionTransport(mConfig.runMountPoint));
mAdmin->start();
- mConnection.connect();
+ mConnection.connect(mConnectionTransport->acquireAddress());
// Send to the background only after we're connected,
// otherwise it'd take ages.
{
mConnection.disconnect();
mAdmin->stop();
- mConnection.deinitialize();
+ mConnectionTransport.reset();
}
void Container::goForeground()
#include "container-config.hpp"
#include "container-admin.hpp"
#include "container-connection.hpp"
+#include "container-connection-transport.hpp"
#include <string>
#include <memory>
private:
ContainerConfig mConfig;
std::unique_ptr<ContainerAdmin> mAdmin;
+ std::unique_ptr<ContainerConnectionTransport> mConnectionTransport;
ContainerConnection mConnection;
};
#include "ut.hpp"
#include "container-connection.hpp"
+#include "container-connection-transport.hpp"
#include "container-dbus-definitions.hpp"
#include "dbus/connection.hpp"
NULL
};
-// TODO fix destruction order - move transport stuff to separate raii class
const std::string TRANSPORT_MOUNT_POINT = "/tmp/ut-container-connection";
-const std::string DBUS_ADDRESS = "unix:path=" + TRANSPORT_MOUNT_POINT + "/dbus/system_bus_socket";
const int EVENT_TIMEOUT = 1000;
-class ScopedDbusDaemon : public ScopedDaemon {
+class ScopedDbusDaemon {
public:
- void start()
+ ScopedDbusDaemon()
+ : mTransport(TRANSPORT_MOUNT_POINT)
{
utils::createDirectory(TRANSPORT_MOUNT_POINT + "/dbus", 0755);
mDaemon.start(DBUS_DAEMON_PROC, DBUS_DAEMON_ARGS);
}
+
+ std::string acquireAddress()
+ {
+ return mTransport.acquireAddress();
+ }
private:
+ ContainerConnectionTransport mTransport;
ScopedDaemon mDaemon;
};
BOOST_AUTO_TEST_CASE(ConnectTest)
{
- ScopedDbusDaemon dbus;
ScopedGlibLoop loop;
+ ScopedDbusDaemon dbus;
ContainerConnection connection;
- connection.initialize(TRANSPORT_MOUNT_POINT);
- dbus.start();
- BOOST_REQUIRE_NO_THROW(connection.connect());
+ BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
BOOST_REQUIRE_NO_THROW(connection.disconnect());
}
BOOST_AUTO_TEST_CASE(NotifyActiveContainerApiTest)
{
- ScopedDbusDaemon dbus;
ScopedGlibLoop loop;
+ ScopedDbusDaemon dbus;
Latch notifyCalled;
ContainerConnection connection;
- connection.initialize(TRANSPORT_MOUNT_POINT);
- dbus.start();
- BOOST_REQUIRE_NO_THROW(connection.connect());
+ BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
auto callback = [&](const std::string& application, const std::string& message) {
if (application == "testapp" && message == "testmessage") {
};
connection.setNotifyActiveContainerCallback(callback);
- DbusConnection::Pointer client = DbusConnection::create(DBUS_ADDRESS);
+ DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress());
client->callMethod(api::BUS_NAME,
api::OBJECT_PATH,
api::INTERFACE,
BOOST_AUTO_TEST_CASE(SignalNotificationApiTest)
{
- ScopedDbusDaemon dbus;
ScopedGlibLoop loop;
+ ScopedDbusDaemon dbus;
Latch signalEmitted;
ContainerConnection connection;
- connection.initialize(TRANSPORT_MOUNT_POINT);
- dbus.start();
- BOOST_REQUIRE_NO_THROW(connection.connect());
+ BOOST_REQUIRE_NO_THROW(connection.connect(dbus.acquireAddress()));
- DbusConnection::Pointer client = DbusConnection::create(DBUS_ADDRESS);
+ DbusConnection::Pointer client = DbusConnection::create(dbus.acquireAddress());
auto handler = [&](const std::string& /*senderBusName*/,
const std::string& objectPath,