From f3e8d507082928520ee9d876ec466cf159ee38fe Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 7 Apr 2015 15:41:58 +0200 Subject: [PATCH 01/16] Client refactor (using libConfig, switch to IPC #1) [Feature] Using libConfig for serialize parameters [Cause] Switching from Dbus to IPC [Solution] Using libConfig for serialize parameters [Verification] run tests with Valgrind Change-Id: I0562037cfc5b78b53024d0021ab74a0a1d3a3f3d --- client/CMakeLists.txt | 2 +- client/dbus-connection.cpp | 119 +++++ client/dbus-connection.hpp | 135 +++++ client/exception.hpp | 65 +++ client/host-dbus-connection.cpp | 191 +++++++ client/host-dbus-connection.hpp | 84 +++ client/vasum-client-impl.cpp | 1067 +++++++++++++++------------------------ client/vasum-client-impl.hpp | 72 +-- client/zone-dbus-connection.cpp | 71 +++ client/zone-dbus-connection.hpp | 60 +++ common/api/messages.hpp | 17 + 11 files changed, 1171 insertions(+), 712 deletions(-) create mode 100644 client/dbus-connection.cpp create mode 100644 client/dbus-connection.hpp create mode 100644 client/exception.hpp create mode 100644 client/host-dbus-connection.cpp create mode 100644 client/host-dbus-connection.hpp create mode 100644 client/zone-dbus-connection.cpp create mode 100644 client/zone-dbus-connection.hpp diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 558f3a7..7198610 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -44,7 +44,7 @@ SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger libConfig) INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${SERVER_FOLDER}) diff --git a/client/dbus-connection.cpp b/client/dbus-connection.cpp new file mode 100644 index 0000000..7e364d7 --- /dev/null +++ b/client/dbus-connection.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015 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 libSimpleDbus's wrapper + */ + +#include +#include "dbus-connection.hpp" +#include "exception.hpp" +#include +#include + +using namespace vasum::client; + + +DbusConnection::DbusConnection(const std::string& definition, + const std::string& busName, + const std::string& objectPath, + const std::string& interface) + : mDefinition(definition) + , mBusName(busName) + , mObjectPath(objectPath) + , mInterface(interface) +{ +} + +DbusConnection::~DbusConnection() +{ +} + +void DbusConnection::create(const std::shared_ptr& connection) +{ + mConnection = connection; +} + +void DbusConnection::callMethod(const std::string& method, + GVariant* args_in, + const std::string& args_spec_out, + GVariant** args_out) +{ + dbus::GVariantPtr ret = mConnection->callMethod(mBusName, + mObjectPath, + mInterface, + method, + args_in, + args_spec_out); + if (args_out != NULL) { + *args_out = ret.release(); + } +} + +DbusConnection::SubscriptionId DbusConnection::signalSubscribe(const std::string& signal, + const SignalCallback& signalCallback) +{ + auto onSignal = [this, signal, signalCallback](const std::string& /*senderBusName*/, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant * parameters) { + if (objectPath == mObjectPath && + interface == mInterface && + signalName == signal) { + + signalCallback(parameters); + } + }; + return mConnection->signalSubscribe(onSignal, mBusName); +} + +void DbusConnection::signalUnsubscribe(SubscriptionId id) +{ + mConnection->signalUnsubscribe(id); +} + +std::string DbusConnection::getArgsOutSpec(const std::string& methodName) +{ + //TODO: Information about output argumnets of all methods can be computed in constuctor + GError *error = NULL; + GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(mDefinition.c_str(), &error); + if (error) { + std::string msg = error->message; + g_error_free (error); + throw ClientException("Invalid xml: " + msg); + } + GDBusInterfaceInfo* interfaceInfo = g_dbus_node_info_lookup_interface(nodeInfo, mInterface.c_str()); + if (interfaceInfo == NULL) { + throw ClientException("Invalid xml: can't find interface: " + mInterface); + } + GDBusMethodInfo* methodInfo = g_dbus_interface_info_lookup_method(interfaceInfo, methodName.c_str()); + if (methodInfo == NULL) { + throw ClientException("Invalid xml: can't find method: " + methodName); + } + + std::string signature; + for (GDBusArgInfo** argInfo = methodInfo->out_args; *argInfo; ++argInfo) { + signature += (*argInfo)->signature; + } + g_dbus_node_info_unref(nodeInfo); + return "(" + signature + ")"; +} diff --git a/client/dbus-connection.hpp b/client/dbus-connection.hpp new file mode 100644 index 0000000..a760bb6 --- /dev/null +++ b/client/dbus-connection.hpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015 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 libSimpleDbus's wrapper + */ + +#ifndef VASUM_CLIENT_DBUS_CONNECTION_HPP +#define VASUM_CLIENT_DBUS_CONNECTION_HPP + +#include +#include +#include +#include +#include +#include + +namespace vasum { +namespace client { + +/** + * libSimpleDbus client definition. + * + * DbusConnection uses libSimpleDbus API. + */ +class DbusConnection { +public: + typedef unsigned int SubscriptionId; + + DbusConnection(const std::string& definition, + const std::string& busName, + const std::string& objectPath, + const std::string& interface); + virtual ~DbusConnection(); + void create(const std::shared_ptr& connection); + + template + typename std::enable_if::value>::type + call(const std::string& method, const ArgIn& argIn, ArgOut& argOut); + + template + typename std::enable_if::value>::type + call(const std::string& method, const ArgIn& argIn, ArgOut& argOut); + + template + typename std::enable_if::value>::type + call(const std::string& method, ArgOut& argOut) { + vasum::api::Void argIn; + call(method, argIn, argOut); + } + + template + typename std::enable_if::value>::type + call(const std::string& method, ArgIn& argIn) { + vasum::api::Void argOut; + call(method, argIn, argOut); + } + + template + SubscriptionId signalSubscribe(const std::string& signal, + const std::function& signalCallback); + void signalUnsubscribe(SubscriptionId id); + +private: + typedef std::function SignalCallback; + + std::shared_ptr mConnection; + const std::string mDefinition; + const std::string mBusName; + const std::string mObjectPath; + const std::string mInterface; + + void callMethod(const std::string& method, + GVariant* args_in, + const std::string& args_spec_out, + GVariant** args_out); + SubscriptionId signalSubscribe(const std::string& signal, const SignalCallback& signalCallback); + + /** + * Get signature of method output parameters + */ + std::string getArgsOutSpec(const std::string& methodName); +}; + +template +typename std::enable_if::value>::type +DbusConnection::call(const std::string& method, const ArgIn& argIn, ArgOut& argOut) +{ + GVariant* gArgOut = NULL; + callMethod(method, config::saveToGVariant(argIn), getArgsOutSpec(method), &gArgOut); + config::loadFromGVariant(gArgOut, argOut); + g_variant_unref(gArgOut); +} + +template +typename std::enable_if::value>::type +DbusConnection::call(const std::string& method, const ArgIn& argIn, ArgOut& /* argOut */) +{ + callMethod(method, config::saveToGVariant(argIn), "", NULL); +} + +template +DbusConnection::SubscriptionId DbusConnection::signalSubscribe(const std::string& signal, + const std::function& signalCallback) +{ + SignalCallback callback = [signalCallback](GVariant* parameters) { + Arg param; + config::loadFromGVariant(parameters, param); + signalCallback(param); + }; + return signalSubscribe(signal, callback); +} + +} // namespace client +} // namespace vasum + +#endif /* VASUM_CLIENT_DBUS_CONNECTION_HPP */ diff --git a/client/exception.hpp b/client/exception.hpp new file mode 100644 index 0000000..d4be66b --- /dev/null +++ b/client/exception.hpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015 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 Exceptions for the client + */ + + +#ifndef CLIENT_EXCEPTION_HPP +#define CLIENT_EXCEPTION_HPP + +#include "base-exception.hpp" + + +namespace vasum { + + +/** + * Base class for exceptions in Vasum Client + */ +struct ClientException: public VasumException { + + ClientException(const std::string& error) : VasumException(error) {} +}; + +struct IOException: public ClientException { + + IOException(const std::string& error) : ClientException(error) {} +}; + +struct OperationFailedException: public ClientException { + + OperationFailedException(const std::string& error) : ClientException(error) {} +}; + +struct InvalidArgumentException: public ClientException { + + InvalidArgumentException(const std::string& error) : ClientException(error) {} +}; + +struct InvalidResponseException: public ClientException { + + InvalidResponseException(const std::string& error) : ClientException(error) {} +}; + +} + +#endif // CLIENT_EXCEPTION_HPP diff --git a/client/host-dbus-connection.cpp b/client/host-dbus-connection.cpp new file mode 100644 index 0000000..7e511fe --- /dev/null +++ b/client/host-dbus-connection.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2015 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 Host client class + */ + + +#include +#include "host-dbus-connection.hpp" +#include +#include + +namespace vasum { +namespace client { + +HostDbusConnection::HostDbusConnection() + : mConnection(vasum::api::host::DEFINITION, + vasum::api::host::BUS_NAME, + vasum::api::host::OBJECT_PATH, + vasum::api::host::INTERFACE) +{ +} + +void HostDbusConnection::create(const std::shared_ptr& connection) +{ + mConnection.create(connection); +} + +void HostDbusConnection::callGetZoneIds(vasum::api::ZoneIds& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_ID_LIST, argOut); +} + +void HostDbusConnection::callGetActiveZoneId(vasum::api::ZoneId& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ACTIVE_ZONE_ID, argOut); +} + +void HostDbusConnection::callSetActiveZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SET_ACTIVE_ZONE, argIn); +} + +void HostDbusConnection::callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_INFO, argIn, argOut); +} + +void HostDbusConnection::callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SET_NETDEV_ATTRS, argIn); +} + +void HostDbusConnection::callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_NETDEV_ATTRS, argIn, argOut); +} + +void HostDbusConnection::callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_NETDEV_LIST, argIn, argOut); +} + +void HostDbusConnection::callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_VETH, argIn); +} + +void HostDbusConnection::callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_MACVLAN, argIn); +} + +void HostDbusConnection::callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_PHYS, argIn); +} + +void HostDbusConnection::callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DESTROY_NETDEV, argIn); +} + +void HostDbusConnection::callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, argIn); +} + +void HostDbusConnection::callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_FILE, argIn, argOut); +} + +void HostDbusConnection::callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_MOUNT, argIn, argOut); +} + +void HostDbusConnection::callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_LINK, argIn, argOut); +} + +void HostDbusConnection::callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_DECLARATIONS, argIn, argOut); +} + +void HostDbusConnection::callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_REMOVE_DECLARATION, argIn); +} + +void HostDbusConnection::callCreateZone(const vasum::api::CreateZoneIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_ZONE, argIn); +} + +void HostDbusConnection::callDestroyZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DESTROY_ZONE, argIn); +} + +void HostDbusConnection::callShutdownZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SHUTDOWN_ZONE, argIn); +} + +void HostDbusConnection::callStartZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_START_ZONE, argIn); +} + +void HostDbusConnection::callLockZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_LOCK_ZONE, argIn); +} + +void HostDbusConnection::callUnlockZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_UNLOCK_ZONE, argIn); +} + +void HostDbusConnection::callGrantDevice(const vasum::api::GrantDeviceIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_GRANT_DEVICE, argIn); +} + +void HostDbusConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); +} + +void HostDbusConnection::callGetZoneDbuses(vasum::api::Dbuses& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_DBUSES, argOut); +} + +HostDbusConnection::SubscriptionId +HostDbusConnection::subscribeZoneDbusState(const ZoneDbusStateCallback& callback) +{ + return mConnection.signalSubscribe( + vasum::api::host::SIGNAL_ZONE_DBUS_STATE, callback); +} + +void HostDbusConnection::unsubscribe(const SubscriptionId& id) +{ + mConnection.signalUnsubscribe(id); +} + +} // namespace client +} // namespace vasum diff --git a/client/host-dbus-connection.hpp b/client/host-dbus-connection.hpp new file mode 100644 index 0000000..c7cebdb --- /dev/null +++ b/client/host-dbus-connection.hpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 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 Host client class + */ + +#ifndef VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP +#define VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP + +#include "dbus-connection.hpp" +#include + +namespace vasum { +namespace client { + +/** + * vasum's client definition. + * + * HostDbusConnection is used for communication with the vasum's server from host through dbus + */ +class HostDbusConnection { +public: + typedef unsigned int SubscriptionId; + typedef std::function ZoneDbusStateCallback; + + HostDbusConnection(); + + void create(const std::shared_ptr& connection); + + void callGetZoneIds(vasum::api::ZoneIds& argOut); + void callGetActiveZoneId(vasum::api::ZoneId& argOut); + void callSetActiveZone(const vasum::api::ZoneId& argIn); + void callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut); + void callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn); + void callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut); + void callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut); + void callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn); + void callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn); + void callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn); + void callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn); + void callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn); + void callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut); + void callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut); + void callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut); + void callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut); + void callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn); + void callCreateZone(const vasum::api::CreateZoneIn& argIn); + void callDestroyZone(const vasum::api::ZoneId& argIn); + void callShutdownZone(const vasum::api::ZoneId& argIn); + void callStartZone(const vasum::api::ZoneId& argIn); + void callLockZone(const vasum::api::ZoneId& argIn); + void callUnlockZone(const vasum::api::ZoneId& argIn); + void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); + void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); + void callGetZoneDbuses(vasum::api::Dbuses& argOut); + SubscriptionId subscribeZoneDbusState(const ZoneDbusStateCallback& callback); + void unsubscribe(const SubscriptionId& id); +private: + DbusConnection mConnection; +}; + +} // namespace client +} // namespace vasum + +#endif /* VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP */ diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 4f3a05c..41a0030 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -26,15 +26,16 @@ #include #include "vasum-client-impl.hpp" #include "utils.hpp" +#include "exception.hpp" +#include "host-dbus-connection.hpp" +#include "zone-dbus-connection.hpp" +#include + #include #include #include -#include -#include -#include #include -#include #include #include #include @@ -46,71 +47,11 @@ #include using namespace std; -using namespace dbus; using namespace vasum; -using namespace vasum::utils; namespace { -const DbusInterfaceInfo HOST_INTERFACE(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE); -const DbusInterfaceInfo ZONE_INTERFACE(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE); - -unique_ptr gGlibLoop; - -void toDict(GVariant* in, VsmArrayString* keys, VsmArrayString* values) -{ - assert(in); - assert(keys); - assert(values); - - typedef char* key_type; - typedef char* value_type; - - GVariantIter iter; - value_type value; - key_type key; - gsize size = g_variant_n_children(in); - key_type* outk = (key_type*)calloc(size + 1, sizeof(key_type)); - value_type* outv = (value_type*)calloc(size + 1, sizeof(value_type)); - - g_variant_iter_init(&iter, in); - for (int i = 0; g_variant_iter_loop(&iter, "(ss)", &key, &value); i++) { - outk[i] = strdup(key); - outv[i] = strdup(value); - } - *keys = outk; - *values = outv; -} - -vector> toDict(GVariant* in) -{ - assert(in); - - const gchar* key; - const gchar* value; - vector> dict; - GVariantIter iter; - g_variant_iter_init(&iter, in); - while (g_variant_iter_loop(&iter, "(&s&s)", &key, &value)) { - dict.push_back(make_tuple(key, value)); - } - return dict; -} - -void toBasic(GVariant* in, char** str) -{ - assert(in); - assert(str); - - gsize length; - const gchar* src = g_variant_get_string(in, &length); - char* buf = strndup(src, length); - *str = buf; -} +unique_ptr gGlibLoop; VsmZoneState getZoneState(const char* state) { @@ -137,43 +78,35 @@ VsmZoneState getZoneState(const char* state) } else if (strcmp(state, "ACTIVATING") == 0) { return ACTIVATING; } - assert(0 && "UNKNOWN STATE"); - return (VsmZoneState)-1; + throw InvalidResponseException("Unknown state"); } -void toBasic(GVariant* in, VsmZone* zone) +void convert(const api::VectorOfStrings& in, VsmArrayString& out) { - const char* id; - const char* path; - const char* state; - int terminal; - VsmZone vsmZone = (VsmZone)malloc(sizeof(*vsmZone)); - g_variant_get(in, "(siss)", &id, &terminal, &state, &path); - vsmZone->id = strdup(id); - vsmZone->terminal = terminal; - vsmZone->state = getZoneState(state); - vsmZone->rootfs_path = strdup(path); - *zone = vsmZone; + out = reinterpret_cast(calloc(in.values.size() + 1, sizeof(char*))); + for (size_t i = 0; i < in.values.size(); ++i) { + out[i] = ::strdup(in.values[i].c_str()); + } } -template -void toArray(GVariant* in, T** scArray) +void convert(const api::VectorOfStringPairs& in, VsmArrayString& keys, VsmArrayString& values) { - assert(in); - assert(scArray); - - gsize size = g_variant_n_children(in); - T* ids = (T*)calloc(size + 1, sizeof(T)); - - GVariantIter iter; - GVariant* child; - - g_variant_iter_init(&iter, in); - for (int i = 0; (child = g_variant_iter_next_value(&iter)); i++) { - toBasic(child, &ids[i]); - g_variant_unref(child); + keys = reinterpret_cast(calloc(in.values.size() + 1, sizeof(char*))); + values = reinterpret_cast(calloc(in.values.size() + 1, sizeof(char*))); + for (size_t i = 0; i < in.values.size(); ++i) { + keys[i] = ::strdup(in.values[i].first.c_str()); + values[i] = ::strdup(in.values[i].second.c_str()); } - *scArray = ids; +} + +void convert(const api::ZoneInfoOut& info, VsmZone& zone) +{ + VsmZone vsmZone = reinterpret_cast(malloc(sizeof(*vsmZone))); + vsmZone->id = ::strdup(info.id.c_str()); + vsmZone->terminal = info.vt; + vsmZone->state = getZoneState(info.state.c_str()); + vsmZone->rootfs_path = ::strdup(info.rootPath.c_str()); + zone = vsmZone; } string toString(const in_addr* addr) @@ -181,7 +114,7 @@ string toString(const in_addr* addr) char buf[INET_ADDRSTRLEN]; const char* ret = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN); if (ret == NULL) { - throw runtime_error(getSystemErrorMessage()); + throw InvalidArgumentException(getSystemErrorMessage()); } return ret; } @@ -191,37 +124,11 @@ string toString(const in6_addr* addr) char buf[INET6_ADDRSTRLEN]; const char* ret = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN); if (ret == NULL) { - throw runtime_error(getSystemErrorMessage()); + throw InvalidArgumentException(getSystemErrorMessage()); } return ret; } -GVariant* createTupleArray(const vector>& dict) -{ - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); - for (const auto entry : dict) { - g_variant_builder_add(&builder, "(ss)", get<0>(entry).c_str(), get<1>(entry).c_str()); - } - return g_variant_builder_end(&builder); -} - -VsmStatus toStatus(const exception& ex) -{ - if (typeid(DbusCustomException) == typeid(ex)) { - return VSMCLIENT_CUSTOM_ERROR; - } else if (typeid(DbusIOException) == typeid(ex)) { - return VSMCLIENT_IO_ERROR; - } else if (typeid(DbusOperationException) == typeid(ex)) { - return VSMCLIENT_OPERATION_FAILED; - } else if (typeid(DbusInvalidArgumentException) == typeid(ex)) { - return VSMCLIENT_INVALID_ARGUMENT; - } else if (typeid(DbusException) == typeid(ex)) { - return VSMCLIENT_OTHER_ERROR; - } - return VSMCLIENT_OTHER_ERROR; -} - bool readFirstLineOfFile(const string& path, string& ret) { ifstream file(path); @@ -235,39 +142,15 @@ bool readFirstLineOfFile(const string& path, string& ret) } //namespace -VsmStatus Client::getNetdevAttrs(const string& zone, - const string& netdev, - NetdevAttrs& attrs) noexcept -{ - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(ss)", zone.c_str(), netdev.c_str()); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_NETDEV_ATTRS, - args_in, - "(a(ss))", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - attrs = toDict(unpacked); - g_variant_unref(unpacked); - g_variant_unref(out); - mStatus = Status(); - return vsm_get_status(); -} - VsmStatus Client::vsm_start_glib_loop() noexcept { try { if (!gGlibLoop) { - gGlibLoop.reset(new ScopedGlibLoop()); + gGlibLoop.reset(new utils::ScopedGlibLoop()); } } catch (const exception&) { return VSMCLIENT_OTHER_ERROR; } - return VSMCLIENT_SUCCESS; } @@ -299,89 +182,55 @@ Client::~Client() noexcept { } -VsmStatus Client::createSystem() noexcept +VsmStatus Client::coverException(const function worker) noexcept { try { - mConnection = DbusConnection::createSystem(); - mStatus = Status(); + worker(); + mStatus = Status(VSMCLIENT_SUCCESS); + } catch (const vasum::IOException& ex) { + mStatus = Status(VSMCLIENT_IO_ERROR, ex.what()); + } catch (const vasum::OperationFailedException& ex) { + mStatus = Status(VSMCLIENT_OPERATION_FAILED, ex.what()); + } catch (const vasum::InvalidArgumentException& ex) { + mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); + } catch (const vasum::InvalidResponseException& ex) { + mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what()); + } catch (const vasum::ClientException& ex) { + mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); + } catch (const dbus::DbusCustomException& ex) { + mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); + } catch (const dbus::DbusIOException& ex) { + mStatus = Status(VSMCLIENT_IO_ERROR, ex.what()); + } catch (const dbus::DbusOperationException& ex) { + mStatus = Status(VSMCLIENT_OPERATION_FAILED, ex.what()); + } catch (const dbus::DbusInvalidArgumentException& ex) { + mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); + } catch (const dbus::DbusException& ex) { + mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what()); } catch (const exception& ex) { - mStatus = Status(toStatus(ex), ex.what()); + mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); } - return vsm_get_status(); + return mStatus.mVsmStatus; } -VsmStatus Client::create(const string& address) noexcept +VsmStatus Client::createSystem() noexcept { - try { - mConnection = DbusConnection::create(address); - mStatus = Status(); - } catch (const exception& ex) { - mStatus = Status(toStatus(ex), ex.what()); - } - return vsm_get_status(); -} + return coverException([&] { + shared_ptr connection(dbus::DbusConnection::createSystem().release()); -VsmStatus Client::callMethod(const DbusInterfaceInfo& info, - const string& method, - GVariant* args_in, - const string& args_spec_out, - GVariant** args_out) -{ - try { - GVariantPtr ret = mConnection->callMethod(info.busName, - info.objectPath, - info.interface, - method, - args_in, - args_spec_out); - if (args_out != NULL) { - *args_out = ret.release(); - } - mStatus = Status(); - } catch (const exception& ex) { - mStatus = Status(toStatus(ex), ex.what()); - } - return vsm_get_status(); + mHostClient.create(connection); + mZoneClient.create(connection); + }); } -VsmStatus Client::signalSubscribe(const DbusInterfaceInfo& info, - const string& name, - SignalCallback signalCallback, - VsmSubscriptionId* subscriptionId) +VsmStatus Client::create(const string& address) noexcept { - auto onSignal = [=](const string& /*senderBusName*/, - const string & objectPath, - const string & interface, - const string & signalName, - GVariant * parameters) { - if (objectPath == info.objectPath && - interface == info.interface && - signalName == name) { - - signalCallback(parameters); - } - }; - try { - guint id = mConnection->signalSubscribe(onSignal, info.busName); - if (subscriptionId) { - *subscriptionId = id; - } - mStatus = Status(); - } catch (const exception& ex) { - mStatus = Status(toStatus(ex), ex.what()); - } - return vsm_get_status(); -} + return coverException([&] { + shared_ptr connection(dbus::DbusConnection::create(address).release()); -VsmStatus Client::signalUnsubscribe(VsmSubscriptionId id) -{ - try { - mConnection->signalUnsubscribe(id); - mStatus = Status(); - } catch (const exception& ex) { - mStatus = Status(toStatus(ex), ex.what()); - } - return vsm_get_status(); + mHostClient.create(connection); + mZoneClient.create(connection); + }); } const char* Client::vsm_get_status_message() const noexcept @@ -399,86 +248,54 @@ VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* keys, VsmArrayString* valu assert(keys); assert(values); - GVariant* out = NULL; - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_ZONE_DBUSES, - NULL, - "(a(ss))", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toDict(unpacked, keys, values); - g_variant_unref(unpacked); - g_variant_unref(out); - return ret; + return coverException([&] { + api::Dbuses dbuses; + mHostClient.callGetZoneDbuses(dbuses); + convert(dbuses, *keys, *values); + }); } VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept { assert(array); - GVariant* out = NULL; - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_ZONE_ID_LIST, - NULL, - "(as)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toArray(unpacked, array); - g_variant_unref(unpacked); - g_variant_unref(out); - return ret; + return coverException([&] { + api::ZoneIds zoneIds; + mHostClient.callGetZoneIds(zoneIds); + convert(zoneIds, *array); + }); } VsmStatus Client::vsm_get_active_zone_id(VsmString* id) noexcept { assert(id); - GVariant* out = NULL; - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_ACTIVE_ZONE_ID, - NULL, - "(s)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, id); - g_variant_unref(unpacked); - g_variant_unref(out); - return ret; + return coverException([&] { + api::ZoneId zoneId; + mHostClient.callGetActiveZoneId(zoneId); + *id = ::strdup(zoneId.value.c_str()); + }); } VsmStatus Client::vsm_lookup_zone_by_pid(int pid, VsmString* id) noexcept { assert(id); - const string path = "/proc/" + to_string(pid) + "/cpuset"; + return coverException([&] { + const string path = "/proc/" + to_string(pid) + "/cpuset"; - string cpuset; - if (!readFirstLineOfFile(path, cpuset)) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, "Process not found"); - return vsm_get_status(); - } + string cpuset; + if (!readFirstLineOfFile(path, cpuset)) { + throw InvalidArgumentException("Process not found"); + } - string zoneId; - if (!parseZoneIdFromCpuSet(cpuset, zoneId)) { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "unknown format of cpuset"); - return vsm_get_status(); - } + string zoneId; + if (!parseZoneIdFromCpuSet(cpuset, zoneId)) { + throw OperationFailedException("unknown format of cpuset"); + } - *id = strdup(zoneId.c_str()); - mStatus = Status(); - return vsm_get_status(); + *id = ::strdup(zoneId.c_str()); + }); } VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept @@ -486,104 +303,111 @@ VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept assert(id); assert(zone); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(s)", id); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_ZONE_INFO, - args_in, - "(siss)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - toBasic(out, zone); - g_variant_unref(out); - return ret; + return coverException([&] { + api::ZoneInfoOut info; + mHostClient.callGetZoneInfo({ id }, info); + convert(info, *zone); + }); } VsmStatus Client::vsm_lookup_zone_by_terminal_id(int, VsmString*) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); - return vsm_get_status(); + return coverException([&] { + throw OperationFailedException("Not implemented"); + }); } VsmStatus Client::vsm_set_active_zone(const char* id) noexcept { assert(id); - GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_SET_ACTIVE_ZONE, args_in); + return coverException([&] { + mHostClient.callSetActiveZone({ id }); + }); } VsmStatus Client::vsm_create_zone(const char* id, const char* tname) noexcept { assert(id); - const char* template_name = tname ? tname : "default"; - GVariant* args_in = g_variant_new("(ss)", id, template_name); - return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_ZONE, args_in); + return coverException([&] { + string template_name = tname ? tname : "default"; + mHostClient.callCreateZone({ id, template_name }); + }); } 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_ZONE, args_in); + + return coverException([&] { + mHostClient.callDestroyZone({ id }); + }); } VsmStatus Client::vsm_shutdown_zone(const char* id) noexcept { assert(id); - GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_SHUTDOWN_ZONE, args_in); + + return coverException([&] { + mHostClient.callShutdownZone({ id }); + }); } VsmStatus Client::vsm_start_zone(const char* id) noexcept { assert(id); - GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_START_ZONE, args_in); + + return coverException([&] { + mHostClient.callStartZone({ id }); + }); } VsmStatus Client::vsm_lock_zone(const char* id) noexcept { assert(id); - GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_LOCK_ZONE, args_in); + return coverException([&] { + mHostClient.callLockZone({ id }); + }); } VsmStatus Client::vsm_unlock_zone(const char* id) noexcept { assert(id); - GVariant* args_in = g_variant_new("(s)", id); - return callMethod(HOST_INTERFACE, api::host::METHOD_UNLOCK_ZONE, args_in); + return coverException([&] { + mHostClient.callUnlockZone({ id }); + }); } VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback zoneDbusStateCallback, - void* data, - VsmSubscriptionId* subscriptionId) noexcept + void* data, + VsmSubscriptionId* subscriptionId) noexcept { assert(zoneDbusStateCallback); - auto onSigal = [=](GVariant * parameters) - { - const char* zone; - const char* dbusAddress; - g_variant_get(parameters, "(&s&s)", &zone, &dbusAddress); - zoneDbusStateCallback(zone, dbusAddress, data); - }; - - return signalSubscribe(HOST_INTERFACE, - api::host::SIGNAL_ZONE_DBUS_STATE, - onSigal, - subscriptionId); + return coverException([&] { + auto onSigal = [=](const api::DbusState& dbus) + { + zoneDbusStateCallback(dbus.first.c_str(), + dbus.second.c_str(), + data); + }; + + VsmSubscriptionId id; + id = mHostClient.subscribeZoneDbusState(onSigal); + if (subscriptionId) { + *subscriptionId = id; + } + }); } VsmStatus Client::vsm_del_state_callback(VsmSubscriptionId subscriptionId) noexcept { - return signalUnsubscribe(subscriptionId); + return coverException([&] { + mHostClient.unsubscribe(subscriptionId); + }); } VsmStatus Client::vsm_grant_device(const char* id, const char* device, uint32_t flags) noexcept @@ -591,8 +415,9 @@ VsmStatus Client::vsm_grant_device(const char* id, const char* device, uint32_t assert(id); assert(device); - GVariant* args_in = g_variant_new("(ssu)", id, device, flags); - return callMethod(HOST_INTERFACE, api::host::METHOD_GRANT_DEVICE, args_in); + return coverException([&] { + mHostClient.callGrantDevice({ id, device, flags }); + }); } VsmStatus Client::vsm_revoke_device(const char* id, const char* device) noexcept @@ -600,403 +425,328 @@ VsmStatus Client::vsm_revoke_device(const char* id, const char* device) noexcept assert(id); assert(device); - GVariant* args_in = g_variant_new("(ss)", id, device); - return callMethod(HOST_INTERFACE, api::host::METHOD_REVOKE_DEVICE, args_in); + return coverException([&] { + mHostClient.callRevokeDevice({ id, device }); + }); } -VsmStatus Client::vsm_zone_get_netdevs(const char* zone, VsmArrayString* netdevIds) noexcept +VsmStatus Client::vsm_zone_get_netdevs(const char* id, VsmArrayString* netdevIds) noexcept { - assert(zone); + assert(id); assert(netdevIds); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(s)", zone); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_NETDEV_LIST, - args_in, - "(as)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toArray(unpacked, netdevIds); - g_variant_unref(unpacked); - g_variant_unref(out); - return ret; + return coverException([&] { + api::NetDevList netdevs; + mHostClient.callGetNetdevList({ id }, netdevs); + convert(netdevs, *netdevIds); + }); } -VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* zone, - const char* netdevId, - struct in_addr* addr) noexcept +VsmStatus Client::vsm_netdev_get_ip_addr(const char* id, + const char* netdevId, + int type, + void* addr) noexcept { using namespace boost::algorithm; - assert(zone); + assert(id); assert(netdevId); assert(addr); - NetdevAttrs attrs; - VsmStatus ret = getNetdevAttrs(zone, netdevId, attrs); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - - auto it = find_if(attrs.begin(), attrs.end(), [](const tuple& entry) { - return get<0>(entry) == "ipv4"; - }); - if (it != attrs.end()) { - vector addrAttrs; - for(auto addrAttr : split(addrAttrs, get<1>(*it), is_any_of(","))) { - size_t pos = addrAttr.find(":"); - if (addrAttr.substr(0, pos) == "ip") { - if (pos != string::npos && pos < addrAttr.length() && - inet_pton(AF_INET, addrAttr.substr(pos + 1).c_str(), addr) == 1) { - //XXX: return only one address - mStatus = Status(); - return vsm_get_status(); - } else { - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data"); - return vsm_get_status(); + return coverException([&] { + api::GetNetDevAttrs attrs; + mHostClient.callGetNetdevAttrs({ id, netdevId }, attrs); + + auto it = find_if(attrs.values.begin(), + attrs.values.end(), + [type](const api::StringPair& entry) { + return entry.first == (type == AF_INET ? "ipv4" : "ipv6"); + }); + + if (it != attrs.values.end()) { + vector addrAttrs; + for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) { + size_t pos = addrAttr.find(":"); + if (addrAttr.substr(0, pos) == "ip") { + if (pos != string::npos && pos < addrAttr.length() && + inet_pton(type, addrAttr.substr(pos + 1).c_str(), addr) == 1) { + //XXX: return only one address + return; + } else { + throw InvalidResponseException("Wrong address format returned"); + } } } } - } - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Address not found"); - return vsm_get_status(); + throw OperationFailedException("Address not found"); + }); } -VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* zone, - const char* netdevId, - struct in6_addr* addr) noexcept +VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id, + const char* netdevId, + struct in_addr* addr) noexcept { - using namespace boost::algorithm; + return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr); +} - assert(zone); +VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id, + const char* netdevId, + struct in6_addr* addr) noexcept +{ + return vsm_netdev_get_ip_addr(id, netdevId, AF_INET6, addr); +} + +VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id, + const char* netdevId, + struct in_addr* addr, + int prefix) noexcept +{ + assert(id); assert(netdevId); assert(addr); - NetdevAttrs attrs; - VsmStatus ret = getNetdevAttrs(zone, netdevId, attrs); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - - auto it = find_if(attrs.begin(), attrs.end(), [](const tuple& entry) { - return get<0>(entry) == "ipv6"; + return coverException([&] { + string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix); + mHostClient.callSetNetdevAttrs({ id, netdevId, { { "ipv4", value } } } ); }); - if (it != attrs.end()) { - vector addrAttrs; - for(auto addrAttr : split(addrAttrs, get<1>(*it), is_any_of(","))) { - size_t pos = addrAttr.find(":"); - if (addrAttr.substr(0, pos) == "ip") { - if (pos != string::npos && pos < addrAttr.length() && - inet_pton(AF_INET6, addrAttr.substr(pos + 1).c_str(), addr) == 1) { - //XXX: return only one address - mStatus = Status(); - return vsm_get_status(); - } else { - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data"); - return vsm_get_status(); - } - } - } - } - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Address not found"); - return vsm_get_status(); } -VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* zone, - const char* netdevId, - struct in_addr* addr, - int prefix) noexcept +VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id, + const char* netdevId, + struct in6_addr* addr, + int prefix) noexcept { - try { - GVariant* dict = createTupleArray({make_tuple("ipv4", - "ip:" + toString(addr) + "," - "prefixlen:" + to_string(prefix))}); - GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict); - return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in); - } catch (exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } -} + assert(id); + assert(netdevId); + assert(addr); -VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone, - const char* netdevId, - struct in6_addr* addr, - int prefix) noexcept -{ - try { - GVariant* dict = createTupleArray({make_tuple("ipv6", - "ip:" + toString(addr) + "," - "prefixlen:" + to_string(prefix))}); - GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict); - return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in); - } catch (exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } + return coverException([&] { + string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix); + mHostClient.callSetNetdevAttrs({ id, netdevId, { { "ipv6", value } } } ); + }); } -VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* zone, - const char* netdevId, - struct in_addr* addr, - int prefix) noexcept +VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* id, + const char* netdevId, + struct in_addr* addr, + int prefix) noexcept { - std::string ip; - try { - //CIDR notation - ip = toString(addr) + "/" + to_string(prefix); - } catch(const std::exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } + assert(id); + assert(netdevId); + assert(addr); - GVariant* args_in = g_variant_new("(sss)", zone, netdevId, ip.c_str()); - return callMethod(HOST_INTERFACE, api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, args_in); + return coverException([&] { + //CIDR notation + string ip = toString(addr) + "/" + to_string(prefix); + mHostClient.callDeleteNetdevIpAddress({ id, netdevId, ip }); + }); } -VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* zone, - const char* netdevId, - struct in6_addr* addr, - int prefix) noexcept +VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* id, + const char* netdevId, + struct in6_addr* addr, + int prefix) noexcept { + assert(id); + assert(netdevId); + assert(addr); - std::string ip; - try { + return coverException([&] { //CIDR notation - ip = toString(addr) + "/" + to_string(prefix); - } catch(const std::exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } - - GVariant* args_in = g_variant_new("(sss)", zone, netdevId, ip.c_str()); - return callMethod(HOST_INTERFACE, api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, args_in); + string ip = toString(addr) + "/" + to_string(prefix); + mHostClient.callDeleteNetdevIpAddress({ id, netdevId, ip }); + }); } -VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept +VsmStatus Client::vsm_netdev_up(const char* id, const char* netdevId) noexcept { - try { - GVariant* dict = createTupleArray({make_tuple("flags", to_string(IFF_UP)), - make_tuple("change", to_string(IFF_UP))}); - GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict); - return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in); - } catch (exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } + assert(id); + assert(netdevId); + + return coverException([&] { + mHostClient.callSetNetdevAttrs({ id, netdevId, { { "flags", to_string(IFF_UP) }, + { "change", to_string(IFF_UP) } } } ); + }); } -VsmStatus Client::vsm_netdev_down(const char* zone, const char* netdevId) noexcept +VsmStatus Client::vsm_netdev_down(const char* id, const char* netdevId) noexcept { - try { - GVariant* dict = createTupleArray({make_tuple("flags", to_string(~IFF_UP)), - make_tuple("change", to_string(IFF_UP))}); - GVariant* args_in = g_variant_new("(ss@a(ss))", zone, netdevId, dict); - return callMethod(HOST_INTERFACE, api::host::METHOD_SET_NETDEV_ATTRS, args_in); - } catch (exception& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - return vsm_get_status(); - } + assert(id); + assert(netdevId); + + return coverException([&] { + mHostClient.callSetNetdevAttrs({ id, netdevId, { { "flags", to_string(~IFF_UP) }, + { "change", to_string(IFF_UP) } } } ); + }); } -VsmStatus Client::vsm_create_netdev_veth(const char* zone, - const char* zoneDev, - const char* hostDev) noexcept +VsmStatus Client::vsm_create_netdev_veth(const char* id, + const char* zoneDev, + const char* hostDev) noexcept { - GVariant* args_in = g_variant_new("(sss)", zone, zoneDev, hostDev); - return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_NETDEV_VETH, args_in); + assert(id); + assert(zoneDev); + assert(hostDev); + + return coverException([&] { + mHostClient.callCreateNetdevVeth({ id, zoneDev, hostDev }); + }); } -VsmStatus Client::vsm_create_netdev_macvlan(const char* zone, - const char* zoneDev, - const char* hostDev, - enum macvlan_mode mode) noexcept +VsmStatus Client::vsm_create_netdev_macvlan(const char* id, + const char* zoneDev, + const char* hostDev, + enum macvlan_mode mode) noexcept { - GVariant* args_in = g_variant_new("(sssu)", zone, zoneDev, hostDev, mode); - return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_NETDEV_MACVLAN, args_in); + assert(id); + assert(zoneDev); + assert(hostDev); + + return coverException([&] { + mHostClient.callCreateNetdevMacvlan({ id, zoneDev, hostDev, mode }); + }); } -VsmStatus Client::vsm_create_netdev_phys(const char* zone, const char* devId) noexcept +VsmStatus Client::vsm_create_netdev_phys(const char* id, const char* devId) noexcept { - GVariant* args_in = g_variant_new("(ss)", zone, devId); - return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_NETDEV_PHYS, args_in); + assert(id); + assert(devId); + + return coverException([&] { + mHostClient.callCreateNetdevPhys({ id, devId }); + }); } -VsmStatus Client::vsm_lookup_netdev_by_name(const char* zone, - const char* netdevId, - VsmNetdev* netdev) noexcept +VsmStatus Client::vsm_lookup_netdev_by_name(const char* id, + const char* netdevId, + VsmNetdev* netdev) noexcept { using namespace boost::algorithm; - assert(zone); + assert(id); assert(netdevId); assert(netdev); - NetdevAttrs attrs; - VsmStatus ret = getNetdevAttrs(zone, netdevId, attrs); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - - auto it = find_if(attrs.begin(), attrs.end(), [](const tuple& entry) { - return get<0>(entry) == "type"; - }); - - VsmNetdevType type; - if (it == attrs.end()) { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Can't fetch netdev type"); - return vsm_get_status(); - } + return coverException([&] { + api::GetNetDevAttrs attrs; + mHostClient.callGetNetdevAttrs({ id, netdevId }, attrs); + auto it = find_if(attrs.values.begin(), + attrs.values.end(), + [](const api::StringPair& entry) { + return entry.first == "type"; + }); + + VsmNetdevType type; + if (it == attrs.values.end()) { + throw OperationFailedException("Can't fetch netdev type"); + } - switch (stoi(get<1>(*it))) { - case 1<<0 /*IFF_802_1Q_VLAN*/: type = VSMNETDEV_VETH; break; - case 1<<21 /*IFF_MACVLAN*/: type = VSMNETDEV_MACVLAN; break; - default: - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Unknown netdev type: " + get<1>(*it)); - return vsm_get_status(); - } + switch (stoi(it->second)) { + case 1<<0 /*IFF_802_1Q_VLAN*/: type = VSMNETDEV_VETH; break; + case 1<<21 /*IFF_MACVLAN*/: type = VSMNETDEV_MACVLAN; break; + default: + throw InvalidResponseException("Unknown netdev type: " + it->second); + } - *netdev = reinterpret_cast(malloc(sizeof(**netdev))); - (*netdev)->name = strdup(zone); - (*netdev)->type = type; - mStatus = Status(); - return vsm_get_status(); + *netdev = reinterpret_cast(malloc(sizeof(**netdev))); + (*netdev)->name = ::strdup(id); + (*netdev)->type = type; + }); } -VsmStatus Client::vsm_destroy_netdev(const char* zone, const char* devId) noexcept +VsmStatus Client::vsm_destroy_netdev(const char* id, const char* devId) noexcept { - GVariant* args_in = g_variant_new("(ss)", zone, devId); - return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_NETDEV, args_in); + assert(id); + assert(devId); + + return coverException([&] { + mHostClient.callDestroyNetdev({ id, devId }); + }); } -VsmStatus Client::vsm_declare_file(const char* zone, - VsmFileType type, - const char *path, - int32_t flags, - mode_t mode, - VsmString* id) noexcept +VsmStatus Client::vsm_declare_file(const char* id, + VsmFileType type, + const char *path, + int32_t flags, + mode_t mode, + VsmString* declarationId) noexcept { + assert(id); assert(path); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(sisii)", zone, type, path, flags, mode); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_DECLARE_FILE, - args_in, - "(s)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - if (id != NULL) { - g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, id); - g_variant_unref(unpacked); - } - g_variant_unref(out); - return ret; + return coverException([&] { + api::Declaration declaration; + mHostClient.callDeclareFile({ id, type, path, flags, (int)mode }, declaration); + if (declarationId != NULL) { + *declarationId = ::strdup(declaration.value.c_str()); + } + }); } VsmStatus Client::vsm_declare_mount(const char *source, - const char* zone, - const char *target, - const char *type, - uint64_t flags, - const char *data, - VsmString* id) noexcept + const char* id, + const char *target, + const char *type, + uint64_t flags, + const char *data, + VsmString* declarationId) noexcept { assert(source); + assert(id); assert(target); assert(type); if (!data) { data = ""; } - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(ssssts)", source, zone, target, type, flags, data); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_DECLARE_MOUNT, - args_in, - "(s)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - if (id != NULL) { - g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, id); - g_variant_unref(unpacked); - } - g_variant_unref(out); - return ret; + return coverException([&] { + api::Declaration declaration; + mHostClient.callDeclareMount({ source, id, target, type, flags, data }, declaration); + if (declarationId != NULL) { + *declarationId = ::strdup(declaration.value.c_str()); + } + }); } -VsmStatus Client::vsm_declare_link(const char *source, - const char* zone, - const char *target, - VsmString* id) noexcept +VsmStatus Client::vsm_declare_link(const char* source, + const char* id, + const char* target, + VsmString* declarationId) noexcept { assert(source); + assert(id); assert(target); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(sss)", source, zone, target); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_DECLARE_LINK, - args_in, - "(s)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - if (id != NULL) { - g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, id); - g_variant_unref(unpacked); - } - g_variant_unref(out); - return ret; + return coverException([&] { + api::Declaration declaration; + mHostClient.callDeclareLink({ source, id, target }, declaration); + if (declarationId != NULL) { + *declarationId = ::strdup(declaration.value.c_str()); + } + }); } -VsmStatus Client::vsm_list_declarations(const char* zone, VsmArrayString* declarations) +VsmStatus Client::vsm_list_declarations(const char* id, VsmArrayString* declarations) noexcept { + assert(id); assert(declarations); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(s)", zone); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_DECLARATIONS, - args_in, - "(as)", - &out); - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toArray(unpacked, declarations); - g_variant_unref(unpacked); - g_variant_unref(out); - return ret; + return coverException([&] { + api::Declarations declarationsOut; + mHostClient.callGetDeclarations({ id }, declarationsOut); + convert(declarationsOut, *declarations); + }); } -VsmStatus Client::vsm_remove_declaration(const char* zone, VsmString declaration) +VsmStatus Client::vsm_remove_declaration(const char* id, VsmString declaration) noexcept { + assert(id); assert(declaration); - GVariant* args_in = g_variant_new("(ss)", zone, declaration); - return callMethod(HOST_INTERFACE, - api::host::METHOD_REMOVE_DECLARATION, - args_in); + return coverException([&] { + mHostClient.callRemoveDeclaration({ id, declaration }); + }); } VsmStatus Client::vsm_notify_active_zone(const char* application, const char* message) noexcept @@ -1004,10 +754,9 @@ VsmStatus Client::vsm_notify_active_zone(const char* application, const char* me assert(application); assert(message); - GVariant* args_in = g_variant_new("(ss)", application, message); - return callMethod(ZONE_INTERFACE, - api::zone::METHOD_NOTIFY_ACTIVE_ZONE, - args_in); + return coverException([&] { + mZoneClient.callNotifyActiveZone({ application, message }); + }); } VsmStatus Client::vsm_file_move_request(const char* destZone, const char* path) noexcept @@ -1015,50 +764,42 @@ VsmStatus Client::vsm_file_move_request(const char* destZone, const char* path) assert(destZone); assert(path); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(ss)", destZone, path); - VsmStatus ret = callMethod(ZONE_INTERFACE, - api::zone::METHOD_FILE_MOVE_REQUEST, - args_in, - "(s)", - &out); - - if (ret != VSMCLIENT_SUCCESS) { - return ret; - } - const gchar* retcode = NULL;; - g_variant_get(out, "(&s)", &retcode); - if (strcmp(retcode, api::zone::FILE_MOVE_SUCCEEDED.c_str()) != 0) { - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, retcode); - g_variant_unref(out); - return vsm_get_status(); - } - g_variant_unref(out); - return ret; + return coverException([&] { + api::FileMoveRequestStatus status; + mZoneClient.callFileMoveRequest({ destZone, path }, status); + if (status.value != api::zone::FILE_MOVE_SUCCEEDED) { + throw ClientException(status.value); + } + }); } VsmStatus Client::vsm_add_notification_callback(VsmNotificationCallback notificationCallback, - void* data, - VsmSubscriptionId* subscriptionId) noexcept + void* data, + VsmSubscriptionId* subscriptionId) noexcept { assert(notificationCallback); - auto onSigal = [=](GVariant * parameters) { - const char* zone; - const char* application; - const char* message; - g_variant_get(parameters, "(&s&s&s)", &zone, &application, &message); - notificationCallback(zone, application, message, data); - }; - - return signalSubscribe(ZONE_INTERFACE, - api::zone::SIGNAL_NOTIFICATION, - onSigal, - subscriptionId); + return coverException([&] { + auto onSignal = [=](const api::Notification& notification) + { + notificationCallback(notification.zone.c_str(), + notification.application.c_str(), + notification.message.c_str(), + data); + }; + + VsmSubscriptionId id; + id = mZoneClient.subscribeNotification(onSignal); + if (subscriptionId) { + *subscriptionId = id; + } + }); } VsmStatus Client::vsm_del_notification_callback(VsmSubscriptionId subscriptionId) noexcept { - return signalUnsubscribe(subscriptionId); + return coverException([&] { + mZoneClient.unsubscribe(subscriptionId); + }); } diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 4e01966..634b801 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -27,26 +27,12 @@ #define VASUM_CLIENT_IMPL_HPP #include "vasum-client.h" -#include -#include -#include -#include -#include -/** - * Structure which defines the dbus interface. - */ -struct DbusInterfaceInfo { - DbusInterfaceInfo(const std::string& busName, - const std::string& objectPath, - const std::string& interface) - : busName(busName), - objectPath(objectPath), - interface(interface) {} - const std::string busName; - const std::string objectPath; - const std::string interface; -}; +#include "host-dbus-connection.hpp" +#include "zone-dbus-connection.hpp" + +#include +#include /** * vasum's client definition. @@ -54,33 +40,6 @@ struct DbusInterfaceInfo { * Client uses dbus API. */ class Client { -private: - typedef std::vector> NetdevAttrs; - typedef std::function SignalCallback; - struct Status { - Status(); - Status(VsmStatus status, const std::string& msg); - VsmStatus mVsmStatus; - std::string mMsg; - }; - - dbus::DbusConnection::Pointer mConnection; - Status mStatus; - - VsmStatus callMethod(const DbusInterfaceInfo& info, - const std::string& method, - GVariant* args_in, - const std::string& args_spec_out = std::string(), - GVariant** args_out = NULL); - VsmStatus signalSubscribe(const DbusInterfaceInfo& info, - const std::string& name, - SignalCallback signalCallback, - VsmSubscriptionId* subscriptionId); - VsmStatus signalUnsubscribe(VsmSubscriptionId id); - VsmStatus getNetdevAttrs(const std::string& zone, - const std::string& netdev, - NetdevAttrs& attrs) noexcept; - public: Client() noexcept; ~Client() noexcept; @@ -323,12 +282,12 @@ public: /** * @see ::vsm_list_declarations */ - VsmStatus vsm_list_declarations(const char* zone, VsmArrayString* declarations); + VsmStatus vsm_list_declarations(const char* zone, VsmArrayString* declarations) noexcept; /** * @see ::vsm_remove_declaration */ - VsmStatus vsm_remove_declaration(const char* zone, VsmString declaration); + VsmStatus vsm_remove_declaration(const char* zone, VsmString declaration) noexcept; /** * @see ::vsm_notify_active_zone @@ -361,6 +320,23 @@ public: * @see ::vsm_stop_glib_loop */ static VsmStatus vsm_stop_glib_loop() noexcept; +private: + struct Status { + Status(); + Status(VsmStatus status, const std::string& msg = ""); + VsmStatus mVsmStatus; + std::string mMsg; + }; + + Status mStatus; + vasum::client::HostDbusConnection mHostClient; + vasum::client::ZoneDbusConnection mZoneClient; + + VsmStatus coverException(const std::function worker) noexcept; + VsmStatus vsm_netdev_get_ip_addr(const char* zone, + const char* netdevId, + int type, + void* addr) noexcept; }; #endif /* VASUM_CLIENT_IMPL_HPP */ diff --git a/client/zone-dbus-connection.cpp b/client/zone-dbus-connection.cpp new file mode 100644 index 0000000..b7f82a8 --- /dev/null +++ b/client/zone-dbus-connection.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 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 Zone client class + */ + +#include +#include "zone-dbus-connection.hpp" +#include +#include + +namespace vasum { +namespace client { + +ZoneDbusConnection::ZoneDbusConnection() + : mConnection(vasum::api::zone::DEFINITION, + vasum::api::zone::BUS_NAME, + vasum::api::zone::OBJECT_PATH, + vasum::api::zone::INTERFACE) +{ +} + +void ZoneDbusConnection::create(const std::shared_ptr& connection) +{ + mConnection.create(connection); +} + +void ZoneDbusConnection::callNotifyActiveZone(const vasum::api::NotifActiveZoneIn& argIn) +{ + mConnection.call(vasum::api::zone::METHOD_NOTIFY_ACTIVE_ZONE, argIn); +} + +void ZoneDbusConnection::callFileMoveRequest(const vasum::api::FileMoveRequestIn& argIn, + vasum::api::FileMoveRequestStatus& argOut) +{ + mConnection.call(vasum::api::zone::METHOD_FILE_MOVE_REQUEST, argIn, argOut); +} + +ZoneDbusConnection::SubscriptionId +ZoneDbusConnection::subscribeNotification(const NotificationCallback& callback) +{ + return mConnection.signalSubscribe( + vasum::api::zone::SIGNAL_NOTIFICATION, callback); +} + +void ZoneDbusConnection::unsubscribe(const SubscriptionId& id ) +{ + mConnection.signalUnsubscribe(id); +} + +} // namespace client +} // namespace vasum diff --git a/client/zone-dbus-connection.hpp b/client/zone-dbus-connection.hpp new file mode 100644 index 0000000..576b4cb --- /dev/null +++ b/client/zone-dbus-connection.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 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 Zone client class + */ + +#ifndef VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP +#define VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP + +#include "dbus-connection.hpp" +#include + +namespace vasum { +namespace client { + +/** + * vasum's client definition. + * + * ZoneDbusConnection is used for communication with the vasum's server from zone through dbus + */ +class ZoneDbusConnection { +public: + typedef unsigned int SubscriptionId; + typedef std::function NotificationCallback; + + ZoneDbusConnection(); + void create(const std::shared_ptr& connection); + + void callNotifyActiveZone(const vasum::api::NotifActiveZoneIn& argIn); + void callFileMoveRequest(const vasum::api::FileMoveRequestIn& argIn, + vasum::api::FileMoveRequestStatus& argOut); + SubscriptionId subscribeNotification(const NotificationCallback& callback); + void unsubscribe(const SubscriptionId& id); +private: + DbusConnection mConnection; +}; + +} // namespace client +} // namespace vasum + +#endif /* VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP */ diff --git a/common/api/messages.hpp b/common/api/messages.hpp index de193bd..de606c0 100644 --- a/common/api/messages.hpp +++ b/common/api/messages.hpp @@ -84,6 +84,9 @@ typedef api::StringPair RemoveDeclarationIn; typedef api::StringPair CreateZoneIn; typedef api::StringPair RevokeDeviceIn; typedef api::StringPair DestroyNetDevIn; +typedef api::StringPair DbusState; +typedef api::StringPair NotifActiveZoneIn; +typedef api::StringPair FileMoveRequestIn; typedef api::VectorOfStrings ZoneIds; typedef api::VectorOfStrings Declarations; typedef api::VectorOfStrings NetDevList; @@ -223,6 +226,20 @@ struct GrantDeviceIn ) }; +struct Notification +{ + std::string zone; + std::string application; + std::string message; + + CONFIG_REGISTER + ( + zone, + application, + message + ) +}; + } // namespace api } // namespace vasum -- 2.7.4 From fb166c64324481b35f4cba2386691e6a2fd93258 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 10 Apr 2015 15:08:30 +0200 Subject: [PATCH 02/16] Zones stopped by default when Vasum is starting. [Bug/Feature] Zones was always started. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests, run server. Change-Id: I5ca9ad8bdedea43a409d8f1c9061447c6462c4cc Signed-off-by: Dariusz Michaluk --- server/server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/server.cpp b/server/server.cpp index c2ca778..2271f08 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -107,7 +107,8 @@ void Server::run(bool asRoot) utils::ScopedGlibLoop loop; ZonesManager manager(mConfigPath); - manager.restoreAll(); + // Do not restore zones state at Vasum start + // manager.restoreAll(); LOGI("Daemon started"); gSignalLatch.wait(); -- 2.7.4 From f93b8129e0803f8c8374bbda05bc6630e67c63cd Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 9 Apr 2015 10:33:31 +0200 Subject: [PATCH 03/16] Host to host communication through IPC (switch to IPC #2) [Feature] Using IPC for host to host communication [Cause] Switching from Dbus to IPC [Solution] Using IPC in host and client [Verification] run ClientSuite tests with Valgrind Change-Id: I45bda31482fbf0a6a1dab7d14cc407bfd73a96c1 --- CMakeLists.txt | 2 + client/CMakeLists.txt | 19 +- client/host-ipc-connection.cpp | 183 ++++++++++++++ client/host-ipc-connection.hpp | 80 ++++++ client/ipc-connection.cpp | 47 ++++ client/ipc-connection.hpp | 90 +++++++ client/vasum-client-impl.cpp | 11 +- client/vasum-client-impl.hpp | 18 +- common/ipc/service.cpp | 14 +- ...ost-connection.cpp => host-dbus-connection.cpp} | 81 +++--- ...ost-connection.hpp => host-dbus-connection.hpp} | 17 +- server/host-ipc-connection.cpp | 272 +++++++++++++++++++++ server/host-ipc-connection.hpp | 119 +++++++++ server/host-ipc-definitions.hpp | 68 ++++++ server/zones-manager.cpp | 12 +- server/zones-manager.hpp | 11 +- 16 files changed, 977 insertions(+), 67 deletions(-) create mode 100644 client/host-ipc-connection.cpp create mode 100644 client/host-ipc-connection.hpp create mode 100644 client/ipc-connection.cpp create mode 100644 client/ipc-connection.hpp rename server/{host-connection.cpp => host-dbus-connection.cpp} (83%) rename server/{host-connection.hpp => host-dbus-connection.hpp} (97%) create mode 100644 server/host-ipc-connection.cpp create mode 100644 server/host-ipc-connection.hpp create mode 100644 server/host-ipc-definitions.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 743860b..e7f7aff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,8 @@ ADD_DEFINITIONS(-DVASUM_USER="${VASUM_USER}") ADD_DEFINITIONS(-DINPUT_EVENT_GROUP="${INPUT_EVENT_GROUP}") ADD_DEFINITIONS(-DDISK_GROUP="${DISK_GROUP}") ADD_DEFINITIONS(-DTTY_GROUP="${TTY_GROUP}") +ADD_DEFINITIONS(-DHOST_IPC_SOCKET="/var/run/vasum-ipc.socket") +#ADD_DEFINITIONS(-DDBUS_CONNECTION) ## Python packages directory ################################################### IF(NOT DEFINED PYTHON_SITELIB) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 7198610..0ebbf75 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -25,7 +25,17 @@ FILE(GLOB common_SRCS ${COMMON_FOLDER}/utils/callback-guard.hpp ${COMMON_FOLDER}/utils/glib-loop.cpp ${COMMON_FOLDER}/utils/glib-loop.hpp ${COMMON_FOLDER}/base-exception.hpp - ${COMMON_FOLDER}/base-exception.cpp) + ${COMMON_FOLDER}/base-exception.cpp + ${COMMON_FOLDER}/utils/eventfd.hpp + ${COMMON_FOLDER}/utils/eventfd.cpp + ${COMMON_FOLDER}/utils/fd-utils.hpp + ${COMMON_FOLDER}/utils/fd-utils.cpp + ${COMMON_FOLDER}/epoll/*.hpp + ${COMMON_FOLDER}/epoll/*.cpp + ${COMMON_FOLDER}/ipc/*.hpp + ${COMMON_FOLDER}/ipc/*.cpp + ${COMMON_FOLDER}/ipc/internals/*.hpp + ${COMMON_FOLDER}/ipc/internals/*.cpp) SET(_LIB_VERSION_ "0.0.1") SET(_LIB_SOVERSION_ "0") @@ -44,11 +54,12 @@ SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger libConfig) -INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS}) +FIND_PACKAGE(Boost COMPONENTS system filesystem) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger libConfig libsystemd-daemon) +INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${SERVER_FOLDER}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES}) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/client/host-ipc-connection.cpp b/client/host-ipc-connection.cpp new file mode 100644 index 0000000..6a22e6b --- /dev/null +++ b/client/host-ipc-connection.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2015 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 HostIPCConnection class + */ + +#include +#include "host-ipc-connection.hpp" +#include +#include + +namespace vasum { +namespace client { + +void HostIPCConnection::createSystem() +{ + mConnection.createSystem(); +} + +void HostIPCConnection::callGetZoneIds(vasum::api::ZoneIds& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_ID_LIST, argOut); +} + +void HostIPCConnection::callGetActiveZoneId(vasum::api::ZoneId& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ACTIVE_ZONE_ID, argOut); +} + +void HostIPCConnection::callSetActiveZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SET_ACTIVE_ZONE, argIn); +} + +void HostIPCConnection::callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_INFO, argIn, argOut); +} + +void HostIPCConnection::callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SET_NETDEV_ATTRS, argIn); +} + +void HostIPCConnection::callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_NETDEV_ATTRS, argIn, argOut); +} + +void HostIPCConnection::callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_NETDEV_LIST, argIn, argOut); +} + +void HostIPCConnection::callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_VETH, argIn); +} + +void HostIPCConnection::callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_MACVLAN, argIn); +} + +void HostIPCConnection::callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_PHYS, argIn); +} + +void HostIPCConnection::callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DESTROY_NETDEV, argIn); +} + +void HostIPCConnection::callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, argIn); +} + +void HostIPCConnection::callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_FILE, argIn, argOut); +} + +void HostIPCConnection::callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_MOUNT, argIn, argOut); +} + +void HostIPCConnection::callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut) +{ + mConnection.call(vasum::api::host::METHOD_DECLARE_LINK, argIn, argOut); +} + +void HostIPCConnection::callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_DECLARATIONS, argIn, argOut); +} + +void HostIPCConnection::callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_REMOVE_DECLARATION, argIn); +} + +void HostIPCConnection::callCreateZone(const vasum::api::CreateZoneIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_CREATE_ZONE, argIn); +} + +void HostIPCConnection::callDestroyZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_DESTROY_ZONE, argIn); +} + +void HostIPCConnection::callShutdownZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_SHUTDOWN_ZONE, argIn); +} + +void HostIPCConnection::callStartZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_START_ZONE, argIn); +} + +void HostIPCConnection::callLockZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_LOCK_ZONE, argIn); +} + +void HostIPCConnection::callUnlockZone(const vasum::api::ZoneId& argIn) +{ + mConnection.call(vasum::api::host::METHOD_UNLOCK_ZONE, argIn); +} + +void HostIPCConnection::callGrantDevice(const vasum::api::GrantDeviceIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_GRANT_DEVICE, argIn); +} + +void HostIPCConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn) +{ + mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); +} + +void HostIPCConnection::callGetZoneDbuses(vasum::api::Dbuses& argOut) +{ + mConnection.call(vasum::api::host::METHOD_GET_ZONE_DBUSES, argOut); +} + +HostIPCConnection::SubscriptionId +HostIPCConnection::subscribeZoneDbusState(const ZoneDbusStateCallback& callback) +{ + mConnection.subscribe( + vasum::api::host::SIGNAL_ZONE_DBUS_STATE, callback); + return vasum::api::host::SIGNAL_ZONE_DBUS_STATE; +} + +void HostIPCConnection::unsubscribe(const SubscriptionId& id) +{ + mConnection.unsubscribe(id); +} + +} // namespace client +} // namespace vasum diff --git a/client/host-ipc-connection.hpp b/client/host-ipc-connection.hpp new file mode 100644 index 0000000..83313e1 --- /dev/null +++ b/client/host-ipc-connection.hpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 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 HostIPCConnection class + */ + +#ifndef VASUM_CLIENT_HOST_IPC_CONNECTION_HPP +#define VASUM_CLIENT_HOST_IPC_CONNECTION_HPP + +#include "ipc-connection.hpp" +#include + +namespace vasum { +namespace client { + +/** + * HostIPCConnection is used for communication with the vasum's server from host through ipc + */ +class HostIPCConnection { +public: + typedef unsigned int SubscriptionId; + typedef std::function ZoneDbusStateCallback; + void createSystem(); + + void callGetZoneIds(vasum::api::ZoneIds& argOut); + void callGetActiveZoneId(vasum::api::ZoneId& argOut); + void callSetActiveZone(const vasum::api::ZoneId& argIn); + void callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut); + void callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn); + void callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut); + void callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut); + void callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn); + void callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn); + void callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn); + void callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn); + void callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn); + void callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut); + void callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut); + void callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut); + void callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut); + void callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn); + void callCreateZone(const vasum::api::CreateZoneIn& argIn); + void callDestroyZone(const vasum::api::ZoneId& argIn); + void callShutdownZone(const vasum::api::ZoneId& argIn); + void callStartZone(const vasum::api::ZoneId& argIn); + void callLockZone(const vasum::api::ZoneId& argIn); + void callUnlockZone(const vasum::api::ZoneId& argIn); + void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); + void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); + void callGetZoneDbuses(vasum::api::Dbuses& argOut); + SubscriptionId subscribeZoneDbusState(const ZoneDbusStateCallback& callback); + void unsubscribe(const SubscriptionId& id); + +private: + IPCConnection mConnection; +}; + +} // namespace client +} // namespace vasum + +#endif /* VASUM_CLIENT_HOST_IPC_CONNECTION_HPP */ diff --git a/client/ipc-connection.cpp b/client/ipc-connection.cpp new file mode 100644 index 0000000..04954bc --- /dev/null +++ b/client/ipc-connection.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015 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 IPCConnection class + */ + +#include +#include "ipc-connection.hpp" + +namespace { + +const std::string SOCKET_PATH = HOST_IPC_SOCKET; + +} // namespace + +vasum::client::IPCConnection::IPCConnection() +{ +} + +vasum::client::IPCConnection::~IPCConnection() +{ +} + +void vasum::client::IPCConnection::createSystem() +{ + mClient.reset(new ipc::Client(mDispatcher.getPoll(), SOCKET_PATH)); + mClient->start(); +} diff --git a/client/ipc-connection.hpp b/client/ipc-connection.hpp new file mode 100644 index 0000000..1cb4d10 --- /dev/null +++ b/client/ipc-connection.hpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015 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 IPCConnection class + */ + +#ifndef VASUM_CLIENT_IPC_CONNECTION_HPP +#define VASUM_CLIENT_IPC_CONNECTION_HPP + +#include +#include +#include +#include +#include +#include + +namespace vasum { +namespace client { + +/** + * IPCConnection class + */ +class IPCConnection { +public: + IPCConnection(); + virtual ~IPCConnection(); + + void createSystem(); + + template + typename std::enable_if::value>::type + call(const ipc::MethodID method, const ArgIn& argIn, ArgOut& argOut, unsigned int timeout = 50000) { + auto out = mClient->callSync(method, std::make_shared(argIn), timeout); + argOut = *out; + } + + template + typename std::enable_if::value>::type + call(const ipc::MethodID method, ArgOut& argOut, unsigned int timeout = 50000) { + vasum::api::Void argIn; + call(method, argIn, argOut, timeout); + } + + template + typename std::enable_if::value>::type + call(const ipc::MethodID method, ArgIn& argIn, unsigned int timeout = 50000) { + vasum::api::Void argOut; + call(method, argIn, argOut, timeout); + } + + template + void subscribe(const ipc::MethodID signal, const Callback& callback) { + auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { + callback(*data); + }; + mClient->setSignalHandler(signal, callbackWrapper); + } + + void unsubscribe(const ipc::MethodID signal) { + mClient->removeMethod(signal); + } + +private: + epoll::ThreadDispatcher mDispatcher; + std::unique_ptr mClient; +}; + +} // namespace client +} // namespace vasum + +#endif /* VASUM_CLIENT_IPC_CONNECTION_HPP */ diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 41a0030..2d85fb0 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -28,6 +28,7 @@ #include "utils.hpp" #include "exception.hpp" #include "host-dbus-connection.hpp" +#include "host-ipc-connection.hpp" #include "zone-dbus-connection.hpp" #include @@ -182,7 +183,7 @@ Client::~Client() noexcept { } -VsmStatus Client::coverException(const function worker) noexcept +VsmStatus Client::coverException(const function& worker) noexcept { try { worker(); @@ -218,7 +219,11 @@ VsmStatus Client::createSystem() noexcept return coverException([&] { shared_ptr connection(dbus::DbusConnection::createSystem().release()); +#ifdef DBUS_CONNECTION mHostClient.create(connection); +#else + mHostClient.createSystem(); +#endif mZoneClient.create(connection); }); } @@ -228,7 +233,11 @@ VsmStatus Client::create(const string& address) noexcept return coverException([&] { shared_ptr connection(dbus::DbusConnection::create(address).release()); +#ifdef DBUS_CONNECTION mHostClient.create(connection); +#else + mHostClient.createSystem(); +#endif mZoneClient.create(connection); }); } diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 634b801..9e8118c 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -27,8 +27,11 @@ #define VASUM_CLIENT_IMPL_HPP #include "vasum-client.h" - +#ifdef DBUS_CONNECTION #include "host-dbus-connection.hpp" +#else +#include "host-ipc-connection.hpp" +#endif #include "zone-dbus-connection.hpp" #include @@ -321,6 +324,12 @@ public: */ static VsmStatus vsm_stop_glib_loop() noexcept; private: +#ifdef DBUS_CONNECTION + typedef vasum::client::HostDbusConnection HostConnection; +#else + typedef vasum::client::HostIPCConnection HostConnection; +#endif + typedef vasum::client::ZoneDbusConnection ZoneConnection; struct Status { Status(); Status(VsmStatus status, const std::string& msg = ""); @@ -329,10 +338,11 @@ private: }; Status mStatus; - vasum::client::HostDbusConnection mHostClient; - vasum::client::ZoneDbusConnection mZoneClient; - VsmStatus coverException(const std::function worker) noexcept; + HostConnection mHostClient; + ZoneConnection mZoneClient; + + VsmStatus coverException(const std::function& worker) noexcept; VsmStatus vsm_netdev_get_ip_addr(const char* zone, const char* netdevId, int type, diff --git a/common/ipc/service.cpp b/common/ipc/service.cpp index 849ce3c..d4e1b88 100644 --- a/common/ipc/service.cpp +++ b/common/ipc/service.cpp @@ -100,13 +100,17 @@ void Service::handle(const FileDescriptor fd, const epoll::Events pollEvents) return; } - if (pollEvents & EPOLLIN) { - mProcessor.handleInput(fd); - return; // because handleInput will handle RDHUP - } - if ((pollEvents & EPOLLHUP) || (pollEvents & EPOLLRDHUP)) { + //IN, HUP, RDHUP are set when client is disconnecting but there is 0 bytes to read, so + //assume that if IN and HUP or RDHUP are set then input data is garbage. + //Assumption is harmless because handleInput processes all message data. mProcessor.handleLostConnection(fd); + return; + } + + if (pollEvents & EPOLLIN) { + //Process all message data + mProcessor.handleInput(fd); } } diff --git a/server/host-connection.cpp b/server/host-dbus-connection.cpp similarity index 83% rename from server/host-connection.cpp rename to server/host-dbus-connection.cpp index 1bdd790..b3eb19d 100644 --- a/server/host-connection.cpp +++ b/server/host-dbus-connection.cpp @@ -24,7 +24,7 @@ #include "config.hpp" -#include "host-connection.hpp" +#include "host-dbus-connection.hpp" #include "host-dbus-definitions.hpp" #include "exception.hpp" #include "api/dbus-method-result-builder.hpp" @@ -45,7 +45,7 @@ const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000; } // namespace -HostConnection::HostConnection() +HostDbusConnection::HostDbusConnection() : mNameAcquired(false) , mNameLost(false) { @@ -54,8 +54,8 @@ HostConnection::HostConnection() LOGT("Setting DBUS name"); mDbusConnection->setName(api::host::BUS_NAME, - std::bind(&HostConnection::onNameAcquired, this), - std::bind(&HostConnection::onNameLost, this)); + std::bind(&HostDbusConnection::onNameAcquired, this), + std::bind(&HostDbusConnection::onNameLost, this)); if (!waitForName(NAME_ACQUIRED_TIMEOUT)) { LOGE("Could not acquire dbus name: " << api::host::BUS_NAME); @@ -66,17 +66,17 @@ HostConnection::HostConnection() using namespace std::placeholders; mDbusConnection->registerObject(api::host::OBJECT_PATH, api::host::DEFINITION, - std::bind(&HostConnection::onMessageCall, + std::bind(&HostDbusConnection::onMessageCall, this, _1, _2, _3, _4, _5)); LOGD("Connected"); } -HostConnection::~HostConnection() +HostDbusConnection::~HostDbusConnection() { } -bool HostConnection::waitForName(const unsigned int timeoutMs) +bool HostDbusConnection::waitForName(const unsigned int timeoutMs) { std::unique_lock lock(mNameMutex); mNameCondition.wait_for(lock, @@ -88,14 +88,14 @@ bool HostConnection::waitForName(const unsigned int timeoutMs) return mNameAcquired; } -void HostConnection::onNameAcquired() +void HostDbusConnection::onNameAcquired() { std::unique_lock lock(mNameMutex); mNameAcquired = true; mNameCondition.notify_one(); } -void HostConnection::onNameLost() +void HostDbusConnection::onNameLost() { std::unique_lock lock(mNameMutex); mNameLost = true; @@ -107,143 +107,143 @@ void HostConnection::onNameLost() } } -void HostConnection::setProxyCallCallback(const ProxyCallCallback& callback) +void HostDbusConnection::setProxyCallCallback(const ProxyCallCallback& callback) { mProxyCallCallback = callback; } -void HostConnection::setGetZoneDbusesCallback(const GetZoneDbusesCallback& callback) +void HostDbusConnection::setGetZoneDbusesCallback(const GetZoneDbusesCallback& callback) { mGetZoneDbusesCallback = callback; } -void HostConnection::setGetZoneIdsCallback(const GetZoneIdsCallback& callback) +void HostDbusConnection::setGetZoneIdsCallback(const GetZoneIdsCallback& callback) { mGetZoneIdsCallback = callback; } -void HostConnection::setGetActiveZoneIdCallback(const GetActiveZoneIdCallback& callback) +void HostDbusConnection::setGetActiveZoneIdCallback(const GetActiveZoneIdCallback& callback) { mGetActiveZoneIdCallback = callback; } -void HostConnection::setGetZoneInfoCallback(const GetZoneInfoCallback& callback) +void HostDbusConnection::setGetZoneInfoCallback(const GetZoneInfoCallback& callback) { mGetZoneInfoCallback = callback; } -void HostConnection::setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback) +void HostDbusConnection::setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback) { mSetNetdevAttrsCallback = callback; } -void HostConnection::setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback) +void HostDbusConnection::setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback) { mGetNetdevAttrsCallback = callback; } -void HostConnection::setGetNetdevListCallback(const GetNetdevListCallback& callback) +void HostDbusConnection::setGetNetdevListCallback(const GetNetdevListCallback& callback) { mGetNetdevListCallback = callback; } -void HostConnection::setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback) +void HostDbusConnection::setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback) { mCreateNetdevVethCallback = callback; } -void HostConnection::setCreateNetdevMacvlanCallback(const CreateNetdevMacvlanCallback& callback) +void HostDbusConnection::setCreateNetdevMacvlanCallback(const CreateNetdevMacvlanCallback& callback) { mCreateNetdevMacvlanCallback = callback; } -void HostConnection::setCreateNetdevPhysCallback(const CreateNetdevPhysCallback& callback) +void HostDbusConnection::setCreateNetdevPhysCallback(const CreateNetdevPhysCallback& callback) { mCreateNetdevPhysCallback = callback; } -void HostConnection::setDestroyNetdevCallback(const DestroyNetdevCallback& callback) +void HostDbusConnection::setDestroyNetdevCallback(const DestroyNetdevCallback& callback) { mDestroyNetdevCallback = callback; } -void HostConnection::setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback) +void HostDbusConnection::setDeleteNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback) { mDeleteNetdevIpAddressCallback = callback; } -void HostConnection::setDeclareFileCallback(const DeclareFileCallback& callback) +void HostDbusConnection::setDeclareFileCallback(const DeclareFileCallback& callback) { mDeclareFileCallback = callback; } -void HostConnection::setDeclareMountCallback(const DeclareMountCallback& callback) +void HostDbusConnection::setDeclareMountCallback(const DeclareMountCallback& callback) { mDeclareMountCallback = callback; } -void HostConnection::setDeclareLinkCallback(const DeclareLinkCallback& callback) +void HostDbusConnection::setDeclareLinkCallback(const DeclareLinkCallback& callback) { mDeclareLinkCallback = callback; } -void HostConnection::setGetDeclarationsCallback(const GetDeclarationsCallback& callback) +void HostDbusConnection::setGetDeclarationsCallback(const GetDeclarationsCallback& callback) { mGetDeclarationsCallback = callback; } -void HostConnection::setRemoveDeclarationCallback(const RemoveDeclarationCallback& callback) +void HostDbusConnection::setRemoveDeclarationCallback(const RemoveDeclarationCallback& callback) { mRemoveDeclarationCallback = callback; } -void HostConnection::setSetActiveZoneCallback(const SetActiveZoneCallback& callback) +void HostDbusConnection::setSetActiveZoneCallback(const SetActiveZoneCallback& callback) { mSetActiveZoneCallback = callback; } -void HostConnection::setCreateZoneCallback(const CreateZoneCallback& callback) +void HostDbusConnection::setCreateZoneCallback(const CreateZoneCallback& callback) { mCreateZoneCallback = callback; } -void HostConnection::setDestroyZoneCallback(const DestroyZoneCallback& callback) +void HostDbusConnection::setDestroyZoneCallback(const DestroyZoneCallback& callback) { mDestroyZoneCallback = callback; } -void HostConnection::setShutdownZoneCallback(const ShutdownZoneCallback& callback) +void HostDbusConnection::setShutdownZoneCallback(const ShutdownZoneCallback& callback) { mShutdownZoneCallback = callback; } -void HostConnection::setStartZoneCallback(const StartZoneCallback& callback) +void HostDbusConnection::setStartZoneCallback(const StartZoneCallback& callback) { mStartZoneCallback = callback; } -void HostConnection::setLockZoneCallback(const LockZoneCallback& callback) +void HostDbusConnection::setLockZoneCallback(const LockZoneCallback& callback) { mLockZoneCallback = callback; } -void HostConnection::setUnlockZoneCallback(const UnlockZoneCallback& callback) +void HostDbusConnection::setUnlockZoneCallback(const UnlockZoneCallback& callback) { mUnlockZoneCallback = callback; } -void HostConnection::setGrantDeviceCallback(const GrantDeviceCallback& callback) +void HostDbusConnection::setGrantDeviceCallback(const GrantDeviceCallback& callback) { mGrantDeviceCallback = callback; } -void HostConnection::setRevokeDeviceCallback(const RevokeDeviceCallback& callback) +void HostDbusConnection::setRevokeDeviceCallback(const RevokeDeviceCallback& callback) { mRevokeDeviceCallback = callback; } -void HostConnection::onMessageCall(const std::string& objectPath, +void HostDbusConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, GVariant* parameters, @@ -553,7 +553,7 @@ void HostConnection::onMessageCall(const std::string& objectPath, } } -void HostConnection::proxyCallAsync(const std::string& busName, +void HostDbusConnection::proxyCallAsync(const std::string& busName, const std::string& objectPath, const std::string& interface, const std::string& method, @@ -569,10 +569,9 @@ void HostConnection::proxyCallAsync(const std::string& busName, callback); } -void HostConnection::signalZoneDbusState(const std::string& zoneId, - const std::string& dbusAddress) +void HostDbusConnection::signalZoneDbusState(const api::DbusState& state) { - GVariant* parameters = g_variant_new("(ss)", zoneId.c_str(), dbusAddress.c_str()); + GVariant* parameters = g_variant_new("(ss)", state.first.c_str(), state.second.c_str()); mDbusConnection->emitSignal(api::host::OBJECT_PATH, api::host::INTERFACE, api::host::SIGNAL_ZONE_DBUS_STATE, diff --git a/server/host-connection.hpp b/server/host-dbus-connection.hpp similarity index 97% rename from server/host-connection.hpp rename to server/host-dbus-connection.hpp index 4ad07c8..980b5e9 100644 --- a/server/host-connection.hpp +++ b/server/host-dbus-connection.hpp @@ -23,13 +23,14 @@ */ -#ifndef SERVER_HOST_CONNECTION_HPP -#define SERVER_HOST_CONNECTION_HPP +#ifndef SERVER_HOST_DBUS_CONNECTION_HPP +#define SERVER_HOST_DBUS_CONNECTION_HPP #include "dbus/connection.hpp" #include "api/method-result-builder.hpp" #include "api/messages.hpp" +#include #include #include #include @@ -39,11 +40,11 @@ namespace vasum { -class HostConnection { +class HostDbusConnection { public: - HostConnection(); - ~HostConnection(); + HostDbusConnection(); + ~HostDbusConnection(); // ------------- API -------------- @@ -144,7 +145,7 @@ public: /** * Send signal describing dbus address state change */ - void signalZoneDbusState(const std::string& zoneId, const std::string& dbusAddress); + void signalZoneDbusState(const api::DbusState& state); /** * Register a callback called to get a list of zone ids @@ -199,7 +200,7 @@ public: /** * Register a callback called to remove ip address from netdev */ - void setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback); + void setDeleteNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback); /** * Register a callback called to declare file @@ -330,4 +331,4 @@ private: } // namespace vasum -#endif // SERVER_HOST_CONNECTION_HPP +#endif // SERVER_HOST_DBUS_CONNECTION_HPP diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp new file mode 100644 index 0000000..bb8d081 --- /dev/null +++ b/server/host-ipc-connection.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2015 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 HostIPCConnection class + */ + +#include "config.hpp" + +#include "host-ipc-connection.hpp" +#include "host-ipc-definitions.hpp" +#include "exception.hpp" +#include "logger/logger.hpp" + +namespace vasum { + +namespace { + +const std::string SOCKET_PATH = HOST_IPC_SOCKET; + +} // namespace + + +HostIPCConnection::HostIPCConnection() +{ + LOGT("Connecting to host IPC socket"); + mService.reset(new ipc::Service(mDispatcher.getPoll(), SOCKET_PATH)); + + LOGT("Starting IPC"); + mService->start(); + LOGD("Connected"); +} + +HostIPCConnection::~HostIPCConnection() +{ +} + +void HostIPCConnection::setGetZoneDbusesCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_ZONE_DBUSES, + Callback::getCallbackWrapper(callback)); + +} + +void HostIPCConnection::setGetZoneIdsCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_ZONE_ID_LIST, + Callback::getCallbackWrapper(callback)); + +} + +void HostIPCConnection::setGetActiveZoneIdCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_ACTIVE_ZONE_ID, + Callback::getCallbackWrapper(callback)); + +} + +void HostIPCConnection::setGetZoneInfoCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_ZONE_INFO, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setSetNetdevAttrsCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_SET_NETDEV_ATTRS, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setGetNetdevAttrsCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_NETDEV_ATTRS, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setGetNetdevListCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_NETDEV_LIST, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setCreateNetdevVethCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_CREATE_NETDEV_VETH, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setCreateNetdevMacvlanCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_CREATE_NETDEV_MACVLAN, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setCreateNetdevPhysCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_CREATE_NETDEV_PHYS, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDestroyNetdevCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DESTROY_NETDEV, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDeleteNetdevIpAddressCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDeclareFileCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DECLARE_FILE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDeclareMountCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DECLARE_MOUNT, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDeclareLinkCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DECLARE_LINK, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setGetDeclarationsCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GET_DECLARATIONS, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setRemoveDeclarationCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_REMOVE_DECLARATION, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setSetActiveZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_SET_ACTIVE_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setCreateZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_CREATE_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setDestroyZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_DESTROY_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setShutdownZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_SHUTDOWN_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setStartZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_START_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setLockZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_LOCK_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setUnlockZoneCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_UNLOCK_ZONE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setGrantDeviceCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_GRANT_DEVICE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::setRevokeDeviceCallback(const Callback::type& callback) +{ + typedef Callback Callback; + mService->setMethodHandler( + api::host::METHOD_REVOKE_DEVICE, + Callback::getCallbackWrapper(callback)); +} + +void HostIPCConnection::signalZoneDbusState(const api::DbusState& dbusState) +{ + mService->signal(api::host::SIGNAL_ZONE_DBUS_STATE, + std::make_shared(dbusState)); +} + +} // namespace vasum diff --git a/server/host-ipc-connection.hpp b/server/host-ipc-connection.hpp new file mode 100644 index 0000000..e8c1c8d --- /dev/null +++ b/server/host-ipc-connection.hpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2015 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 HostIPCConnection class + */ + + +#ifndef SERVER_HOST_IPC_CONNECTION_HPP +#define SERVER_HOST_IPC_CONNECTION_HPP + +#include "api/messages.hpp" +#include "api/method-result-builder.hpp" +#include "api/ipc-method-result-builder.hpp" +#include "epoll/thread-dispatcher.hpp" +#include "ipc/service.hpp" + +#include + +namespace vasum { + + + +class HostIPCConnection { +public: + template + class Callback { + public: + typedef typename std::remove_cv::type in; + typedef ArgOut out; + typedef std::function type; + + static typename ipc::MethodHandler::type + getCallbackWrapper(const type& callback) { + return [callback](const ipc::PeerID, + const std::shared_ptr& argIn, + ipc::MethodResult::Pointer&& argOut) + { + auto rb = std::make_shared(argOut); + callback(*argIn, rb); + }; + } + }; + + template + class Callback::value, api::Void>::type> { + public: + typedef api::Void in; + typedef ArgOut out; + typedef std::function type; + + static typename ipc::MethodHandler::type + getCallbackWrapper(const type& callback) { + return [callback](const ipc::PeerID, + const std::shared_ptr& /* argIn */, + ipc::MethodResult::Pointer&& argOut) + { + auto rb = std::make_shared(argOut); + callback(rb); + }; + } + }; + + HostIPCConnection(); + ~HostIPCConnection(); + + void setGetZoneDbusesCallback(const Callback::type& callback); + void setGetZoneIdsCallback(const Callback::type& callback); + void setGetActiveZoneIdCallback(const Callback::type& callback); + void setGetZoneInfoCallback(const Callback::type& callback); + void setSetNetdevAttrsCallback(const Callback::type& callback); + void setGetNetdevAttrsCallback(const Callback::type& callback); + void setGetNetdevListCallback(const Callback::type& callback); + void setCreateNetdevVethCallback(const Callback::type& callback); + void setCreateNetdevMacvlanCallback(const Callback::type& callback); + void setCreateNetdevPhysCallback(const Callback::type& callback); + void setDestroyNetdevCallback(const Callback::type& callback); + void setDeleteNetdevIpAddressCallback(const Callback::type& callback); + void setDeclareFileCallback(const Callback::type& callback); + void setDeclareMountCallback(const Callback::type& callback); + void setDeclareLinkCallback(const Callback::type& callback); + void setGetDeclarationsCallback(const Callback::type& callback); + void setRemoveDeclarationCallback(const Callback::type& callback); + void setSetActiveZoneCallback(const Callback::type& callback); + void setCreateZoneCallback(const Callback::type& callback); + void setDestroyZoneCallback(const Callback::type& callback); + void setShutdownZoneCallback(const Callback::type& callback); + void setStartZoneCallback(const Callback::type& callback); + void setLockZoneCallback(const Callback::type& callback); + void setUnlockZoneCallback(const Callback::type& callback); + void setGrantDeviceCallback(const Callback::type& callback); + void setRevokeDeviceCallback(const Callback::type& callback); + void signalZoneDbusState(const api::DbusState& dbusState); + +private: + epoll::ThreadDispatcher mDispatcher; + std::unique_ptr mService; +}; + +} // namespace vasum + +#endif // SERVER_HOST_IPC_CONNECTION_HPP diff --git a/server/host-ipc-definitions.hpp b/server/host-ipc-definitions.hpp new file mode 100644 index 0000000..4cd06e7 --- /dev/null +++ b/server/host-ipc-definitions.hpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 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 Host ipc api definitions + */ + +#ifndef SERVER_HOST_IPC_DEFINITIONS_HPP +#define SERVER_HOST_IPC_DEFINITIONS_HPP + +#include "ipc/types.hpp" + +namespace vasum { +namespace api { +namespace host { + +const vasum::ipc::MethodID METHOD_GET_ZONE_DBUSES = 1; +const vasum::ipc::MethodID METHOD_GET_ZONE_ID_LIST = 2; +const vasum::ipc::MethodID METHOD_GET_ACTIVE_ZONE_ID = 3; +const vasum::ipc::MethodID METHOD_GET_ZONE_INFO = 4; +const vasum::ipc::MethodID METHOD_SET_NETDEV_ATTRS = 5; +const vasum::ipc::MethodID METHOD_GET_NETDEV_ATTRS = 6; +const vasum::ipc::MethodID METHOD_GET_NETDEV_LIST = 7; +const vasum::ipc::MethodID METHOD_CREATE_NETDEV_VETH = 8; +const vasum::ipc::MethodID METHOD_CREATE_NETDEV_MACVLAN = 9; +const vasum::ipc::MethodID METHOD_CREATE_NETDEV_PHYS = 10; +const vasum::ipc::MethodID METHOD_DELETE_NETDEV_IP_ADDRESS = 11; +const vasum::ipc::MethodID METHOD_DESTROY_NETDEV = 12; +const vasum::ipc::MethodID METHOD_DECLARE_FILE = 13; +const vasum::ipc::MethodID METHOD_DECLARE_MOUNT = 14; +const vasum::ipc::MethodID METHOD_DECLARE_LINK = 15; +const vasum::ipc::MethodID METHOD_GET_DECLARATIONS = 16; +const vasum::ipc::MethodID METHOD_REMOVE_DECLARATION = 17; +const vasum::ipc::MethodID METHOD_SET_ACTIVE_ZONE = 18; +const vasum::ipc::MethodID METHOD_CREATE_ZONE = 19; +const vasum::ipc::MethodID METHOD_DESTROY_ZONE = 20; +const vasum::ipc::MethodID METHOD_SHUTDOWN_ZONE = 21; +const vasum::ipc::MethodID METHOD_START_ZONE = 22; +const vasum::ipc::MethodID METHOD_LOCK_ZONE = 23; +const vasum::ipc::MethodID METHOD_UNLOCK_ZONE = 24; +const vasum::ipc::MethodID METHOD_GRANT_DEVICE = 25; +const vasum::ipc::MethodID METHOD_REVOKE_DEVICE = 26; + +const vasum::ipc::MethodID SIGNAL_ZONE_DBUS_STATE = 27; + +} // namespace host +} // namespace api +} // namespace vasum + + +#endif // SERVER_HOST_IPC_DEFINITIONS_HPP diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index d3e802b..11589bd 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -127,8 +127,10 @@ ZonesManager::ZonesManager(const std::string& configPath) mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); using namespace std::placeholders; +#ifdef DBUS_CONNECTION mHostConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall, this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); +#endif mHostConnection.setGetZoneDbusesCallback(bind(&ZonesManager::handleGetZoneDbusesCall, this, _1)); @@ -163,7 +165,7 @@ ZonesManager::ZonesManager(const std::string& configPath) mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, this, _1, _2)); - mHostConnection.setDeleleNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, + mHostConnection.setDeleteNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, this, _1, _2)); mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, @@ -717,12 +719,16 @@ void ZonesManager::handleProxyCall(const std::string& caller, }; if (target == HOST_ID) { +#ifdef DBUS_CONNECTION mHostConnection.proxyCallAsync(targetBusName, targetObjectPath, targetInterface, targetMethod, parameters, asyncResultCallback); +#else + result->setError(api::ERROR_INVALID_ID, "Unsupported proxy call target"); +#endif return; } @@ -755,10 +761,10 @@ void ZonesManager::handleGetZoneDbusesCall(api::MethodResultBuilder::Pointer res result->set(dbuses); } -void ZonesManager::handleDbusStateChanged(const std::string& zoneId, +void ZonesManager::handleDbusStateChanged(const std::string& zoneId , const std::string& dbusAddress) { - mHostConnection.signalZoneDbusState(zoneId, dbusAddress); + mHostConnection.signalZoneDbusState({zoneId, dbusAddress}); } void ZonesManager::handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result) diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index f789595..84285f3 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -28,7 +28,11 @@ #include "zone.hpp" #include "zones-manager-config.hpp" -#include "host-connection.hpp" +#ifdef DBUS_CONNECTION +#include "host-dbus-connection.hpp" +#else +#include "host-ipc-connection.hpp" +#endif #include "input-monitor.hpp" #include "proxy-call-policy.hpp" #include "utils/worker.hpp" @@ -114,6 +118,11 @@ public: private: typedef std::recursive_mutex Mutex; typedef std::unique_lock Lock; +#ifdef DBUS_CONNECTION + typedef HostDbusConnection HostConnection; +#else + typedef HostIPCConnection HostConnection; +#endif utils::Worker::Pointer mWorker; Mutex mMutex; // used to protect mZones -- 2.7.4 From 0d6b2ea9111fa21372e05f85478617e7ab6c2493 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 13 Apr 2015 15:05:24 +0200 Subject: [PATCH 04/16] Host to host communication test fix (switch to IPC #3) [Feature] Repaired tests that uses host to host communication [Cause] Switching from Dbus to IPC [Solution] Using IPCAccessory instead DbusAccessory [Verification] run tests with Valgrind Change-Id: Ia326bd98559691a7f5d61925760c811b0f5ea9a4 --- tests/unit_tests/server/ut-zones-manager.cpp | 524 ++++++++++++++++++++++----- 1 file changed, 430 insertions(+), 94 deletions(-) diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp index b140e6f..12a3dbe 100644 --- a/tests/unit_tests/server/ut-zones-manager.cpp +++ b/tests/unit_tests/server/ut-zones-manager.cpp @@ -28,7 +28,14 @@ #include "zones-manager.hpp" #include "zone-dbus-definitions.hpp" +#ifdef DBUS_CONNECTION #include "host-dbus-definitions.hpp" +#else +#include "host-ipc-definitions.hpp" +#include +#include +#include +#endif #include "test-dbus-definitions.hpp" // TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager #include "fake-power-manager-dbus-definitions.hpp" @@ -77,6 +84,7 @@ const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf const std::string SIMPLE_TEMPLATE = "console"; const std::string DBUS_TEMPLATE = "console-dbus"; +#ifdef DBUS_CONNECTION /** * Currently there is no way to propagate an error from async call * dropException are used to prevent system crash @@ -101,9 +109,19 @@ public: MethodResultBuilder::Pointer result )> TestApiMethodCallback; typedef std::function VoidResultCallback; + typedef std::function SignalCallback; typedef std::map Dbuses; + DbusAccessory() + : mId(0), + mClient(DbusConnection::create(acquireAddress())), + mNameAcquired(false), + mPendingDisconnect(false) + { + } + DbusAccessory(int id) : mId(id), mClient(DbusConnection::create(acquireAddress())), @@ -150,6 +168,26 @@ public: mClient->signalSubscribe(callback, isHost() ? api::host::BUS_NAME : api::zone::BUS_NAME); } + void subscribeZoneDbusState(const SignalCallback& callback) { + assert(isHost()); + auto onSignal = [callback] (const std::string& /*senderBusName*/, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant* parameters) { + if (objectPath == api::host::OBJECT_PATH && + interface == api::host::INTERFACE && + signalName == api::host::SIGNAL_ZONE_DBUS_STATE) { + + const gchar* zoneId = NULL; + const gchar* dbusAddress = NULL; + g_variant_get(parameters, "(&s&s)", &zoneId, &dbusAddress); + callback(zoneId, dbusAddress); + } + }; + mClient->signalSubscribe(onSignal, api::host::BUS_NAME); + } + void emitSignal(const std::string& objectPath, const std::string& interface, const std::string& name, @@ -451,6 +489,308 @@ private: } }; +typedef DbusAccessory HostAccessory; +typedef DbusAccessory ZoneAccessory; + +#else +//#ifdef DBUS_CONNECTION + +class HostIPCAccessory { +public: + typedef std::function TestApiMethodCallback; + typedef std::function VoidResultCallback; + typedef std::function SignalCallback; + + typedef std::map Dbuses; + + HostIPCAccessory() + : mClient(mDispatcher.getPoll(), HOST_IPC_SOCKET) + { + mClient.start(); + } + + void subscribeZoneDbusState(const SignalCallback& callback) + { + auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { + callback(data->first, data->second); + }; + mClient.setSignalHandler(api::host::SIGNAL_ZONE_DBUS_STATE, callbackWrapper); + } + + Dbuses callMethodGetZoneDbuses() + { + const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_DBUSES, + std::make_shared()); + Dbuses dbuses; + for (const auto& dbus : out->values) { + dbuses.insert(Dbuses::value_type(dbus.first, dbus.second)); + } + return dbuses; + } + + std::vector callMethodGetZoneIds() + { + const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_ID_LIST, + std::make_shared()); + return out->values; + } + + std::string callMethodGetActiveZoneId() + { + const auto out = mClient.callSync(api::host::METHOD_GET_ACTIVE_ZONE_ID, + std::make_shared()); + return out->value; + } + + void callMethodSetActiveZone(const std::string& id) + { + mClient.callSync(api::host::METHOD_SET_ACTIVE_ZONE, + std::make_shared(api::ZoneId{id})); + } + + void callAsyncMethodCreateZone(const std::string& id, + const std::string& templateName, + const VoidResultCallback& result) + { + auto asyncResult = [result](ipc::Result&& out) { + if (out.isValid()) { + result(); + } + }; + mClient.callAsync(api::host::METHOD_CREATE_ZONE, + std::make_shared(api::CreateZoneIn{id, templateName}), + asyncResult); + } + + void callAsyncMethodDestroyZone(const std::string& id, + const VoidResultCallback& result) + { + auto asyncResult = [result](ipc::Result&& out) { + if (out.isValid()) { + result(); + } + }; + mClient.callAsync(api::host::METHOD_DESTROY_ZONE, + std::make_shared(api::ZoneId{id}), + asyncResult); + } + + void callAsyncMethodShutdownZone(const std::string& id, + const VoidResultCallback& result) + { + auto asyncResult = [result](ipc::Result&& out) { + if (out.isValid()) { + result(); + } + }; + mClient.callAsync(api::host::METHOD_SHUTDOWN_ZONE, + std::make_shared(api::ZoneId{id}), + asyncResult); + } + + void callAsyncMethodStartZone(const std::string& id, + const VoidResultCallback& result) + { + auto asyncResult = [result](ipc::Result&& out) { + if (out.isValid()) { + result(); + } + }; + mClient.callAsync(api::host::METHOD_START_ZONE, + std::make_shared(api::ZoneId{id}), + asyncResult); + } + + void callMethodLockZone(const std::string& id) + { + mClient.callSync(api::host::METHOD_LOCK_ZONE, + std::make_shared(api::ZoneId{id}), + EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone + } + + void callMethodUnlockZone(const std::string& id) + { + mClient.callSync(api::host::METHOD_UNLOCK_ZONE, + std::make_shared(api::ZoneId{id}), + EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone + } + +private: + epoll::ThreadDispatcher mDispatcher; + ipc::Client mClient; +}; + +class ZoneDbusAccessory { +public: + typedef std::function TestApiMethodCallback; + + typedef std::map Dbuses; + + ZoneDbusAccessory(int id) + : mId(id), + mClient(DbusConnection::create(acquireAddress())), + mNameAcquired(false), + mPendingDisconnect(false) + { + } + + void setName(const std::string& name) + { + mClient->setName(name, + std::bind(&ZoneDbusAccessory::onNameAcquired, this), + std::bind(&ZoneDbusAccessory::onDisconnect, this)); + + if(!waitForName()) { + mClient.reset(); + throw dbus::DbusOperationException("Could not acquire name."); + } + } + + bool waitForName() + { + std::unique_lock lock(mMutex); + mNameCondition.wait(lock, [this] {return mNameAcquired || mPendingDisconnect;}); + return mNameAcquired; + } + + void onNameAcquired() + { + std::unique_lock lock(mMutex); + mNameAcquired = true; + mNameCondition.notify_one(); + } + + void onDisconnect() + { + std::unique_lock lock(mMutex); + mPendingDisconnect = true; + mNameCondition.notify_one(); + } + + void signalSubscribe(const DbusConnection::SignalCallback& callback) + { + mClient->signalSubscribe(callback, api::zone::BUS_NAME); + } + + void emitSignal(const std::string& objectPath, + const std::string& interface, + const std::string& name, + GVariant* parameters) + { + mClient->emitSignal(objectPath, interface, name, parameters); + } + + void callMethodNotify() + { + GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str()); + mClient->callMethod(api::zone::BUS_NAME, + api::zone::OBJECT_PATH, + api::zone::INTERFACE, + api::zone::METHOD_NOTIFY_ACTIVE_ZONE, + parameters, + "()"); + } + + std::string callMethodMove(const std::string& dest, const std::string& path) + { + GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str()); + GVariantPtr result = mClient->callMethod(api::zone::BUS_NAME, + api::zone::OBJECT_PATH, + api::zone::INTERFACE, + api::zone::METHOD_FILE_MOVE_REQUEST, + parameters, + "(s)"); + + const gchar* retcode = NULL; + g_variant_get(result.get(), "(&s)", &retcode); + return std::string(retcode); + } + + void registerTestApiObject(const TestApiMethodCallback& callback) + { + auto handler = [callback](const std::string& objectPath, + const std::string& interface, + const std::string& methodName, + GVariant* parameters, + MethodResultBuilder::Pointer result) { + if (objectPath == testapi::OBJECT_PATH && + interface == testapi::INTERFACE && + methodName == testapi::METHOD) { + const gchar* argument = NULL; + g_variant_get(parameters, "(&s)", &argument); + if (callback) { + callback(argument, result); + } + } + }; + mClient->registerObject(testapi::OBJECT_PATH, testapi::DEFINITION, handler); + } + + std::string testApiProxyCall(const std::string& target, const std::string& argument) + { + GVariant* parameters = g_variant_new("(s)", argument.c_str()); + GVariantPtr result = proxyCall(target, + testapi::BUS_NAME, + testapi::OBJECT_PATH, + testapi::INTERFACE, + testapi::METHOD, + parameters); + const gchar* ret = NULL; + g_variant_get(result.get(), "(&s)", &ret); + return ret; + } + + + GVariantPtr proxyCall(const std::string& target, + const std::string& busName, + const std::string& objectPath, + const std::string& interface, + const std::string& method, + GVariant* parameters) + { + GVariant* packedParameters = g_variant_new("(sssssv)", + target.c_str(), + busName.c_str(), + objectPath.c_str(), + interface.c_str(), + method.c_str(), + parameters); + GVariantPtr result = mClient->callMethod(api::zone::BUS_NAME, + api::zone::OBJECT_PATH, + api::zone::INTERFACE, + api::METHOD_PROXY_CALL, + packedParameters, + "(v)"); + GVariant* unpackedResult = NULL; + g_variant_get(result.get(), "(v)", &unpackedResult); + return GVariantPtr(unpackedResult, g_variant_unref); + } + +private: + const int mId; + DbusConnection::Pointer mClient; + bool mNameAcquired; + bool mPendingDisconnect; + std::mutex mMutex; + std::condition_variable mNameCondition; + + std::string acquireAddress() const + { + std::string zoneId = "zone" + std::to_string(mId); + return "unix:path=/tmp/ut-run/" + zoneId + "/dbus/system_bus_socket"; + } +}; + +typedef HostIPCAccessory HostAccessory; +typedef ZoneDbusAccessory ZoneAccessory; + +#endif //DBUS_CONNECTION + template bool spinWaitFor(int timeoutMs, Predicate pred) { @@ -559,9 +899,9 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) Latch signalReceivedLatch; std::map> signalReceivedSourcesMap; - std::map> dbuses; + std::map> dbuses; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - dbuses[i] = std::unique_ptr(new DbusAccessory(i)); + dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); } auto handler = [](Latch& latch, @@ -626,9 +966,9 @@ BOOST_AUTO_TEST_CASE(DisplayOff) cm.createZone("zone3", DBUS_TEMPLATE); cm.restoreAll(); - std::vector> clients; + std::vector> clients; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - clients.push_back(std::unique_ptr(new DbusAccessory(i))); + clients.push_back(std::unique_ptr(new ZoneAccessory(i))); } for (auto& client : clients) { @@ -668,9 +1008,9 @@ BOOST_AUTO_TEST_CASE(MoveFile) std::string notificationPath; std::string notificationRetcode; - std::map> dbuses; + std::map> dbuses; for (int i = 1; i <= 2; ++i) { - dbuses[i] = std::unique_ptr(new DbusAccessory(i)); + dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); } auto handler = [&](const std::string& /*senderBusName*/, @@ -765,9 +1105,9 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) cm.createZone("zone3", DBUS_TEMPLATE); cm.restoreAll(); - std::vector> clients; + std::vector> clients; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - clients.push_back(std::unique_ptr(new DbusAccessory(i))); + clients.push_back(std::unique_ptr(new ZoneAccessory(i))); } for (auto& client : clients) { @@ -806,6 +1146,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) } } +#ifdef DBUS_CONNECTION BOOST_AUTO_TEST_CASE(ProxyCall) { ZonesManager cm(TEST_CONFIG_PATH); @@ -815,8 +1156,9 @@ BOOST_AUTO_TEST_CASE(ProxyCall) cm.restoreAll(); std::map> dbuses; - for (int i = 0; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - dbuses[i] = std::unique_ptr(new DbusAccessory(i)); + dbuses[0] = std::unique_ptr(new HostAccessory()); + for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { + dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); } for (auto& dbus : dbuses) { @@ -879,14 +1221,15 @@ BOOST_AUTO_TEST_CASE(ProxyCall) DbusCustomException, WhatEquals("Proxy call forbidden")); } +#endif // DBUS_CONNECTION namespace { - const DbusAccessory::Dbuses EXPECTED_DBUSES_NONE = { + const HostAccessory::Dbuses EXPECTED_DBUSES_NONE = { {"zone1", ""}, {"zone2", ""}, {"zone3", ""}}; - const DbusAccessory::Dbuses EXPECTED_DBUSES_ALL = { + const HostAccessory::Dbuses EXPECTED_DBUSES_ALL = { {"zone1", "unix:path=/tmp/ut-run/zone1/dbus/system_bus_socket"}, {"zone2", @@ -897,8 +1240,8 @@ namespace { BOOST_AUTO_TEST_CASE(GetZoneDbuses) { - DbusAccessory host(DbusAccessory::HOST_ID); ZonesManager cm(TEST_CONFIG_PATH); + HostAccessory host; cm.createZone("zone1", DBUS_TEMPLATE); cm.createZone("zone2", DBUS_TEMPLATE); cm.createZone("zone3", DBUS_TEMPLATE); @@ -912,8 +1255,8 @@ BOOST_AUTO_TEST_CASE(GetZoneDbuses) BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbus) { - DbusAccessory host(DbusAccessory::HOST_ID); ZonesManager cm(TEST_CONFIG_PATH); + HostAccessory host; cm.createZone("zone1", SIMPLE_TEMPLATE); cm.createZone("zone2", SIMPLE_TEMPLATE); cm.createZone("zone3", SIMPLE_TEMPLATE); @@ -928,32 +1271,19 @@ BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbus) BOOST_AUTO_TEST_CASE(ZoneDbusesSignals) { Latch signalLatch; - DbusAccessory::Dbuses collectedDbuses; + HostAccessory::Dbuses collectedDbuses; + std::mutex collectedDbusesMutex; - DbusAccessory host(DbusAccessory::HOST_ID); - - auto onSignal = [&] (const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters) { - if (objectPath == api::host::OBJECT_PATH && - interface == api::host::INTERFACE && - signalName == api::host::SIGNAL_ZONE_DBUS_STATE) { - - const gchar* zoneId = NULL; - const gchar* dbusAddress = NULL; - g_variant_get(parameters, "(&s&s)", &zoneId, &dbusAddress); - - collectedDbuses.insert(DbusAccessory::Dbuses::value_type(zoneId, dbusAddress)); - signalLatch.set(); - } + auto onSignal = [&] (const std::string& zoneId, const std::string& dbusAddress) { + std::unique_lock lock(collectedDbusesMutex); + collectedDbuses.insert(HostAccessory::Dbuses::value_type(zoneId, dbusAddress)); + signalLatch.set(); }; - host.signalSubscribe(onSignal); - { ZonesManager cm(TEST_CONFIG_PATH); + HostAccessory host; + host.subscribeZoneDbusState(onSignal); cm.createZone("zone1", DBUS_TEMPLATE); cm.createZone("zone2", DBUS_TEMPLATE); cm.createZone("zone3", DBUS_TEMPLATE); @@ -965,13 +1295,10 @@ BOOST_AUTO_TEST_CASE(ZoneDbusesSignals) BOOST_REQUIRE(signalLatch.waitForN(TEST_DBUS_CONNECTION_ZONES_COUNT, EVENT_TIMEOUT)); BOOST_CHECK(signalLatch.empty()); + std::unique_lock lock(collectedDbusesMutex); BOOST_CHECK(EXPECTED_DBUSES_ALL == collectedDbuses); collectedDbuses.clear(); } - - BOOST_CHECK(signalLatch.waitForN(TEST_DBUS_CONNECTION_ZONES_COUNT, EVENT_TIMEOUT)); - BOOST_CHECK(signalLatch.empty()); - BOOST_CHECK(EXPECTED_DBUSES_NONE == collectedDbuses); } @@ -982,12 +1309,12 @@ BOOST_AUTO_TEST_CASE(GetZoneIds) cm.createZone("zone2", SIMPLE_TEMPLATE); cm.createZone("zone3", SIMPLE_TEMPLATE); - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; std::vector zoneIds = {"zone1", "zone2", "zone3"}; - std::vector returnedIds = dbus.callMethodGetZoneIds(); + std::vector returnedIds = host.callMethodGetZoneIds(); BOOST_CHECK(returnedIds == zoneIds);// order should be preserved } @@ -1000,7 +1327,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; std::vector zoneIds = {"zone1", "zone2", @@ -1008,11 +1335,11 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) for (const std::string& zoneId: zoneIds){ cm.focus(zoneId); - BOOST_CHECK(dbus.callMethodGetActiveZoneId() == zoneId); + BOOST_CHECK(host.callMethodGetActiveZoneId() == zoneId); } cm.shutdownAll(); - BOOST_CHECK(dbus.callMethodGetActiveZoneId() == ""); + BOOST_CHECK(host.callMethodGetActiveZoneId() == ""); } BOOST_AUTO_TEST_CASE(SetActiveZone) @@ -1023,24 +1350,24 @@ BOOST_AUTO_TEST_CASE(SetActiveZone) cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; std::vector zoneIds = {"zone1", "zone2", "zone3"}; for (const std::string& zoneId: zoneIds){ - dbus.callMethodSetActiveZone(zoneId); - BOOST_CHECK(dbus.callMethodGetActiveZoneId() == zoneId); + host.callMethodSetActiveZone(zoneId); + BOOST_CHECK(host.callMethodGetActiveZoneId() == zoneId); } - BOOST_REQUIRE_EXCEPTION(dbus.callMethodSetActiveZone(NON_EXISTANT_ZONE_ID), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodSetActiveZone(NON_EXISTANT_ZONE_ID), + std::exception, //TODO: exception should be more specific WhatEquals("No such zone id")); cm.shutdownAll(); - BOOST_REQUIRE_EXCEPTION(dbus.callMethodSetActiveZone("zone1"), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodSetActiveZone("zone1"), + std::exception, //TODO: exception should be more specific WhatEquals("Could not activate stopped or paused zone")); } @@ -1060,18 +1387,18 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZone) callDone.set(); }; - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; // create zone1 - dbus.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); // create zone2 - dbus.callAsyncMethodCreateZone(zone2, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone2, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); // create zone3 - dbus.callAsyncMethodCreateZone(zone3, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone3, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); cm.restoreAll(); @@ -1081,17 +1408,17 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZone) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone3); // destroy zone2 - dbus.callAsyncMethodDestroyZone(zone2, resultCallback); + host.callAsyncMethodDestroyZone(zone2, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone3); // destroy zone3 - dbus.callAsyncMethodDestroyZone(zone3, resultCallback); + host.callAsyncMethodDestroyZone(zone3, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1); // destroy zone1 - dbus.callAsyncMethodDestroyZone(zone1, resultCallback); + host.callAsyncMethodDestroyZone(zone1, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } @@ -1109,8 +1436,8 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) ZonesManager cm(TEST_CONFIG_PATH); cm.restoreAll(); - DbusAccessory dbus(DbusAccessory::HOST_ID); - return dbus.callMethodGetZoneIds(); + HostAccessory host; + return host.callMethodGetZoneIds(); }; BOOST_CHECK(getZoneIds().empty()); @@ -1118,8 +1445,8 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) // create zone { ZonesManager cm(TEST_CONFIG_PATH); - DbusAccessory dbus(DbusAccessory::HOST_ID); - dbus.callAsyncMethodCreateZone(zone, SIMPLE_TEMPLATE, resultCallback); + HostAccessory host; + host.callAsyncMethodCreateZone(zone, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } @@ -1132,8 +1459,8 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) // destroy zone { ZonesManager cm(TEST_CONFIG_PATH); - DbusAccessory dbus(DbusAccessory::HOST_ID); - dbus.callAsyncMethodDestroyZone(zone, resultCallback); + HostAccessory host; + host.callAsyncMethodDestroyZone(zone, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } @@ -1156,44 +1483,44 @@ BOOST_AUTO_TEST_CASE(ZoneStatePersistence) // firts run { ZonesManager cm(TEST_CONFIG_PATH); - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; // zone1 - created - dbus.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); // zone2 - started - dbus.callAsyncMethodCreateZone(zone2, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone2, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodStartZone(zone2, resultCallback); + host.callAsyncMethodStartZone(zone2, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(cm.isRunning(zone2)); // zone3 - started then paused - dbus.callAsyncMethodCreateZone(zone3, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone3, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodStartZone(zone3, resultCallback); + host.callAsyncMethodStartZone(zone3, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callMethodLockZone(zone3); + host.callMethodLockZone(zone3); BOOST_CHECK(cm.isPaused(zone3)); // zone4 - started then stopped - dbus.callAsyncMethodCreateZone(zone4, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone4, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodStartZone(zone4, resultCallback); + host.callAsyncMethodStartZone(zone4, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodShutdownZone(zone4, resultCallback); + host.callAsyncMethodShutdownZone(zone4, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(cm.isStopped(zone4)); // zone5 - started then stopped then started - dbus.callAsyncMethodCreateZone(zone5, SIMPLE_TEMPLATE, resultCallback); + host.callAsyncMethodCreateZone(zone5, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodStartZone(zone5, resultCallback); + host.callAsyncMethodStartZone(zone5, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodShutdownZone(zone5, resultCallback); + host.callAsyncMethodShutdownZone(zone5, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); - dbus.callAsyncMethodStartZone(zone5, resultCallback); + host.callAsyncMethodStartZone(zone5, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(cm.isRunning(zone5)); } @@ -1225,27 +1552,27 @@ BOOST_AUTO_TEST_CASE(StartShutdownZone) callDone.set(); }; - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; // start zone1 - dbus.callAsyncMethodStartZone(zone1, resultCallback); + host.callAsyncMethodStartZone(zone1, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(cm.isRunning(zone1)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone1); // start zone2 - dbus.callAsyncMethodStartZone(zone2, resultCallback); + host.callAsyncMethodStartZone(zone2, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(cm.isRunning(zone2)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), zone2); // shutdown zone2 - dbus.callAsyncMethodShutdownZone(zone2, resultCallback); + host.callAsyncMethodShutdownZone(zone2, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(!cm.isRunning(zone2)); // shutdown zone1 - dbus.callAsyncMethodShutdownZone(zone1, resultCallback); + host.callAsyncMethodShutdownZone(zone1, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); BOOST_CHECK(!cm.isRunning(zone1)); BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); @@ -1259,32 +1586,41 @@ BOOST_AUTO_TEST_CASE(LockUnlockZone) cm.createZone("zone3", DBUS_TEMPLATE); cm.restoreAll(); - DbusAccessory dbus(DbusAccessory::HOST_ID); + HostAccessory host; std::vector zoneIds = {"zone1", "zone2", "zone3"}; for (const std::string& zoneId: zoneIds){ - dbus.callMethodLockZone(zoneId); + try { + host.callMethodLockZone(zoneId); + } catch(const std::exception&) { + //This try catch clause is for prevent from test crashing + //and should be removed after resolve following errors + //TODO: Abort when zone is locked on destroying ZonesManager + HostAccessory host2; //TODO: After IPCTimeoutException host is useless -- fix it + try { host2.callMethodUnlockZone(zoneId); } catch (...) {}; + throw; + } BOOST_CHECK(cm.isPaused(zoneId)); - dbus.callMethodUnlockZone(zoneId); + host.callMethodUnlockZone(zoneId); BOOST_CHECK(cm.isRunning(zoneId)); } - BOOST_REQUIRE_EXCEPTION(dbus.callMethodLockZone(NON_EXISTANT_ZONE_ID), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodLockZone(NON_EXISTANT_ZONE_ID), + std::exception, //TODO: exception should be more specific WhatEquals("No such zone id")); - BOOST_REQUIRE_EXCEPTION(dbus.callMethodUnlockZone(NON_EXISTANT_ZONE_ID), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodUnlockZone(NON_EXISTANT_ZONE_ID), + std::exception, //TODO: exception should be more specific WhatEquals("No such zone id")); cm.shutdownAll(); - BOOST_REQUIRE_EXCEPTION(dbus.callMethodLockZone("zone1"), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodLockZone("zone1"), + std::exception, //TODO: exception should be more specific WhatEquals("Zone is not running")); - BOOST_REQUIRE_EXCEPTION(dbus.callMethodUnlockZone("zone1"), - DbusException, + BOOST_REQUIRE_EXCEPTION(host.callMethodUnlockZone("zone1"), + std::exception, //TODO: exception should be more specific WhatEquals("Zone is not paused")); } -- 2.7.4 From 5a608e18a90ffb35171d5be56adbb540f7c918a5 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Tue, 14 Apr 2015 17:36:19 +0200 Subject: [PATCH 05/16] Add libSimpleDbus, libLogger, libConfig source code to Vasum. [Feature] Add libSimpleDbus, libLogger, libConfig source code to Vasum. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests, run server. Change-Id: I2466604ee744874237fb989695d4104d399cdca1 Signed-off-by: Dariusz Michaluk --- CMakeLists.txt | 1 + client/CMakeLists.txt | 27 +- client/dbus-connection.cpp | 2 +- client/dbus-connection.hpp | 6 +- common/api/method-result-builder.hpp | 2 +- common/config/exception.hpp | 44 +++ common/config/fdstore.cpp | 148 ++++++++ common/config/fdstore.hpp | 72 ++++ common/config/fields-union.hpp | 194 ++++++++++ common/config/fields.hpp | 85 +++++ common/config/from-fdstore-visitor.hpp | 91 +++++ common/config/from-gvariant-visitor.hpp | 167 +++++++++ common/config/from-json-visitor.hpp | 162 ++++++++ common/config/from-kvjson-visitor.hpp | 279 ++++++++++++++ common/config/from-kvstore-visitor.hpp | 92 +++++ common/config/fs-utils.cpp | 73 ++++ common/config/fs-utils.hpp | 43 +++ common/config/is-union.hpp | 70 ++++ common/config/is-visitable.hpp | 53 +++ common/config/kvstore.cpp | 342 +++++++++++++++++ common/config/kvstore.hpp | 261 +++++++++++++ common/config/manager.hpp | 257 +++++++++++++ common/config/sqlite3/connection.cpp | 77 ++++ common/config/sqlite3/connection.hpp | 66 ++++ common/config/sqlite3/statement.cpp | 77 ++++ common/config/sqlite3/statement.hpp | 66 ++++ common/config/to-fdstore-visitor.hpp | 88 +++++ common/config/to-gvariant-visitor.hpp | 126 +++++++ common/config/to-json-visitor.hpp | 140 +++++++ common/config/to-kvstore-visitor.hpp | 86 +++++ common/dbus/connection.cpp | 409 +++++++++++++++++++++ common/dbus/connection.hpp | 211 +++++++++++ common/dbus/exception.hpp | 74 ++++ common/ipc/client.hpp | 2 +- common/ipc/internals/processor.hpp | 2 +- common/ipc/service.hpp | 2 +- common/logger/backend-journal.cpp | 71 ++++ common/logger/backend-journal.hpp | 46 +++ common/logger/backend-null.hpp | 46 +++ common/logger/backend-stderr.cpp | 61 +++ common/logger/backend-stderr.hpp | 46 +++ common/logger/backend.hpp | 49 +++ common/logger/ccolor.cpp | 41 +++ common/logger/ccolor.hpp | 53 +++ common/logger/formatter.cpp | 131 +++++++ common/logger/formatter.hpp | 50 +++ common/logger/level.cpp | 71 ++++ common/logger/level.hpp | 55 +++ common/logger/logger-scope.cpp | 56 +++ common/logger/logger-scope.hpp | 78 ++++ common/logger/logger.cpp | 76 ++++ common/logger/logger.hpp | 79 ++++ common/netlink/netlink-message.hpp | 1 + common/utils/glib-utils.cpp | 59 +++ common/utils/glib-utils.hpp | 44 +++ packaging/vasum.spec | 3 - server/CMakeLists.txt | 2 +- server/netdev.hpp | 1 + tests/unit_tests/CMakeLists.txt | 2 +- .../unit_tests/socket_test_service/socket-test.cpp | 2 +- zone-daemon/CMakeLists.txt | 10 +- 61 files changed, 4994 insertions(+), 36 deletions(-) create mode 100644 common/config/exception.hpp create mode 100644 common/config/fdstore.cpp create mode 100644 common/config/fdstore.hpp create mode 100644 common/config/fields-union.hpp create mode 100644 common/config/fields.hpp create mode 100644 common/config/from-fdstore-visitor.hpp create mode 100644 common/config/from-gvariant-visitor.hpp create mode 100644 common/config/from-json-visitor.hpp create mode 100644 common/config/from-kvjson-visitor.hpp create mode 100644 common/config/from-kvstore-visitor.hpp create mode 100644 common/config/fs-utils.cpp create mode 100644 common/config/fs-utils.hpp create mode 100644 common/config/is-union.hpp create mode 100644 common/config/is-visitable.hpp create mode 100644 common/config/kvstore.cpp create mode 100644 common/config/kvstore.hpp create mode 100644 common/config/manager.hpp create mode 100644 common/config/sqlite3/connection.cpp create mode 100644 common/config/sqlite3/connection.hpp create mode 100644 common/config/sqlite3/statement.cpp create mode 100644 common/config/sqlite3/statement.hpp create mode 100644 common/config/to-fdstore-visitor.hpp create mode 100644 common/config/to-gvariant-visitor.hpp create mode 100644 common/config/to-json-visitor.hpp create mode 100644 common/config/to-kvstore-visitor.hpp create mode 100644 common/dbus/connection.cpp create mode 100644 common/dbus/connection.hpp create mode 100644 common/dbus/exception.hpp create mode 100644 common/logger/backend-journal.cpp create mode 100644 common/logger/backend-journal.hpp create mode 100644 common/logger/backend-null.hpp create mode 100644 common/logger/backend-stderr.cpp create mode 100644 common/logger/backend-stderr.hpp create mode 100644 common/logger/backend.hpp create mode 100644 common/logger/ccolor.cpp create mode 100644 common/logger/ccolor.hpp create mode 100644 common/logger/formatter.cpp create mode 100644 common/logger/formatter.hpp create mode 100644 common/logger/level.cpp create mode 100644 common/logger/level.hpp create mode 100644 common/logger/logger-scope.cpp create mode 100644 common/logger/logger-scope.hpp create mode 100644 common/logger/logger.cpp create mode 100644 common/logger/logger.hpp create mode 100644 common/utils/glib-utils.cpp create mode 100644 common/utils/glib-utils.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e7f7aff..6a87b41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,7 @@ ADD_DEFINITIONS("-pedantic-errors") # Make pedantic warnings into errors ADD_DEFINITIONS(-DPROGRAM_VERSION="${VERSION}") ADD_DEFINITIONS(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") ADD_DEFINITIONS(-DUSE_EXEC) +ADD_DEFINITIONS(-D__STDC_LIMIT_MACROS) IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # Warn about documentation problems diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0ebbf75..296e638 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -20,22 +20,15 @@ MESSAGE(STATUS "") MESSAGE(STATUS "Generating makefile for the Client...") FILE(GLOB project_SRCS *.cpp *.hpp *.h) -FILE(GLOB common_SRCS ${COMMON_FOLDER}/utils/callback-guard.hpp - ${COMMON_FOLDER}/utils/callback-guard.cpp - ${COMMON_FOLDER}/utils/glib-loop.cpp - ${COMMON_FOLDER}/utils/glib-loop.hpp - ${COMMON_FOLDER}/base-exception.hpp - ${COMMON_FOLDER}/base-exception.cpp - ${COMMON_FOLDER}/utils/eventfd.hpp - ${COMMON_FOLDER}/utils/eventfd.cpp - ${COMMON_FOLDER}/utils/fd-utils.hpp - ${COMMON_FOLDER}/utils/fd-utils.cpp - ${COMMON_FOLDER}/epoll/*.hpp - ${COMMON_FOLDER}/epoll/*.cpp - ${COMMON_FOLDER}/ipc/*.hpp - ${COMMON_FOLDER}/ipc/*.cpp - ${COMMON_FOLDER}/ipc/internals/*.hpp - ${COMMON_FOLDER}/ipc/internals/*.cpp) +FILE(GLOB common_SRCS ${COMMON_FOLDER}/config/*.hpp ${COMMON_FOLDER}/config/*.cpp + ${COMMON_FOLDER}/config/sqlite3/*.hpp ${COMMON_FOLDER}/config/sqlite3/*.cpp + ${COMMON_FOLDER}/dbus/*.hpp ${COMMON_FOLDER}/dbus/*.cpp + ${COMMON_FOLDER}/epoll/*.hpp ${COMMON_FOLDER}/epoll/*.cpp + ${COMMON_FOLDER}/ipc/*.hpp ${COMMON_FOLDER}/ipc/*.cpp + ${COMMON_FOLDER}/ipc/internals/*.hpp ${COMMON_FOLDER}/ipc/internals/*.cpp + ${COMMON_FOLDER}/logger/*.hpp ${COMMON_FOLDER}/logger/*.cpp + ${COMMON_FOLDER}/utils/*.hpp ${COMMON_FOLDER}/utils/*.cpp + ${COMMON_FOLDER}/*.hpp ${COMMON_FOLDER}/*.cpp) SET(_LIB_VERSION_ "0.0.1") SET(_LIB_SOVERSION_ "0") @@ -55,7 +48,7 @@ SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS system filesystem) -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libSimpleDbus libLogger libConfig libsystemd-daemon) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libsystemd-daemon libsystemd-journal libcap-ng sqlite3) INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${SERVER_FOLDER}) diff --git a/client/dbus-connection.cpp b/client/dbus-connection.cpp index 7e364d7..b52bd71 100644 --- a/client/dbus-connection.cpp +++ b/client/dbus-connection.cpp @@ -20,7 +20,7 @@ /** * @file * @author Mateusz Malicki (m.malicki2@samsung.com) - * @brief libSimpleDbus's wrapper + * @brief SimpleDbus's wrapper */ #include diff --git a/client/dbus-connection.hpp b/client/dbus-connection.hpp index a760bb6..3cb37ad 100644 --- a/client/dbus-connection.hpp +++ b/client/dbus-connection.hpp @@ -20,7 +20,7 @@ /** * @file * @author Mateusz Malicki (m.malicki2@samsung.com) - * @brief libSimpleDbus's wrapper + * @brief SimpleDbus's wrapper */ #ifndef VASUM_CLIENT_DBUS_CONNECTION_HPP @@ -37,9 +37,9 @@ namespace vasum { namespace client { /** - * libSimpleDbus client definition. + * SimpleDbus client definition. * - * DbusConnection uses libSimpleDbus API. + * DbusConnection uses SimpleDbus API. */ class DbusConnection { public: diff --git a/common/api/method-result-builder.hpp b/common/api/method-result-builder.hpp index 04ede40..89aa7a9 100644 --- a/common/api/method-result-builder.hpp +++ b/common/api/method-result-builder.hpp @@ -47,7 +47,7 @@ public: template void set(const std::shared_ptr& data) { - static_assert(config::isVisitable::value, "Use only libConfig's structures"); + static_assert(config::isVisitable::value, "Use only Config's structures"); setImpl(data); } diff --git a/common/config/exception.hpp b/common/config/exception.hpp new file mode 100644 index 0000000..977ec32 --- /dev/null +++ b/common/config/exception.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk + * + * 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 Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Exceptions for the configuration + */ + +#ifndef COMMON_CONFIG_EXCEPTION_HPP +#define COMMON_CONFIG_EXCEPTION_HPP + +#include + +namespace config { + +/** + * Base class for exceptions in configuration. + * Error occured during a config file parsing, + * e.g. syntax error + */ +struct ConfigException: public std::runtime_error { + + ConfigException(const std::string& error) : std::runtime_error(error) {} +}; + +} // namespace config + +#endif // COMMON_CONFIG_EXCEPTION_HPP diff --git a/common/config/fdstore.cpp b/common/config/fdstore.cpp new file mode 100644 index 0000000..c1cedfe --- /dev/null +++ b/common/config/fdstore.cpp @@ -0,0 +1,148 @@ +/* + * 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 Definition of a class for writing and reading data from a file descriptor + */ + +#include "config.hpp" + +#include "config/fdstore.hpp" +#include "config/exception.hpp" + +#include +#include +#include +#include +#include + +namespace config { + +namespace { + +void waitForEvent(int fd, + short event, + const std::chrono::high_resolution_clock::time_point deadline) +{ + // Wait for the rest of the data + struct pollfd fds[1]; + fds[0].fd = fd; + fds[0].events = event | POLLHUP; + + for (;;) { + std::chrono::milliseconds timeoutMS = + std::chrono::duration_cast(deadline - std::chrono::high_resolution_clock::now()); + if (timeoutMS.count() < 0) { + throw ConfigException("Timeout"); + } + + int ret = ::poll(fds, 1 /*fds size*/, timeoutMS.count()); + + if (ret == -1) { + if (errno == EINTR) { + continue; + } + throw ConfigException("Error in poll: " + std::string(strerror(errno))); + } + + if (ret == 0) { + throw ConfigException("Timeout"); + } + + if (fds[0].revents & POLLHUP) { + throw ConfigException("Peer disconnected"); + } + + // Here Comes the Sun + break; + } +} + +} // namespace + +FDStore::FDStore(int fd) + : mFD(fd) +{ +} + +FDStore::FDStore(const FDStore& store) + : mFD(store.mFD) +{ +} + +FDStore::~FDStore() +{ +} + +void FDStore::write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS) +{ + std::chrono::high_resolution_clock::time_point deadline = std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); + + size_t nTotal = 0; + for (;;) { + int n = ::write(mFD, + reinterpret_cast(bufferPtr) + nTotal, + size - nTotal); + if (n >= 0) { + nTotal += n; + if (nTotal == size) { + // All data is written, break loop + break; + } + } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors + } else { + throw ConfigException("Error during writing: " + std::string(strerror(errno))); + } + + waitForEvent(mFD, POLLOUT, deadline); + } +} + +void FDStore::read(void* bufferPtr, const size_t size, const unsigned int timeoutMS) +{ + std::chrono::high_resolution_clock::time_point deadline = std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); + + size_t nTotal = 0; + for (;;) { + int n = ::read(mFD, + reinterpret_cast(bufferPtr) + nTotal, + size - nTotal); + if (n >= 0) { + nTotal += n; + if (nTotal == size) { + // All data is read, break loop + break; + } + if (n == 0) { + throw ConfigException("Peer disconnected"); + } + } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors + } else { + throw ConfigException("Error during reading: " + std::string(strerror(errno))); + } + + waitForEvent(mFD, POLLIN, deadline); + } +} +} // namespace config diff --git a/common/config/fdstore.hpp b/common/config/fdstore.hpp new file mode 100644 index 0000000..d34ea14 --- /dev/null +++ b/common/config/fdstore.hpp @@ -0,0 +1,72 @@ +/* + * 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 Declaration of a class for writing and reading data from a file descriptor + */ + +#ifndef COMMON_CONFIG_FDSTORE_HPP +#define COMMON_CONFIG_FDSTORE_HPP + +#include + +namespace config { + +class FDStore { + +public: + /** + * Constructor. One can pass any kind of file descriptor. + * Serialization is NOT written for network purposes, + * rather local communication. + * + * @param fd file descriptor + */ + FDStore(int fd = -1); + FDStore(const FDStore& store); + ~FDStore(); + + /** + * Write data using the file descriptor + * + * @param bufferPtr buffer with the data + * @param size size of the buffer + * @param timeoutMS timeout in milliseconds + */ + void write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS = 500); + + /** + * Reads a value of the given type. + * + * @param bufferPtr buffer with the data + * @param size size of the buffer + * @param timeoutMS timeout in milliseconds + */ + void read(void* bufferPtr, const size_t size, const unsigned int timeoutMS = 500); + +private: + int mFD; +}; + +} // namespace config + +#endif // COMMON_CONFIG_FDSTORE_HPP + + diff --git a/common/config/fields-union.hpp b/common/config/fields-union.hpp new file mode 100644 index 0000000..67720e7 --- /dev/null +++ b/common/config/fields-union.hpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki (m.malicki2@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 Mateusz Malicki (m.malicki2@samsung.com) + * @brief Macros for declare configuration fields + */ + +#ifndef COMMON_CONFIG_FIELDS_UNION_HPP +#define COMMON_CONFIG_FIELDS_UNION_HPP + +#include "config/fields.hpp" +#include "config/exception.hpp" + +#include +#include + +/** + * Use this macro to declare and register config fields + * + * Example: + * struct Foo { + * std::string bar; + * + * CONFIG_REGISTER + * ( + * bar, + * ) + * }; + * + * struct Config + * { + * CONFIG_DECLARE_UNION + * ( + * Foo, + * int + * ) + * }; + * + * Example of valid configuration: + * 1. { + * "type": "Foo", + * "value": { "bar": "some string" } + * } + * 2. { + * "type": "int", + * "value": 1 + * } + * + * + * Usage: + * Config config; + * // ... + * if (config.isSet()) { + * if (config.is()) { + * Foo& foo = config.as(); + * // ... + * } + * if (config.is())) { + * int field = config.as(); + * // ... + * } + * } else { + * // Config is not set + * Foo foo({"some string"}); + * config.set(foo); + * config.set(std::move(foo)); //< copy sic! + * config.set(Foo({"some string"})); + * } + */ + +class DisbaleMoveAnyWrapper : public boost::any +{ + public: + DisbaleMoveAnyWrapper() {} + DisbaleMoveAnyWrapper(const DisbaleMoveAnyWrapper& any) + : boost::any(static_cast(any)) {}; + DisbaleMoveAnyWrapper& operator=(DisbaleMoveAnyWrapper&& any) = delete; + DisbaleMoveAnyWrapper& operator=(const DisbaleMoveAnyWrapper& any) { + static_cast(*this) = static_cast(any); + return *this; + } +}; + +#define CONFIG_DECLARE_UNION(...) \ +private: \ + DisbaleMoveAnyWrapper mConfigDeclareField; \ + \ + template \ + void visitOption(Visitor& v, const std::string& name) { \ + GENERATE_CODE(GENERATE_UNION_VISIT__, __VA_ARGS__) \ + throw config::ConfigException("Union type error. Unsupported type"); \ + } \ + template \ + void visitOption(Visitor& v, const std::string& name) const { \ + GENERATE_CODE(GENERATE_UNION_VISIT_CONST__, __VA_ARGS__) \ + throw config::ConfigException("Union type error. Unsupported type"); \ + } \ + std::string getOptionName() const { \ + GENERATE_CODE(GENERATE_UNION_NAME__, __VA_ARGS__) \ + return std::string(); \ + } \ + boost::any& getHolder() { \ + return static_cast(mConfigDeclareField); \ + } \ + const boost::any& getHolder() const { \ + return static_cast(mConfigDeclareField); \ + } \ +public: \ + \ + template \ + void accept(Visitor v) { \ + std::string name; \ + v.visit("type", name); \ + visitOption(v, name); \ + } \ + \ + template \ + void accept(Visitor v) const { \ + const std::string name = getOptionName(); \ + if (name.empty()) { \ + throw config::ConfigException("Type is not set"); \ + } \ + v.visit("type", name); \ + visitOption(v, name); \ + } \ + \ + template \ + bool is() const { \ + return boost::any_cast(&getHolder()) != NULL; \ + } \ + template \ + typename std::enable_if::value, Type>::type& as() { \ + if (getHolder().empty()) { \ + throw config::ConfigException("Type is not set"); \ + } \ + return boost::any_cast(getHolder()); \ + } \ + template \ + const Type& as() const { \ + if (getHolder().empty()) { \ + throw config::ConfigException("Type is not set"); \ + } \ + return boost::any_cast(getHolder()); \ + } \ + bool isSet() { \ + return !getOptionName().empty(); \ + } \ + template \ + Type& set(const Type& src) { \ + getHolder() = std::forward(src); \ + if (getOptionName().empty()) { \ + throw config::ConfigException("Unsupported type"); \ + } \ + return as(); \ + } \ + +#define GENERATE_CODE(MACRO, ...) \ + BOOST_PP_LIST_FOR_EACH(MACRO, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)) + +#define GENERATE_UNION_VISIT__(r, _, TYPE_) \ + if (#TYPE_ == name) { \ + v.visit("value", set(std::move(TYPE_()))); \ + return; \ + } + +#define GENERATE_UNION_VISIT_CONST__(r, _, TYPE_) \ + if (#TYPE_ == name) { \ + v.visit("value", as()); \ + return; \ + } + +#define GENERATE_UNION_NAME__(r, _, TYPE_) \ + if (is()) { \ + return #TYPE_; \ + } + +#endif // COMMON_CONFIG_FIELDS_UNION_HPP diff --git a/common/config/fields.hpp b/common/config/fields.hpp new file mode 100644 index 0000000..cba5a67 --- /dev/null +++ b/common/config/fields.hpp @@ -0,0 +1,85 @@ +/* + * 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 Macros for registering configuration fields + */ + +#ifndef COMMON_CONFIG_FIELDS_HPP +#define COMMON_CONFIG_FIELDS_HPP + +#include +#include + +#if BOOST_PP_VARIADICS != 1 +#error variadic macros not supported +#endif + +/** + * Use this macro to register config fields. + * + * Example: + * struct Foo + * { + * std::string bar; + * std::vector tab; + * + * // SubConfigA must also register config fields + * SubConfigA sub_a; + * + * // SubConfigB must also register config fields + * std::vector tab_sub; + * + * CONFIG_REGISTER + * ( + * bar, + * tab, + * sub_a + * ) + * }; + */ + +#define CONFIG_REGISTER_EMPTY \ + template \ + void accept(Visitor ) { \ + } \ + template \ + void accept(Visitor ) const { \ + } \ + +#define CONFIG_REGISTER(...) \ + template \ + void accept(Visitor v) { \ + GENERATE_ELEMENTS__(__VA_ARGS__) \ + } \ + template \ + void accept(Visitor v) const { \ + GENERATE_ELEMENTS__(__VA_ARGS__) \ + } \ + +#define GENERATE_ELEMENTS__(...) \ + BOOST_PP_LIST_FOR_EACH(GENERATE_ELEMENT__, \ + _, \ + BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)) \ + +#define GENERATE_ELEMENT__(r, _, element) \ + v.visit(#element, element); \ + +#endif // COMMON_CONFIG_FIELDS_HPP diff --git a/common/config/from-fdstore-visitor.hpp b/common/config/from-fdstore-visitor.hpp new file mode 100644 index 0000000..9b9df42 --- /dev/null +++ b/common/config/from-fdstore-visitor.hpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak (j.olszak@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 Jan Olszak (j.olszak@samsung.com) + * @brief Visitor for loading from FDStore + */ + +#ifndef COMMON_CONFIG_FROM_FDSTORE_VISITOR_HPP +#define COMMON_CONFIG_FROM_FDSTORE_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/fdstore.hpp" + +#include + +namespace config { + +class FromFDStoreVisitor { +public: + explicit FromFDStoreVisitor(int fd) + : mStore(fd) + { + } + + FromFDStoreVisitor(const FromFDStoreVisitor&) = default; + + FromFDStoreVisitor& operator=(const FromFDStoreVisitor&) = delete; + + template + void visit(const std::string&, T& value) + { + readInternal(value); + } + +private: + FDStore mStore; + + void readInternal(std::string& value) + { + size_t size; + readInternal(size); + value.resize(size); + mStore.read(&value.front(), size); + } + + template::value, int>::type = 0> + void readInternal(T& value) + { + mStore.read(&value, sizeof(T)); + } + + template::value, int>::type = 0> + void readInternal(T& value) + { + FromFDStoreVisitor visitor(*this); + value.accept(visitor); + } + + template + void readInternal(std::vector& values) + { + size_t vectorSize; + readInternal(vectorSize); + values.resize(vectorSize); + + for (T& value : values) { + readInternal(value); + } + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_FROM_FDSTORE_VISITOR_HPP diff --git a/common/config/from-gvariant-visitor.hpp b/common/config/from-gvariant-visitor.hpp new file mode 100644 index 0000000..040dcae --- /dev/null +++ b/common/config/from-gvariant-visitor.hpp @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki (m.malicki2@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 Mateusz Malicki (m.malicki2@samsung.com) + * @brief GVariant visitor + */ + +#ifndef COMMON_CONFIG_FROM_GVARIANT_VISITOR_HPP +#define COMMON_CONFIG_FROM_GVARIANT_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/exception.hpp" +#include "config/is-union.hpp" + +#include +#include +#include +#include +#include + +namespace config { + +class FromGVariantVisitor { +public: + explicit FromGVariantVisitor(GVariant* variant) + { + //Assume that the visited object is not a union + checkType(variant, G_VARIANT_TYPE_TUPLE); + mIter = g_variant_iter_new(variant); + } + + FromGVariantVisitor(const FromGVariantVisitor& visitor) + : mIter(g_variant_iter_copy(visitor.mIter)) + { + } + + ~FromGVariantVisitor() + { + g_variant_iter_free(mIter); + } + + FromGVariantVisitor& operator=(const FromGVariantVisitor&) = delete; + + template + void visit(const std::string& name, T& value) + { + auto child = makeUnique(g_variant_iter_next_value(mIter)); + if (!child) { + throw config::ConfigException( + "GVariant doesn't match with config. Can't set '" + name + "'"); + } + fromGVariant(child.get(), value); + } + +private: + GVariantIter* mIter; + + static std::unique_ptr makeUnique(GVariant* variant) + { + return std::unique_ptr(variant, g_variant_unref); + } + + static void checkType(GVariant* object, const GVariantType* type) + { + if (!g_variant_is_of_type(object, type)) { + throw ConfigException("Invalid field type"); + } + } + + static void fromGVariant(GVariant* object, std::int32_t& value) + { + checkType(object, G_VARIANT_TYPE_INT32); + value = g_variant_get_int32(object); + } + + static void fromGVariant(GVariant* object, std::int64_t& value) + { + checkType(object, G_VARIANT_TYPE_INT64); + value = g_variant_get_int64(object); + } + + static void fromGVariant(GVariant* object, std::uint32_t& value) + { + checkType(object, G_VARIANT_TYPE_UINT32); + value = g_variant_get_uint32(object); + } + + static void fromGVariant(GVariant* object, std::uint64_t& value) + { + checkType(object, G_VARIANT_TYPE_UINT64); + value = g_variant_get_uint64(object); + } + + static void fromGVariant(GVariant* object, bool& value) + { + checkType(object, G_VARIANT_TYPE_BOOLEAN); + value = g_variant_get_boolean(object); + } + + static void fromGVariant(GVariant* object, double& value) + { + checkType(object, G_VARIANT_TYPE_DOUBLE); + value = g_variant_get_double(object); + } + + static void fromGVariant(GVariant* object, std::string& value) + { + checkType(object, G_VARIANT_TYPE_STRING); + value = g_variant_get_string(object, NULL); + } + + template + static void fromGVariant(GVariant* object, std::vector& value) + { + checkType(object, G_VARIANT_TYPE_ARRAY); + GVariantIter iter; + g_variant_iter_init(&iter, object); + int length = g_variant_iter_n_children(&iter); + value.resize(static_cast(length)); + for (int i = 0; i < length; ++i) { + auto child = makeUnique(g_variant_iter_next_value(&iter)); + assert(child); + fromGVariant(child.get(), value[static_cast(i)]); + } + } + + template + static typename std::enable_if::value>::type + fromGVariant(GVariant* object, T& value) + { + checkType(object, G_VARIANT_TYPE_VARIANT); + auto inner = makeUnique(g_variant_get_variant(object)); + + FromGVariantVisitor visitor(inner.get()); + value.accept(visitor); + } + + template + static typename std::enable_if::value && !isUnion::value>::type + fromGVariant(GVariant* object, T& value) + { + FromGVariantVisitor visitor(object); + value.accept(visitor); + } + +}; + +} // namespace config + +#endif // COMMON_CONFIG_FROM_GVARIANT_VISITOR_HPP diff --git a/common/config/from-json-visitor.hpp b/common/config/from-json-visitor.hpp new file mode 100644 index 0000000..2934adf --- /dev/null +++ b/common/config/from-json-visitor.hpp @@ -0,0 +1,162 @@ +/* + * 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 JSON visitor + */ + +#ifndef COMMON_CONFIG_FROM_JSON_VISITOR_HPP +#define COMMON_CONFIG_FROM_JSON_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/exception.hpp" + +#include +#include +#include + +namespace config { + +class FromJsonVisitor { +public: + explicit FromJsonVisitor(const std::string& jsonString) + : mObject(nullptr) + { + mObject = json_tokener_parse(jsonString.c_str()); + if (mObject == nullptr) { + throw ConfigException("Json parsing error"); + } + } + + FromJsonVisitor(const FromJsonVisitor& visitor) + : mObject(json_object_get(visitor.mObject)) + { + } + + ~FromJsonVisitor() + { + json_object_put(mObject); + } + + FromJsonVisitor& operator=(const FromJsonVisitor&) = delete; + + template + void visit(const std::string& name, T& value) + { + json_object* object = nullptr; + if (!json_object_object_get_ex(mObject, name.c_str(), &object)) { + throw ConfigException("Missing field '" + name + "'"); + } + fromJsonObject(object, value); + } + +private: + json_object* mObject; + + + explicit FromJsonVisitor(json_object* object) + : mObject(json_object_get(object)) + { + } + + static void checkType(json_object* object, json_type type) + { + if (type != json_object_get_type(object)) { + throw ConfigException("Invalid field type"); + } + } + + static void fromJsonObject(json_object* object, std::int32_t& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 > INT32_MAX || value64 < INT32_MIN) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, std::uint32_t& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 > UINT32_MAX || value64 < 0) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, std::int64_t& value) + { + checkType(object, json_type_int); + value = json_object_get_int64(object); + } + + static void fromJsonObject(json_object* object, std::uint64_t& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 < 0) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, bool& value) + { + checkType(object, json_type_boolean); + value = json_object_get_boolean(object); + } + + static void fromJsonObject(json_object* object, double& value) + { + checkType(object, json_type_double); + value = json_object_get_double(object); + } + + static void fromJsonObject(json_object* object, std::string& value) + { + checkType(object, json_type_string); + value = json_object_get_string(object); + } + + template + static void fromJsonObject(json_object* object, std::vector& value) + { + checkType(object, json_type_array); + int length = json_object_array_length(object); + value.resize(static_cast(length)); + for (int i = 0; i < length; ++i) { + fromJsonObject(json_object_array_get_idx(object, i), value[static_cast(i)]); + } + } + + template::value>::type> + static void fromJsonObject(json_object* object, T& value) + { + checkType(object, json_type_object); + FromJsonVisitor visitor(object); + value.accept(visitor); + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_FROM_JSON_VISITOR_HPP diff --git a/common/config/from-kvjson-visitor.hpp b/common/config/from-kvjson-visitor.hpp new file mode 100644 index 0000000..35e1bf7 --- /dev/null +++ b/common/config/from-kvjson-visitor.hpp @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Dynowski (k.dynowski@samsumg.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 Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief KVStore visitor with defaults values from json + */ + +#ifndef COMMON_CONFIG_FROM_KVJSON_VISITOR_HPP +#define COMMON_CONFIG_FROM_KVJSON_VISITOR_HPP + +#include "config/from-kvstore-visitor.hpp" +#include "config/is-union.hpp" +#include + +namespace config { + +class FromKVJsonVisitor { +public: + FromKVJsonVisitor(KVStore& store, const std::string& json, const std::string& prefix) + : mStore(store) + , mKeyPrefix(prefix) + , mIsUnion(false) + { + mObject = json_tokener_parse(json.c_str()); + if (mObject == nullptr) { + throw ConfigException("Json parsing error"); + } + } + + + ~FromKVJsonVisitor() { + json_object_put(mObject); + } + + FromKVJsonVisitor(const FromKVJsonVisitor& v) : + mStore(v.mStore), + mKeyPrefix(v.mKeyPrefix), + mObject(v.mObject ? json_object_get(v.mObject) : nullptr), + mIsUnion(v.mIsUnion) + { + } + FromKVJsonVisitor& operator=(const FromKVJsonVisitor&) = delete; + + template + void visit(const std::string& name, T& value) { + getValue(name, value); + } + +private: + KVStore& mStore; + std::string mKeyPrefix; + json_object* mObject; + bool mIsUnion; + + // create visitor for field object (visitable object) + FromKVJsonVisitor(const FromKVJsonVisitor& v, const std::string& name, const bool isUnion) : + mStore(v.mStore), + mKeyPrefix(key(v.mKeyPrefix, name)), + mIsUnion(isUnion || v.mIsUnion) + { + json_object* object = nullptr; + if (v.mObject && !json_object_object_get_ex(v.mObject, name.c_str(), &object)) { + if (!mIsUnion) + throw ConfigException("Missing json field " + mKeyPrefix); + } + mObject = object ? json_object_get(object) : nullptr; + } + + // create visitor for vector i-th element (visitable object) + FromKVJsonVisitor(const FromKVJsonVisitor& v, int i, const bool isUnion) : + mStore(v.mStore), + mKeyPrefix(key(v.mKeyPrefix, std::to_string(i))), + mIsUnion(isUnion || v.mIsUnion) + { + json_object* object = nullptr; + if (v.mObject) { + object = json_object_array_get_idx(v.mObject, i); + checkType(object, json_type_object); + } + mObject = object ? json_object_get(object) : nullptr; + } + + template::value, int>::type = 0> + void getValue(const std::string& name, T& t) + { + std::string k = key(mKeyPrefix, name); + if (mStore.exists(k)) { + t = mStore.get(k); + } + else { + json_object* object = nullptr; + if (mObject) { + json_object_object_get_ex(mObject, name.c_str(), &object); + } + if (!object) { + throw ConfigException("Missing json field " + key(mKeyPrefix, name)); + } + fromJsonObject(object, t); + } + } + + template::value, int>::type = 0> + void getValue(const std::string& name, T& t) + { + FromKVJsonVisitor visitor(*this, name, true); + t.accept(visitor); + } + + template::value && !isUnion::value, int>::type = 0> + void getValue(const std::string& name, T& t) + { + FromKVJsonVisitor visitor(*this, name, false); + t.accept(visitor); + } + + int getArraySize(std::string& name, json_object* object) + { + if (mStore.exists(name)) { + return mStore.get(name); + } + if (object) { + return json_object_array_length(object); + } + return -1; + } + + template + void getValue(const std::string& name, std::vector& value) + { + json_object* object = nullptr; + if (mObject && json_object_object_get_ex(mObject, name.c_str(), &object)) { + checkType(object, json_type_array); + } + + std::string k = key(mKeyPrefix, name); + int length = getArraySize(k, object); + if (length < 0) { + throw ConfigException("Missing array length " + k); + } + value.resize(static_cast(length)); + FromKVJsonVisitor visitor(*this, name, false); + if (mStore.exists(k)) { + json_object_put(visitor.mObject); + visitor.mObject = nullptr; + } + for (int i = 0; i < length; ++i) { + visitor.getValue(i, value[i]); + } + } + + template::value, int>::type = 0> + void getValue(int i, T& t) + { + std::string k = key(mKeyPrefix, std::to_string(i)); + if (mStore.exists(k)) { + t = mStore.get(k); + } + else { + json_object* object = mObject ? json_object_array_get_idx(mObject, i) : nullptr; + if (!object) { + throw ConfigException("Missing json array elem " + k); + } + fromJsonObject(object, t); + } + } + + template::value, int>::type = 0> + void getValue(int i, T& t) + { + FromKVJsonVisitor visitor(*this, i, true); + t.accept(visitor); + } + + template::value && !isUnion::value, int>::type = 0> + void getValue(int i, T& t) + { + FromKVJsonVisitor visitor(*this, i, false); + t.accept(visitor); + } + + template + void getValue(int i, std::vector& value) + { + std::string k = key(mKeyPrefix, std::to_string(i)); + int length = getArraySize(k, mObject); + value.resize(static_cast(length)); + FromKVJsonVisitor visitor(*this, i, false); + if (mStore.exists(k)) { + json_object_put(visitor.mObject); + visitor.mObject = nullptr; + } + for (int i = 0; i < length; ++i) { + visitor.getValue(i, value[i]); + } + } + + static void checkType(json_object* object, json_type type) + { + if (type != json_object_get_type(object)) { + throw ConfigException("Invalid field type " + std::to_string(type)); + } + } + + static void fromJsonObject(json_object* object, int& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 > INT32_MAX || value64 < INT32_MIN) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, std::int64_t& value) + { + checkType(object, json_type_int); + value = json_object_get_int64(object); + } + + static void fromJsonObject(json_object* object, std::uint32_t& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 > UINT32_MAX || value64 < 0) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, std::uint64_t& value) + { + checkType(object, json_type_int); + std::int64_t value64 = json_object_get_int64(object); + if (value64 < 0) { + throw ConfigException("Value out of range"); + } + value = static_cast(value64); + } + + static void fromJsonObject(json_object* object, bool& value) + { + checkType(object, json_type_boolean); + value = json_object_get_boolean(object); + } + + static void fromJsonObject(json_object* object, double& value) + { + checkType(object, json_type_double); + value = json_object_get_double(object); + } + + static void fromJsonObject(json_object* object, std::string& value) + { + checkType(object, json_type_string); + value = json_object_get_string(object); + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_FROM_KVJSON_VISITOR_HPP diff --git a/common/config/from-kvstore-visitor.hpp b/common/config/from-kvstore-visitor.hpp new file mode 100644 index 0000000..56bcd14 --- /dev/null +++ b/common/config/from-kvstore-visitor.hpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak (j.olszak@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 Jan Olszak (j.olszak@samsung.com) + * @brief Visitor for loading from KVStore + */ + +#ifndef COMMON_CONFIG_FROM_KVSTORE_VISITOR_HPP +#define COMMON_CONFIG_FROM_KVSTORE_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/kvstore.hpp" + +namespace config { + +class FromKVStoreVisitor { +public: + FromKVStoreVisitor(KVStore& store, const std::string& prefix) + : mStore(store), + mKeyPrefix(prefix) + { + } + + FromKVStoreVisitor& operator=(const FromKVStoreVisitor&) = delete; + + template + void visit(const std::string& name, T& value) + { + getInternal(key(mKeyPrefix, name), value); + } + +private: + KVStore& mStore; + std::string mKeyPrefix; + + FromKVStoreVisitor(const FromKVStoreVisitor& visitor, const std::string& prefix) + : mStore(visitor.mStore), + mKeyPrefix(prefix) + { + } + + template::value, int>::type = 0> + void getInternal(const std::string& name, T& value) + { + value = mStore.get(name); + } + + template::value, int>::type = 0> + void getInternal(const std::string& name, T& value) + { + FromKVStoreVisitor visitor(*this, name); + value.accept(visitor); + } + + template::value, int>::type = 0> + void getInternal(const std::string& name, std::vector& values) + { + values.clear(); + + size_t vectorSize = mStore.get(name); + if (vectorSize == 0) { + return; + } + + values.resize(vectorSize); + for (size_t i = 0; i < vectorSize; ++i) { + const std::string k = key(name, std::to_string(i)); + getInternal(k, values[i]); + } + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_FROM_KVSTORE_VISITOR_HPP diff --git a/common/config/fs-utils.cpp b/common/config/fs-utils.cpp new file mode 100644 index 0000000..1b08dce --- /dev/null +++ b/common/config/fs-utils.cpp @@ -0,0 +1,73 @@ +/* + * 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 Filesystem helper functions + */ + +#include "config/fs-utils.hpp" + +#include +#include + + +namespace config { +namespace fsutils { + +bool readFileContent(const std::string& path, std::string& result) +{ + std::ifstream file(path); + + if (!file) { + return false; + } + + file.seekg(0, std::ios::end); + std::streampos length = file.tellg(); + if (length < 0) { + return false; + } + result.resize(static_cast(length)); + file.seekg(0, std::ios::beg); + + file.read(&result[0], length); + if (!file) { + result.clear(); + return false; + } + + return true; +} + +bool saveFileContent(const std::string& path, const std::string& content) +{ + std::ofstream file(path); + if (!file) { + return false; + } + file.write(content.data(), static_cast(content.size())); + if (!file) { + return false; + } + return true; +} + +} // namespace fsutils +} // namespace config diff --git a/common/config/fs-utils.hpp b/common/config/fs-utils.hpp new file mode 100644 index 0000000..a9dccec --- /dev/null +++ b/common/config/fs-utils.hpp @@ -0,0 +1,43 @@ +/* + * 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 src/config/manager.hpp + */ + +#ifndef COMMON_CONFIG_FS_UTILS_HPP +#define COMMON_CONFIG_FS_UTILS_HPP + +#include + +namespace config { +namespace fsutils { + +bool readFileContent(const std::string& path, std::string& result); +bool saveFileContent(const std::string& path, const std::string& content); + +inline std::string readFileContent(const std::string& path) { + std::string content; + return readFileContent(path, content) ? content : std::string(); +} +} // namespace fsutils +} // namespace config + +#endif // COMMON_CONFIG_FS_UTILS_HPP diff --git a/common/config/is-union.hpp b/common/config/is-union.hpp new file mode 100644 index 0000000..63636ec --- /dev/null +++ b/common/config/is-union.hpp @@ -0,0 +1,70 @@ +/* + * 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 Krzysztof Dynowski (k.dynowski@samsumg.com) + * @brief Internal configuration helper + */ + +#ifndef COMMON_CONFIG_IS_UNION_HPP +#define COMMON_CONFIG_IS_UNION_HPP + +#include "config/is-visitable.hpp" + +namespace config { + +// generic member checker, start +template +struct has_member_impl { + template + static std::true_type check(typename F::template checker__* =0); + + template + static std::false_type check(...); + + static const bool value = std::is_same(0)), std::true_type>::value; +}; + +template +struct has_member : public std::integral_constant::value> {}; +// generic member checker, end + + +template +struct check_union : isVisitable { + template + struct checker__ {}; +}; +template +struct isUnion : has_member> {}; + +//Note: +// unfortunately, above generic has_member can't be used for isVisitable +// because Vistable need 'accept' OR 'accept const', while has_member make exect match +// e.g accept AND accept const + +} // namespace config + +#endif // COMMON_CONFIG_IS_UNION_HPP + diff --git a/common/config/is-visitable.hpp b/common/config/is-visitable.hpp new file mode 100644 index 0000000..d63069f --- /dev/null +++ b/common/config/is-visitable.hpp @@ -0,0 +1,53 @@ +/* + * 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 Internal configuration helper + */ + +#ifndef COMMON_CONFIG_IS_VISITABLE_HPP +#define COMMON_CONFIG_IS_VISITABLE_HPP + +#include + +namespace config { + +template +struct isVisitableHelper__ { + struct Visitor {}; + + template static std::true_type + test(decltype(std::declval().template accept(Visitor()))*); + + template static std::false_type + test(...); + + static constexpr bool value = std::is_same(0)), std::true_type>::value; +}; + +/** + * Helper for compile-time checking against existance of template method 'accept'. + */ +template +struct isVisitable : public std::integral_constant::value> {}; + +} // namespace config + +#endif // COMMON_CONFIG_IS_VISITABLE_HPP diff --git a/common/config/kvstore.cpp b/common/config/kvstore.cpp new file mode 100644 index 0000000..49656ae --- /dev/null +++ b/common/config/kvstore.cpp @@ -0,0 +1,342 @@ +/* + * 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 Definition of a class for key-value storage in a sqlite3 database + */ + +#include "config.hpp" + +#include "config/kvstore.hpp" +#include "config/exception.hpp" + +#include +#include +#include +#include +#include + +namespace config { + +namespace { + +const int AUTO_DETERM_SIZE = -1; +const int FIRST_COLUMN = 0; + +struct ScopedReset { + ScopedReset(std::unique_ptr& stmtPtr) + : mStmtPtr(stmtPtr) {} + ~ScopedReset() + { + mStmtPtr->reset(); + } +private: + std::unique_ptr& mStmtPtr; +}; + +/** + * Escape characters used by the GLOB function. + */ +void sqliteEscapeStr(::sqlite3_context* context, int argc, ::sqlite3_value** values) +{ + char* inBuff = (char*)sqlite3_value_text(values[0]); + if (argc != 1 || inBuff == NULL) { + sqlite3_result_error(context, "SQL function escapeSequence() called with invalid arguments.\n", -1); + return; + } + + std::string in(inBuff); + static const std::set toEscape({'?', '*', '[', ']'}); + + // Compute the out size + auto isEscapeChar = [&](char c) { + return toEscape.count(c) == 1; + }; + size_t numEscape = std::count_if(in.begin(), + in.end(), + isEscapeChar); + if (numEscape == 0) { + sqlite3_result_text(context, in.c_str(), AUTO_DETERM_SIZE, SQLITE_TRANSIENT); + } + + // Escape characters + std::string out(in.size() + 2 * numEscape, 'x'); + for (size_t i = 0, j = 0; + i < in.size(); + ++i, ++j) { + if (isEscapeChar(in[i])) { + out[j] = '['; + ++j; + out[j] = in[i]; + ++j; + out[j] = ']'; + } else { + out[j] = in[i]; + } + } + sqlite3_result_text(context, out.c_str(), AUTO_DETERM_SIZE, SQLITE_TRANSIENT); +} + +} // namespace + +KVStore::Transaction::Transaction(KVStore& kvStore) + : mLock(kvStore.mMutex) + , mKVStore(kvStore) + , mIsOuter(kvStore.mTransactionDepth == 0) +{ + if (mKVStore.mIsTransactionCommited) { + throw ConfigException("Previous transaction is not closed"); + } + if (mIsOuter) { + mKVStore.mConn.exec("BEGIN EXCLUSIVE TRANSACTION"); + } + ++mKVStore.mTransactionDepth; +} + +KVStore::Transaction::~Transaction() +{ + --mKVStore.mTransactionDepth; + if (mIsOuter) { + if (mKVStore.mIsTransactionCommited) { + mKVStore.mIsTransactionCommited = false; + } else { + mKVStore.mConn.exec("ROLLBACK TRANSACTION"); + } + } +} + +void KVStore::Transaction::commit() +{ + if (mKVStore.mIsTransactionCommited) { + throw ConfigException("Transaction already commited"); + } + if (mIsOuter) { + mKVStore.mConn.exec("COMMIT TRANSACTION"); + mKVStore.mIsTransactionCommited = true; + } +} + +KVStore::KVStore(const std::string& path) + : mTransactionDepth(0), + mIsTransactionCommited(false), + mPath(path), + mConn(path) +{ + setupDb(); + createFunctions(); + prepareStatements(); +} + +KVStore::~KVStore() +{ + assert(mTransactionDepth == 0); +} + +void KVStore::setupDb() +{ + // called only from ctor, transaction is not needed + mConn.exec("CREATE TABLE IF NOT EXISTS data (key TEXT PRIMARY KEY, value TEXT NOT NULL)"); +} + +void KVStore::prepareStatements() +{ + mGetValueStmt.reset( + new sqlite3::Statement(mConn, "SELECT value FROM data WHERE key = ? LIMIT 1")); + mGetKeyExistsStmt.reset( + // following line left in comment to have example of any subkey matching + //new sqlite3::Statement(mConn, "SELECT 1 FROM data WHERE key = ?1 OR key GLOB escapeStr(?1) || '.*' LIMIT 1")); + new sqlite3::Statement(mConn, "SELECT 1 FROM data WHERE key = ?1 LIMIT 1")); + mGetIsEmptyStmt.reset( + new sqlite3::Statement(mConn, "SELECT 1 FROM data LIMIT 1")); + mSetValueStmt.reset( + new sqlite3::Statement(mConn, "INSERT OR REPLACE INTO data (key, value) VALUES (?,?)")); + mRemoveValuesStmt.reset( + new sqlite3::Statement(mConn, "DELETE FROM data WHERE key = ?1 OR key GLOB escapeStr(?1) ||'.*' ")); + mGetKeysStmt.reset( + new sqlite3::Statement(mConn, "SELECT key FROM data")); +} + +void KVStore::createFunctions() +{ + int ret = sqlite3_create_function(mConn.get(), "escapeStr", 1, SQLITE_ANY, 0, &sqliteEscapeStr, 0, 0); + if (ret != SQLITE_OK) { + throw ConfigException("Error during creating functions: " + mConn.getErrorMessage()); + } +} + +void KVStore::clear() +{ + Transaction transaction(*this); + mConn.exec("DELETE FROM data"); + transaction.commit(); +} + +bool KVStore::isEmpty() +{ + Transaction transaction(*this); + ScopedReset scopedReset(mGetIsEmptyStmt); + + int ret = ::sqlite3_step(mGetIsEmptyStmt->get()); + if (ret != SQLITE_DONE && ret != SQLITE_ROW) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + + transaction.commit(); + return ret == SQLITE_DONE; +} + +bool KVStore::exists(const std::string& key) +{ + Transaction transaction(*this); + ScopedReset scopedReset(mGetKeyExistsStmt); + + ::sqlite3_bind_text(mGetKeyExistsStmt->get(), 1, key.c_str(), AUTO_DETERM_SIZE, SQLITE_TRANSIENT); + + int ret = ::sqlite3_step(mGetKeyExistsStmt->get()); + if (ret != SQLITE_DONE && ret != SQLITE_ROW) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + + transaction.commit(); + return ret == SQLITE_ROW; +} + +void KVStore::remove(const std::string& key) +{ + Transaction transaction(*this); + ScopedReset scopedReset(mRemoveValuesStmt); + + ::sqlite3_bind_text(mRemoveValuesStmt->get(), 1, key.c_str(), AUTO_DETERM_SIZE, SQLITE_STATIC); + + if (::sqlite3_step(mRemoveValuesStmt->get()) != SQLITE_DONE) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + transaction.commit(); +} + +void KVStore::setInternal(const std::string& key, const std::string& value) +{ + Transaction transaction(*this); + ScopedReset scopedReset(mSetValueStmt); + + ::sqlite3_bind_text(mSetValueStmt->get(), 1, key.c_str(), AUTO_DETERM_SIZE, SQLITE_STATIC); + ::sqlite3_bind_text(mSetValueStmt->get(), 2, value.c_str(), AUTO_DETERM_SIZE, SQLITE_STATIC); + + + if (::sqlite3_step(mSetValueStmt->get()) != SQLITE_DONE) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + transaction.commit(); +} + +void KVStore::setInternal(const std::string& key, const std::initializer_list& values) +{ + setInternal(key, std::vector(values)); +} + +void KVStore::setInternal(const std::string& key, const std::vector& values) +{ + if (values.size() > std::numeric_limits::max()) { + throw ConfigException("Too many values to insert"); + } + + Transaction transaction(*this); + + remove(key); + + // Save vector's capacity + setInternal(key, values.size()); + + // Save vector's elements + for (unsigned int i = 0; i < values.size(); ++i) { + setInternal(config::key(key, std::to_string(i)), + values[i]); + } + transaction.commit(); +} + +std::string KVStore::getInternal(const std::string& key, std::string*) +{ + Transaction transaction(*this); + ScopedReset scopedReset(mGetValueStmt); + + ::sqlite3_bind_text(mGetValueStmt->get(), 1, key.c_str(), AUTO_DETERM_SIZE, SQLITE_TRANSIENT); + + int ret = ::sqlite3_step(mGetValueStmt->get()); + if (ret == SQLITE_DONE) { + throw ConfigException("No value corresponding to the key: " + key + "@" + mPath); + } + if (ret != SQLITE_ROW) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + + std::string value = reinterpret_cast( + sqlite3_column_text(mGetValueStmt->get(), FIRST_COLUMN)); + + transaction.commit(); + return value; +} + +std::vector KVStore::getInternal(const std::string& key, std::vector*) +{ + Transaction transaction(*this); + + unsigned int valuesSize = get(key); + std::vector values(valuesSize); + if (valuesSize == 0) { + transaction.commit(); + return values; + } + + for (unsigned int i = 0; i < values.size(); ++i) { + values[i] = getInternal(config::key(key, std::to_string(i)), + static_cast(nullptr)); + + } + + transaction.commit(); + return values; +} + +std::vector KVStore::getKeys() +{ + Transaction transaction(*this); + ScopedReset scopedReset(mGetKeysStmt); + + std::vector result; + + for (;;) { + int ret = ::sqlite3_step(mGetKeysStmt->get()); + if (ret == SQLITE_DONE) { + break; + } + if (ret != SQLITE_ROW) { + throw ConfigException("Error during stepping: " + mConn.getErrorMessage()); + } + const char* key = reinterpret_cast(sqlite3_column_text(mGetKeysStmt->get(), + FIRST_COLUMN)); + result.push_back(key); + } + + transaction.commit(); + return result; +} + +} // namespace config diff --git a/common/config/kvstore.hpp b/common/config/kvstore.hpp new file mode 100644 index 0000000..0717665 --- /dev/null +++ b/common/config/kvstore.hpp @@ -0,0 +1,261 @@ +/* + * 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 Declaration of a class for key-value storage in a sqlite3 database + */ + +#ifndef COMMON_CONFIG_KVSTORE_HPP +#define COMMON_CONFIG_KVSTORE_HPP + +#include "config/sqlite3/connection.hpp" +#include "config/sqlite3/statement.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace config { + +class KVStore { + +public: + /** + * A guard struct for thread synchronization and transaction management. + */ + class Transaction { + public: + Transaction(KVStore& store); + ~Transaction(); + + Transaction(const Transaction&) = delete; + Transaction& operator=(const Transaction&) = delete; + + void commit(); + private: + std::unique_lock mLock; + KVStore& mKVStore; + bool mIsOuter; + }; + + /** + * @param path configuration database file path + */ + explicit KVStore(const std::string& path); + ~KVStore(); + + KVStore(const KVStore&) = delete; + KVStore& operator=(const KVStore&) = delete; + + /** + * Clears all the stored data + */ + void clear(); + + /** + * @return Is there any data stored + */ + bool isEmpty(); + + /** + * @param key string regexp of the stored values + * + * @return Does this key exist in the database + */ + bool exists(const std::string& key); + + /** + * Removes values corresponding to the passed key. + * Many values may correspond to one key, so many values may + * need to be deleted + * + * @param key string regexp of the stored values + */ + void remove(const std::string& key); + + /** + * Stores a single value corresponding to the passed key + * + * @param key string key of the value + * @param value value corresponding to the key + */ + template + void set(const std::string& key, const T& value) + { + return setInternal(key, value); + } + + /** + * Gets the value corresponding to the key. + * Uses stringstreams to parse. + * + * @param key string key of the value + * @tparam T = std::string desired type of the return value + * @return value corresponding to the key + */ + template + T get(const std::string& key) + { + return getInternal(key, static_cast(nullptr)); + } + + /** + * Returns all stored keys. + */ + std::vector getKeys(); + +private: + typedef std::lock_guard Lock; + + std::recursive_mutex mMutex; + size_t mTransactionDepth; + bool mIsTransactionCommited; + + void setInternal(const std::string& key, const std::string& value); + void setInternal(const std::string& key, const std::initializer_list& values); + void setInternal(const std::string& key, const std::vector& values); + template + void setInternal(const std::string& key, const T& value); + template + void setInternal(const std::string& key, const std::vector& values); + + std::string getInternal(const std::string& key, std::string*); + std::vector getInternal(const std::string& key, std::vector*); + template + T getInternal(const std::string& key, T*); + template + std::vector getInternal(const std::string& key, std::vector*); + + std::string mPath; + sqlite3::Connection mConn; + std::unique_ptr mGetValueStmt; + std::unique_ptr mGetKeyExistsStmt; + std::unique_ptr mGetIsEmptyStmt; + std::unique_ptr mGetValueListStmt; + std::unique_ptr mSetValueStmt; + std::unique_ptr mRemoveValuesStmt; + std::unique_ptr mGetKeysStmt; + + void setupDb(); + void prepareStatements(); + void createFunctions(); +}; + +namespace { +template +std::string toString(const T& value) +{ + std::ostringstream oss; + oss << value; + return oss.str(); +} + +template +T fromString(const std::string& strValue) +{ + std::istringstream iss(strValue); + T value; + iss >> value; + return value; +} + +} // namespace + +template +void KVStore::setInternal(const std::string& key, const T& value) +{ + setInternal(key, toString(value)); +} + +template +void KVStore::setInternal(const std::string& key, const std::vector& values) +{ + std::vector strValues(values.size()); + + std::transform(values.begin(), + values.end(), + strValues.begin(), + toString); + + setInternal(key, strValues); +} + +template +T KVStore::getInternal(const std::string& key, T*) +{ + return fromString(getInternal(key, static_cast(nullptr))); +} + +template +std::vector KVStore::getInternal(const std::string& key, std::vector*) +{ + std::vector strValues = getInternal(key, static_cast*>(nullptr)); + std::vector values(strValues.size()); + + std::transform(strValues.begin(), + strValues.end(), + values.begin(), + fromString); + + return values; +} + +/** + * Concatenates all parameters into one std::string. + * Uses '.' to connect the terms. + * @param args components of the string + * @tparam delim optional delimiter + * @tparam typename ... Args any type implementing str + * @return string created from he args + */ +template +std::string key(const Arg1& a1, const Args& ... args) +{ + std::string ret = toString(a1); + std::initializer_list strings {toString(args)...}; + for (const std::string& s : strings) { + ret += delim + s; + } + + return ret; +} + +/** + * Function added for key function completeness. + * + * @tparam delim = '.' parameter not used, added for consistency + * @return empty string + */ +template +std::string key() +{ + return std::string(); +} + +} // namespace config + +#endif // COMMON_CONFIG_KVSTORE_HPP + + diff --git a/common/config/manager.hpp b/common/config/manager.hpp new file mode 100644 index 0000000..0deb8d8 --- /dev/null +++ b/common/config/manager.hpp @@ -0,0 +1,257 @@ +/* + * 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 Configuration management functions + */ + +#ifndef COMMON_CONFIG_MANAGER_HPP +#define COMMON_CONFIG_MANAGER_HPP + +#include "config/to-gvariant-visitor.hpp" +#include "config/to-json-visitor.hpp" +#include "config/to-kvstore-visitor.hpp" +#include "config/to-fdstore-visitor.hpp" +#include "config/from-gvariant-visitor.hpp" +#include "config/from-json-visitor.hpp" +#include "config/from-kvstore-visitor.hpp" +#include "config/from-fdstore-visitor.hpp" +#include "config/from-kvjson-visitor.hpp" +#include "config/fs-utils.hpp" +#include "config/is-union.hpp" + +namespace config { + +/** + * Fills the configuration with data stored in the GVariant + * + * @param gvariant configuration in GVariant type + * @param config visitable structure to fill + */ +template +void loadFromGVariant(GVariant* gvariant, Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + static_assert(!isUnion::value, "Don't use CONFIG_DECLARE_UNION in top level config"); + + FromGVariantVisitor visitor(gvariant); + config.accept(visitor); +} + +/** + * Saves the config in a GVariant + * + * @param config visitable structure to convert + */ +template +GVariant* saveToGVariant(const Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + static_assert(!isUnion::value, "Don't use CONFIG_DECLARE_UNION in top level config"); + + ToGVariantVisitor visitor; + config.accept(visitor); + return visitor.toVariant(); +} + +/** + * Fills the configuration with data stored in the json string + * + * @param jsonString configuration in a json format + * @param config visitable structure to fill + */ +template +void loadFromJsonString(const std::string& jsonString, Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + FromJsonVisitor visitor(jsonString); + config.accept(visitor); +} + +/** + * Creates a string representation of the configuration in json format + * + * @param config visitable structure to convert + */ +template +std::string saveToJsonString(const Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + ToJsonVisitor visitor; + config.accept(visitor); + return visitor.toString(); +} + +/** + * Loads the config from a json file + * + * @param filename path to the file + * @param config visitable structure to load + */ +template +void loadFromJsonFile(const std::string& filename, Config& config) +{ + std::string content; + if (!fsutils::readFileContent(filename, content)) { + throw ConfigException("Could not load " + filename); + } + try { + loadFromJsonString(content, config); + } catch (ConfigException& e) { + throw ConfigException("Error in " + filename + ": " + e.what()); + } +} + +/** + * Saves the config in a json file + * + * @param filename path to the file + * @param config visitable structure to save + */ +template +void saveToJsonFile(const std::string& filename, const Config& config) +{ + const std::string content = saveToJsonString(config); + if (!fsutils::saveFileContent(filename, content)) { + throw ConfigException("Could not save " + filename); + } +} + +/** + * Loads a visitable configuration from KVStore. + * + * @param filename path to the KVStore db + * @param config visitable structure to load + * @param configName name of the configuration inside the KVStore db + */ +template +void loadFromKVStore(const std::string& filename, Config& config, const std::string& configName) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + KVStore store(filename); + KVStore::Transaction transaction(store); + FromKVStoreVisitor visitor(store, configName); + config.accept(visitor); + transaction.commit(); +} + +/** + * Saves the config to a KVStore. + * + * @param filename path to the KVStore db + * @param config visitable structure to save + * @param configName name of the config inside the KVStore db + */ +template +void saveToKVStore(const std::string& filename, const Config& config, const std::string& configName) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + KVStore store(filename); + KVStore::Transaction transaction(store); + ToKVStoreVisitor visitor(store, configName); + config.accept(visitor); + transaction.commit(); +} + +/** + * Load the config from KVStore with defaults given in json + * + * @param kvfile path to the KVStore db + * @param jsonfile path to json file with defaults + * @param config visitable structure to save + * @param kvConfigName name of the config inside the KVStore db + */ +template +void loadFromKVStoreWithJson(const std::string& kvfile, + const std::string& json, + Config& config, + const std::string& kvConfigName) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + KVStore store(kvfile); + KVStore::Transaction transaction(store); + FromKVJsonVisitor visitor(store, json, kvConfigName); + config.accept(visitor); + transaction.commit(); +} + +/** + * Load the config from KVStore with defaults given in json file + * + * @param kvfile path to the KVStore db + * @param jsonfile path to json file with defaults + * @param config visitable structure to save + * @param kvConfigName name of the config inside the KVStore db + */ +template +void loadFromKVStoreWithJsonFile(const std::string& kvfile, + const std::string& jsonfile, + Config& config, + const std::string& kvConfigName) +{ + std::string content; + if (!fsutils::readFileContent(jsonfile, content)) { + throw ConfigException("Could not load " + jsonfile); + } + try { + loadFromKVStoreWithJson(kvfile, content, config, kvConfigName); + } catch (ConfigException& e) { + throw ConfigException("Error in " + jsonfile + ": " + e.what()); + } +} + +/** + * Load binary data from a file/socket/pipe represented by the fd + * + * @param fd file descriptor + * @param config visitable structure to load + */ +template +void loadFromFD(const int fd, Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + FromFDStoreVisitor visitor(fd); + config.accept(visitor); +} + +/** + * Save binary data to a file/socket/pipe represented by the fd + * + * @param fd file descriptor + * @param config visitable structure to save + */ +template +void saveToFD(const int fd, const Config& config) +{ + static_assert(isVisitable::value, "Use CONFIG_REGISTER macro"); + + ToFDStoreVisitor visitor(fd); + config.accept(visitor); +} + +} // namespace config + +#endif // COMMON_CONFIG_MANAGER_HPP diff --git a/common/config/sqlite3/connection.cpp b/common/config/sqlite3/connection.cpp new file mode 100644 index 0000000..cb25694 --- /dev/null +++ b/common/config/sqlite3/connection.cpp @@ -0,0 +1,77 @@ +/* + * 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 Definition of the class managing a sqlite3 database connection + */ + + +#include "config/sqlite3/connection.hpp" +#include "config/exception.hpp" + +namespace config { +namespace sqlite3 { + +Connection::Connection(const std::string& path) +{ + if (path.empty()) { + // Sqlite creates temporary database in case of empty path + // but we want to forbid this. + throw ConfigException("Error opening the database: empty path"); + } + if (::sqlite3_open_v2(path.c_str(), + &mDbPtr, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, + NULL) != SQLITE_OK) { + throw ConfigException("Error opening the database: " + getErrorMessage()); + } + + if (mDbPtr == NULL) { + throw ConfigException("Error opening the database: Unable to allocate memory."); + } +} + +Connection::~Connection() +{ + if (::sqlite3_close(mDbPtr) != SQLITE_OK) { + throw ConfigException("Error during closing the database. Error: " + getErrorMessage()); + } +} + +void Connection::exec(const std::string& query) +{ + char* mess; + if (::sqlite3_exec(mDbPtr, query.c_str(), 0, 0, &mess) != SQLITE_OK) { + throw ConfigException("Error during executing statement " + std::string(mess)); + } +} + +::sqlite3* Connection::get() +{ + return mDbPtr; +} + +std::string Connection::getErrorMessage() +{ + return std::string(sqlite3_errmsg(mDbPtr)); +} + +} // namespace sqlite3 +} // namespace config diff --git a/common/config/sqlite3/connection.hpp b/common/config/sqlite3/connection.hpp new file mode 100644 index 0000000..850332a --- /dev/null +++ b/common/config/sqlite3/connection.hpp @@ -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 Declaration of the class managing a sqlite3 database connection + */ + +#ifndef COMMON_CONFIG_SQLITE3_CONNECTION_HPP +#define COMMON_CONFIG_SQLITE3_CONNECTION_HPP + +#include +#include + +namespace config { +namespace sqlite3 { + +struct Connection { + /** + * @param path database file path + */ + Connection(const std::string& path); + Connection(const Connection&) = delete; + ~Connection(); + + /** + * @return pointer to the corresponding sqlite3 database object + */ + ::sqlite3* get(); + + /** + * @return last error message in the database + */ + std::string getErrorMessage(); + + /** + * Executes the query in the database. + * + * @param query query to be executed + */ + void exec(const std::string& query); + +private: + ::sqlite3* mDbPtr; +}; + +} // namespace sqlite3 +} // namespace config + +#endif // COMMON_CONFIG_SQLITE3_CONNECTION_HPP diff --git a/common/config/sqlite3/statement.cpp b/common/config/sqlite3/statement.cpp new file mode 100644 index 0000000..287cb1c --- /dev/null +++ b/common/config/sqlite3/statement.cpp @@ -0,0 +1,77 @@ +/* + * 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 Definition of the class managing a sqlite3 statement + */ + +#include "config/sqlite3/statement.hpp" +#include "config/exception.hpp" + + +namespace config { +namespace sqlite3 { + +Statement::Statement(sqlite3::Connection& connRef, const std::string& query) + : mConnRef(connRef) +{ + if (::sqlite3_prepare_v2(connRef.get(), + query.c_str(), + query.size(), + &mStmtPtr, + NULL) + != SQLITE_OK) { + throw ConfigException("Error during preparing statement " + + mConnRef.getErrorMessage()); + } + + if (mStmtPtr == NULL) { + throw ConfigException("Wrong query: " + query); + } +} + +Statement::Statement::~Statement() +{ + if (::sqlite3_finalize(mStmtPtr) != SQLITE_OK) { + throw ConfigException("Error during finalizing statement " + + mConnRef.getErrorMessage()); + } +} + +sqlite3_stmt* Statement::get() +{ + return mStmtPtr; +} + +void Statement::reset() +{ + if (::sqlite3_clear_bindings(mStmtPtr) != SQLITE_OK) { + throw ConfigException("Error unbinding statement: " + + mConnRef.getErrorMessage()); + } + + if (::sqlite3_reset(mStmtPtr) != SQLITE_OK) { + throw ConfigException("Error reseting statement: " + + mConnRef.getErrorMessage()); + } +} + +} // namespace sqlite3 +} // namespace config diff --git a/common/config/sqlite3/statement.hpp b/common/config/sqlite3/statement.hpp new file mode 100644 index 0000000..48a1fca --- /dev/null +++ b/common/config/sqlite3/statement.hpp @@ -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 Declaration of the class managing a sqlite3 statement + */ + +#ifndef COMMON_CONFIG_SQLITE3_STATEMENT_HPP +#define COMMON_CONFIG_SQLITE3_STATEMENT_HPP + +#include "config/sqlite3/connection.hpp" + +#include +#include + +namespace config { +namespace sqlite3 { + +struct Statement { + + /** + * @param connRef reference to the Connection object + * @param query query to be executed + */ + Statement(sqlite3::Connection& connRef, const std::string& query); + ~Statement(); + + /** + * @return pointer to the sqlite3 statement + */ + sqlite3_stmt* get(); + + /** + * Clears the bindings and resets the statement. + * After this the statement can be executed again + */ + void reset(); + +private: + ::sqlite3_stmt* mStmtPtr; + sqlite3::Connection& mConnRef; +}; + +} // namespace sqlite3 +} // namespace config + +#endif // COMMON_CONFIG_SQLITE3_STATEMENT_HPP + + diff --git a/common/config/to-fdstore-visitor.hpp b/common/config/to-fdstore-visitor.hpp new file mode 100644 index 0000000..50756c1 --- /dev/null +++ b/common/config/to-fdstore-visitor.hpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak (j.olszak@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 Jan Olszak (j.olszak@samsung.com) + * @brief Visitor for saving to FDStore + */ + +#ifndef COMMON_CONFIG_TO_FDSTORE_VISITOR_HPP +#define COMMON_CONFIG_TO_FDSTORE_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/fdstore.hpp" + +#include + +namespace config { + +class ToFDStoreVisitor { + +public: + ToFDStoreVisitor(int fd) + : mStore(fd) + { + } + + ToFDStoreVisitor(const ToFDStoreVisitor&) = default; + + ToFDStoreVisitor& operator=(const ToFDStoreVisitor&) = delete; + + template + void visit(const std::string&, const T& value) + { + writeInternal(value); + } + +private: + FDStore mStore; + + void writeInternal(const std::string& value) + { + writeInternal(value.size()); + mStore.write(value.c_str(), value.size()); + } + + template::value, int>::type = 0> + void writeInternal(const T& value) + { + mStore.write(&value, sizeof(T)); + } + + template::value, int>::type = 0> + void writeInternal(const T& value) + { + ToFDStoreVisitor visitor(*this); + value.accept(visitor); + } + + template + void writeInternal(const std::vector& values) + { + writeInternal(values.size()); + for (const T& value : values) { + writeInternal(value); + } + } + +}; + +} // namespace config + +#endif // COMMON_CONFIG_TO_FDSTORE_VISITOR_HPP diff --git a/common/config/to-gvariant-visitor.hpp b/common/config/to-gvariant-visitor.hpp new file mode 100644 index 0000000..bb94e49 --- /dev/null +++ b/common/config/to-gvariant-visitor.hpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki (m.malicki2@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 Mateusz Malicki (m.malicki2@samsung.com) + * @brief GVariant visitor + */ + +#ifndef COMMON_CONFIG_TO_GVARIANT_VISITOR_HPP +#define COMMON_CONFIG_TO_GVARIANT_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/is-union.hpp" + +#include +#include +#include + +namespace config { + +class ToGVariantVisitor { + +public: + ToGVariantVisitor() + : mBuilder(g_variant_builder_new(G_VARIANT_TYPE_TUPLE)) + { + } + + ToGVariantVisitor(const ToGVariantVisitor& visitor) + : mBuilder(visitor.mBuilder ? g_variant_builder_ref(visitor.mBuilder) : nullptr) + { + } + + ~ToGVariantVisitor() + { + if (mBuilder) { + g_variant_builder_unref(mBuilder); + } + } + + ToGVariantVisitor& operator=(const ToGVariantVisitor&) = delete; + + GVariant* toVariant() + { + if (mBuilder) { + GVariant* ret = g_variant_builder_end(mBuilder); + g_variant_builder_unref(mBuilder); + mBuilder = nullptr; + return ret; + } + return nullptr; + } + + template + void visit(const std::string& /* name */, const T& value) + { + writeInternal(value); + } +private: + GVariantBuilder* mBuilder; + + void writeInternal(std::int32_t value) { add("i", value); }; + void writeInternal(std::int64_t value) { add("x", value); }; + void writeInternal(std::uint32_t value) { add("u", value); }; + void writeInternal(std::uint64_t value) { add("t", value); }; + void writeInternal(bool value) { add("b", value); }; + void writeInternal(double value) { add("d", value); }; + void writeInternal(const std::string& value) { add("s", value.c_str()); }; + + template + void writeInternal(const std::vector& value) + { + if (!value.empty()) { + g_variant_builder_open(mBuilder, G_VARIANT_TYPE_ARRAY); + for (const T& v : value) { + writeInternal(v); + } + g_variant_builder_close(mBuilder); + } else { + g_variant_builder_add(mBuilder, "as", NULL); + } + } + + template + typename std::enable_if::value && !isUnion::value>::type + writeInternal(const T& value) + { + ToGVariantVisitor visitor; + value.accept(visitor); + g_variant_builder_add_value(mBuilder, visitor.toVariant()); + } + + template + typename std::enable_if::value && isUnion::value>::type + writeInternal(const T& value) + { + ToGVariantVisitor visitor; + value.accept(visitor); + add("v", visitor.toVariant()); + } + + template + void add(const char* type, Value value) { + g_variant_builder_add(mBuilder, type, value); + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_TO_GVARIANT_VISITOR_HPP diff --git a/common/config/to-json-visitor.hpp b/common/config/to-json-visitor.hpp new file mode 100644 index 0000000..f524900 --- /dev/null +++ b/common/config/to-json-visitor.hpp @@ -0,0 +1,140 @@ +/* + * 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 JSON visitor + */ + +#ifndef COMMON_CONFIG_TO_JSON_VISITOR_HPP +#define COMMON_CONFIG_TO_JSON_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/exception.hpp" + +#include +#include +#include + +namespace config { + +class ToJsonVisitor { + +public: + ToJsonVisitor() + : mObject(json_object_new_object()) + { + } + + ToJsonVisitor(const ToJsonVisitor& visitor) + : mObject(json_object_get(visitor.mObject)) + { + } + + ~ToJsonVisitor() + { + json_object_put(mObject); + } + + ToJsonVisitor& operator=(const ToJsonVisitor&) = delete; + + std::string toString() const + { + return json_object_to_json_string(mObject); + } + + template + void visit(const std::string& name, const T& value) + { + json_object_object_add(mObject, name.c_str(), toJsonObject(value)); + } +private: + json_object* mObject; + + + json_object* detach() + { + json_object* ret = mObject; + mObject = nullptr; + return ret; + } + + static json_object* toJsonObject(std::int32_t value) + { + return json_object_new_int(value); + } + + static json_object* toJsonObject(std::int64_t value) + { + return json_object_new_int64(value); + } + + static json_object* toJsonObject(std::uint32_t value) + { + if (value > INT32_MAX) { + throw ConfigException("Value out of range"); + } + return json_object_new_int(value); + } + + static json_object* toJsonObject(std::uint64_t value) + { + if (value > INT64_MAX) { + throw ConfigException("Value out of range"); + } + return json_object_new_int64(value); + } + + static json_object* toJsonObject(bool value) + { + return json_object_new_boolean(value); + } + + static json_object* toJsonObject(double value) + { + return json_object_new_double(value); + } + + static json_object* toJsonObject(const std::string& value) + { + return json_object_new_string(value.c_str()); + } + + template + static json_object* toJsonObject(const std::vector& value) + { + json_object* array = json_object_new_array(); + for (const T& v : value) { + json_object_array_add(array, toJsonObject(v)); + } + return array; + } + + template::value>::type> + static json_object* toJsonObject(const T& value) + { + ToJsonVisitor visitor; + value.accept(visitor); + return visitor.detach(); + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_TO_JSON_VISITOR_HPP diff --git a/common/config/to-kvstore-visitor.hpp b/common/config/to-kvstore-visitor.hpp new file mode 100644 index 0000000..14944dc --- /dev/null +++ b/common/config/to-kvstore-visitor.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak (j.olszak@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 Jan Olszak (j.olszak@samsung.com) + * @brief Visitor for saving to KVStore + */ + +#ifndef COMMON_CONFIG_TO_KVSTORE_VISITOR_HPP +#define COMMON_CONFIG_TO_KVSTORE_VISITOR_HPP + +#include "config/is-visitable.hpp" +#include "config/kvstore.hpp" + +namespace config { + +class ToKVStoreVisitor { + +public: + ToKVStoreVisitor(KVStore& store, const std::string& prefix) + : mStore(store), + mKeyPrefix(prefix) + { + } + + ToKVStoreVisitor& operator=(const ToKVStoreVisitor&) = delete; + + template + void visit(const std::string& name, const T& value) + { + setInternal(key(mKeyPrefix, name), value); + } + +private: + KVStore& mStore; + std::string mKeyPrefix; + + ToKVStoreVisitor(const ToKVStoreVisitor& visitor, const std::string& prefix) + : mStore(visitor.mStore), + mKeyPrefix(prefix) + { + } + + template::value, int>::type = 0> + void setInternal(const std::string& name, const T& value) + { + mStore.set(name, value); + } + + template::value, int>::type = 0> + void setInternal(const std::string& name, const T& value) + { + ToKVStoreVisitor visitor(*this, name); + value.accept(visitor); + } + + template::value, int>::type = 0> + void setInternal(const std::string& name, const std::vector& values) + { + mStore.remove(name); + mStore.set(name, values.size()); + for (size_t i = 0; i < values.size(); ++i) { + setInternal(key(name, std::to_string(i)), values[i]); + } + } +}; + +} // namespace config + +#endif // COMMON_CONFIG_TO_KVSTORE_VISITOR_HPP diff --git a/common/dbus/connection.cpp b/common/dbus/connection.cpp new file mode 100644 index 0000000..12544be --- /dev/null +++ b/common/dbus/connection.cpp @@ -0,0 +1,409 @@ +/* + * 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 Dbus connection class + */ + +#include "config.hpp" +#include "dbus/connection.hpp" +#include "dbus/exception.hpp" +#include "utils/callback-wrapper.hpp" +#include "utils/scoped-gerror.hpp" +#include "utils/glib-utils.hpp" +#include "logger/logger.hpp" + +using namespace vasum::utils; + +namespace dbus { + + +namespace { + +const std::string SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket"; +const std::string INTROSPECT_INTERFACE = "org.freedesktop.DBus.Introspectable"; +const std::string INTROSPECT_METHOD = "Introspect"; + +class MethodResultBuilderImpl : public MethodResultBuilder { +public: + MethodResultBuilderImpl(GDBusMethodInvocation* invocation) + : mInvocation(invocation), mResultSet(false) {} + ~MethodResultBuilderImpl() + { + if (!mResultSet) { + setError("org.freedesktop.DBus.Error.UnknownMethod", "Not implemented"); + } + } + void set(GVariant* parameters) + { + g_dbus_method_invocation_return_value(mInvocation, parameters); + mResultSet = true; + } + void setVoid() + { + set(NULL); + } + void setError(const std::string& name, const std::string& message) + { + g_dbus_method_invocation_return_dbus_error(mInvocation, name.c_str(), message.c_str()); + mResultSet = true; + } +private: + GDBusMethodInvocation* mInvocation; + bool mResultSet; +}; + +void throwDbusException(const ScopedGError& e) +{ + if (e->domain == g_io_error_quark()) { + if (e->code == G_IO_ERROR_DBUS_ERROR) { + throw DbusCustomException(e->message); + } else { + throw DbusIOException(e->message); + } + } else if (e->domain == g_dbus_error_quark()) { + throw DbusOperationException(e->message); + } else if (e->domain == g_markup_error_quark()) { + throw DbusInvalidArgumentException(e->message); + } else { + throw DbusException(e->message); + } +} + +class AsyncMethodCallResultImpl : public AsyncMethodCallResult { +public: + AsyncMethodCallResultImpl(GVariant* result, const ScopedGError& error) + : mResult(result), mError(error) {} + ~AsyncMethodCallResultImpl() + { + if (mResult) { + g_variant_unref(mResult); + } + } + GVariant* get() + { + if (mError) { + throwDbusException(mError); + } + return mResult; + } +private: + GVariant* mResult; + const ScopedGError& mError; +}; + +} // namespace + +DbusConnection::Pointer DbusConnection::create(const std::string& address) +{ + return Pointer(new DbusConnection(address)); +} + +DbusConnection::Pointer DbusConnection::createSystem() +{ + return create(SYSTEM_BUS_ADDRESS); +} + +DbusConnection::DbusConnection(const std::string& address) + : mConnection(NULL) + , mNameId(0) +{ + ScopedGError error; + const GDBusConnectionFlags flags = + static_cast(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | + G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION); + // TODO: this is possible deadlock if the dbus + // socket exists but there is no dbus-daemon + mConnection = g_dbus_connection_new_for_address_sync(address.c_str(), + flags, + NULL, + NULL, + &error); + if (error) { + error.strip(); + LOGE("Could not connect to " << address << "; " << error); + throwDbusException(error); + } +} + +DbusConnection::~DbusConnection() +{ + // Close connection in a glib thread (because of a bug in glib) + GDBusConnection* connection = mConnection; + guint nameId = mNameId; + + auto closeConnection = [=]() { + if (nameId) { + g_bus_unown_name(nameId); + } + g_object_unref(connection); + LOGT("Connection deleted"); + }; + executeInGlibThread(closeConnection, mGuard); +} + +void DbusConnection::setName(const std::string& name, + const VoidCallback& onNameAcquired, + const VoidCallback& onNameLost) +{ + mNameId = g_bus_own_name_on_connection(mConnection, + name.c_str(), + G_BUS_NAME_OWNER_FLAGS_NONE, + &DbusConnection::onNameAcquired, + &DbusConnection::onNameLost, + createCallbackWrapper( + NameCallbacks(onNameAcquired, onNameLost), + mGuard.spawn()), + &deleteCallbackWrapper); +} + +void DbusConnection::onNameAcquired(GDBusConnection*, const gchar* name, gpointer userData) +{ + LOGD("Name acquired " << name); + const NameCallbacks& callbacks = getCallbackFromPointer(userData); + if (callbacks.nameAcquired) { + callbacks.nameAcquired(); + } +} + +void DbusConnection::onNameLost(GDBusConnection*, const gchar* name, gpointer userData) +{ + LOGD("Name lost " << name); + const NameCallbacks& callbacks = getCallbackFromPointer(userData); + if (callbacks.nameLost) { + callbacks.nameLost(); + } +} + +void DbusConnection::emitSignal(const std::string& objectPath, + const std::string& interface, + const std::string& name, + GVariant* parameters) +{ + ScopedGError error; + g_dbus_connection_emit_signal(mConnection, + NULL, + objectPath.c_str(), + interface.c_str(), + name.c_str(), + parameters, + &error); + if (error) { + error.strip(); + LOGE("Emit signal failed; " << error); + throwDbusException(error); + } +} + +DbusConnection::SubscriptionId DbusConnection::signalSubscribe(const SignalCallback& callback, + const std::string& senderBusName) +{ + return g_dbus_connection_signal_subscribe(mConnection, + senderBusName.empty() ? NULL : senderBusName.c_str(), + NULL, + NULL, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + &DbusConnection::onSignal, + createCallbackWrapper(callback, + mGuard.spawn()), + &deleteCallbackWrapper); +} + +void DbusConnection::signalUnsubscribe(DbusConnection::SubscriptionId subscriptionId) +{ + g_dbus_connection_signal_unsubscribe(mConnection, subscriptionId); +} + +void DbusConnection::onSignal(GDBusConnection*, + const gchar* sender, + const gchar* object, + const gchar* interface, + const gchar* name, + GVariant* parameters, + gpointer userData) +{ + const SignalCallback& callback = getCallbackFromPointer(userData); + + LOGD("Signal: " << sender << "; " << object << "; " << interface << "; " << name); + + if (callback) { + callback(sender, object, interface, name, parameters); + } +} + +std::string DbusConnection::introspect(const std::string& busName, const std::string& objectPath) +{ + GVariantPtr result = DbusConnection::callMethod(busName, + objectPath, + INTROSPECT_INTERFACE, + INTROSPECT_METHOD, + NULL, + "(s)"); + const gchar* xml; + g_variant_get(result.get(), "(&s)", &xml); + return xml; +} + +void DbusConnection::registerObject(const std::string& objectPath, + const std::string& objectDefinitionXml, + const MethodCallCallback& callback) +{ + ScopedGError error; + GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(objectDefinitionXml.c_str(), &error); + if (nodeInfo != NULL && (nodeInfo->interfaces == NULL || + nodeInfo->interfaces[0] == NULL || + nodeInfo->interfaces[1] != NULL)) { + g_dbus_node_info_unref(nodeInfo); + g_set_error(&error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Expected exactly one interface"); + } + if (error) { + error.strip(); + LOGE("Invalid xml; " << error); + throwDbusException(error); + } + GDBusInterfaceInfo* interfaceInfo = nodeInfo->interfaces[0]; + + GDBusInterfaceVTable vtable; + vtable.method_call = &DbusConnection::onMethodCall; + vtable.get_property = NULL; + vtable.set_property = NULL; + + g_dbus_connection_register_object(mConnection, + objectPath.c_str(), + interfaceInfo, + &vtable, + createCallbackWrapper(callback, mGuard.spawn()), + &deleteCallbackWrapper, + &error); + g_dbus_node_info_unref(nodeInfo); + if (error) { + error.strip(); + LOGE("Register object failed; " << error); + throwDbusException(error); + } +} + +void DbusConnection::onMethodCall(GDBusConnection*, + const gchar*, + const gchar* objectPath, + const gchar* interface, + const gchar* method, + GVariant* parameters, + GDBusMethodInvocation* invocation, + gpointer userData) +{ + const MethodCallCallback& callback = getCallbackFromPointer(userData); + + LOGD("MethodCall: " << objectPath << "; " << interface << "; " << method); + + MethodResultBuilder::Pointer resultBuilder(new MethodResultBuilderImpl(invocation)); + if (callback) { + callback(objectPath, interface, method, parameters, resultBuilder); + } +} + +GVariantPtr DbusConnection::callMethod(const std::string& busName, + const std::string& objectPath, + const std::string& interface, + const std::string& method, + GVariant* parameters, + const std::string& replyType, + int timeoutMs) +{ + ScopedGError error; + GVariant* result = g_dbus_connection_call_sync(mConnection, + busName.c_str(), + objectPath.c_str(), + interface.c_str(), + method.c_str(), + parameters, + replyType.empty() ? NULL + : G_VARIANT_TYPE(replyType.c_str()), + G_DBUS_CALL_FLAGS_NONE, + timeoutMs, + NULL, + &error); + if (error) { + error.strip(); + LOGE("Call method failed; " << error); + throwDbusException(error); + } + return GVariantPtr(result, g_variant_unref); +} + +void DbusConnection::callMethodAsync(const std::string& busName, + const std::string& objectPath, + const std::string& interface, + const std::string& method, + GVariant* parameters, + const std::string& replyType, + const AsyncMethodCallCallback& callback, + int timeoutMs) +{ + g_dbus_connection_call(mConnection, + busName.c_str(), + objectPath.c_str(), + interface.c_str(), + method.c_str(), + parameters, + replyType.empty() ? NULL + : G_VARIANT_TYPE(replyType.c_str()), + G_DBUS_CALL_FLAGS_NONE, + timeoutMs, + NULL, + &DbusConnection::onAsyncReady, + createCallbackWrapper(callback, mGuard.spawn())); +} + +void DbusConnection::onAsyncReady(GObject* source, + GAsyncResult* asyncResult, + gpointer userData) +{ + std::unique_ptr + autoDeleteCallback(userData, &deleteCallbackWrapper); + GDBusConnection* connection = reinterpret_cast(source); + const AsyncMethodCallCallback& callback = + getCallbackFromPointer(userData); + + ScopedGError error; + GVariant* result = g_dbus_connection_call_finish(connection, asyncResult, &error); + if (error) { + error.strip(); + LOGE("Call method failed; " << error); + } + AsyncMethodCallResultImpl asyncMethodCallResult(result, error); + if (callback) { + try { + callback(asyncMethodCallResult); + } catch (DbusException& e) { + // Drop dbus exceptions (thrown from asyncMethodCallResult.get()). + // We can not ignore other exceptions - they must be catched inside callback, + // otherwise std::terminate will be called. + LOGW("Uncaugth dbus exception: " << e.what()); + } + } +} + +} // namespace dbus diff --git a/common/dbus/connection.hpp b/common/dbus/connection.hpp new file mode 100644 index 0000000..6603c9d --- /dev/null +++ b/common/dbus/connection.hpp @@ -0,0 +1,211 @@ +/* + * 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 Dbus connection class + */ + +#ifndef COMMON_DBUS_CONNECTION_HPP +#define COMMON_DBUS_CONNECTION_HPP + +#include "utils/callback-guard.hpp" + +#include +#include +#include +#include + + +namespace dbus { + + +typedef std::unique_ptr GVariantPtr; + +/** + * An interface used to set a result to a method call. + */ +class MethodResultBuilder { +public: + typedef std::shared_ptr Pointer; + + virtual ~MethodResultBuilder() {} + virtual void set(GVariant* parameters) = 0; + virtual void setVoid() = 0; + virtual void setError(const std::string& name, const std::string& message) = 0; +}; + +/** + * An interface used to get result from async response. + */ +class AsyncMethodCallResult { +public: + virtual ~AsyncMethodCallResult() {} + virtual GVariant* get() = 0; // throws DbusException on error +}; + +/** + * Dbus connection. + * Provides a functionality that allows to call dbus methods, + * register dbus interfaces, etc. + * + * TODO divide to interface and implementation header + */ +class DbusConnection { +public: + typedef std::unique_ptr Pointer; + + typedef std::function VoidCallback; + + typedef std::function MethodCallCallback; + + typedef std::function SignalCallback; + + typedef std::function AsyncMethodCallCallback; + + typedef unsigned int SubscriptionId; + + /** + * Creates a connection to the dbus with given address. + */ + static Pointer create(const std::string& address); + + /** + * Creates a connection to the system dbus. + */ + static Pointer createSystem(); + + ~DbusConnection(); + + /** + * Sets a name to the dbus connection. + * It allows other client to call methods using this name. + */ + void setName(const std::string& name, + const VoidCallback& onNameAcquired, + const VoidCallback& onNameLost); + + /** + * Emits dbus signal. + */ + void emitSignal(const std::string& objectPath, + const std::string& interface, + const std::string& name, + GVariant* parameters); + + /** + * Subscribes to a signal. + * Empty sender means subscribe to all signals + * Returns a subscription identifier that can be used to unsubscribe signal + */ + SubscriptionId signalSubscribe(const SignalCallback& callback, const std::string& senderBusName); + + /** + * Unsubscribes from a signal. + */ + void signalUnsubscribe(SubscriptionId subscriptionId); + + /** + * Registers an object with given definition. + * Api calls will be handled by given callback. + */ + void registerObject(const std::string& objectPath, + const std::string& objectDefinitionXml, + const MethodCallCallback& callback); + + /** + * Call a dbus method + */ + GVariantPtr callMethod(const std::string& busName, + const std::string& objectPath, + const std::string& interface, + const std::string& method, + GVariant* parameters, + const std::string& replyType, + int timeoutMs = -1); + + /** + * Async call a dbus method + */ + void callMethodAsync(const std::string& busName, + const std::string& objectPath, + const std::string& interface, + const std::string& method, + GVariant* parameters, + const std::string& replyType, + const AsyncMethodCallCallback& callback, + int timeoutMs = -1); + + /** + * Returns an xml with meta description of specified dbus object. + */ + std::string introspect(const std::string& busName, const std::string& objectPath); + +private: + struct NameCallbacks { + VoidCallback nameAcquired; + VoidCallback nameLost; + + NameCallbacks(const VoidCallback& acquired, const VoidCallback& lost) + : nameAcquired(acquired), nameLost(lost) {} + }; + + vasum::utils::CallbackGuard mGuard; + GDBusConnection* mConnection; + guint mNameId; + + DbusConnection(const std::string& address); + + static void onNameAcquired(GDBusConnection* connection, const gchar* name, gpointer userData); + static void onNameLost(GDBusConnection* connection, const gchar* name, gpointer userData); + static void onSignal(GDBusConnection* connection, + const gchar* sender, + const gchar* object, + const gchar* interface, + const gchar* name, + GVariant* parameters, + gpointer userData); + static void onMethodCall(GDBusConnection* connection, + const gchar* sender, + const gchar* objectPath, + const gchar* interface, + const gchar* method, + GVariant* parameters, + GDBusMethodInvocation* invocation, + gpointer userData); + static void onAsyncReady(GObject* source, + GAsyncResult* asyncResult, + gpointer userData); +}; + + +} // namespace dbus + +#endif // COMMON_DBUS_CONNECTION_HPP diff --git a/common/dbus/exception.hpp b/common/dbus/exception.hpp new file mode 100644 index 0000000..a09bdbc --- /dev/null +++ b/common/dbus/exception.hpp @@ -0,0 +1,74 @@ +/* + * 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 Dbus exceptions + */ + +#ifndef COMMON_DBUS_EXCEPTION_HPP +#define COMMON_DBUS_EXCEPTION_HPP + +#include + +namespace dbus { + +/** + * Base class for dbus exceptions + */ +struct DbusException: public std::runtime_error { + + DbusException(const std::string& error = "") : std::runtime_error(error) {} +}; + +/** + * Dbus IO exception (connection failed, connection lost, etc) + */ +struct DbusIOException: public DbusException { + + DbusIOException(const std::string& error = "") : DbusException(error) {} +}; + +/** + * Dbus operation failed exception + */ +struct DbusOperationException: public DbusException { + + DbusOperationException(const std::string& error = "") : DbusException(error) {} +}; + +/** + * Dbus custom exception triggered by user logic + */ +struct DbusCustomException: public DbusException { + + DbusCustomException(const std::string& error = "") : DbusException(error) {} +}; + +/** + * Dbus invalid argument exception + */ +struct DbusInvalidArgumentException: public DbusException { + + DbusInvalidArgumentException(const std::string& error = "") : DbusException(error) {} +}; + +} // namespace dbus + +#endif // COMMON_DBUS_EXCEPTION_HPP diff --git a/common/ipc/client.hpp b/common/ipc/client.hpp index a3342b6..db15a4a 100644 --- a/common/ipc/client.hpp +++ b/common/ipc/client.hpp @@ -38,7 +38,7 @@ namespace ipc { /** * This class wraps communication via UX sockets for client applications. - * It uses serialization mechanism from libConfig. + * It uses serialization mechanism from Config. * * For message format @see ipc::Processor */ diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index dec16e8..84aaa5c 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -62,7 +62,7 @@ const unsigned int DEFAULT_MAX_NUMBER_OF_PEERS = 500; * This class wraps communication via UX sockets * * It's intended to be used both in Client and Service classes. -* It uses a serialization mechanism from libConfig. +* It uses a serialization mechanism from Config. * Library user will only have to pass the types that each call will send and receive * * Message format: diff --git a/common/ipc/service.hpp b/common/ipc/service.hpp index 880c137..32b604f 100644 --- a/common/ipc/service.hpp +++ b/common/ipc/service.hpp @@ -40,7 +40,7 @@ namespace ipc { /** * This class wraps communication via UX sockets. - * It uses serialization mechanism from libConfig. + * It uses serialization mechanism from Config. * * For message format @see ipc::Processor */ diff --git a/common/logger/backend-journal.cpp b/common/logger/backend-journal.cpp new file mode 100644 index 0000000..12c4eff --- /dev/null +++ b/common/logger/backend-journal.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Systemd journal backend for logger + */ + +#include "config.hpp" +#include "logger/backend-journal.hpp" + +#define SD_JOURNAL_SUPPRESS_LOCATION +#include + +namespace logger { + +namespace { + +inline int toJournalPriority(LogLevel logLevel) +{ + switch (logLevel) { + case LogLevel::ERROR: + return LOG_ERR; // 3 + case LogLevel::WARN: + return LOG_WARNING; // 4 + case LogLevel::INFO: + return LOG_INFO; // 6 + case LogLevel::DEBUG: + return LOG_DEBUG; // 7 + case LogLevel::TRACE: + return LOG_DEBUG; // 7 + case LogLevel::HELP: + return LOG_DEBUG; // 7 + default: + return LOG_DEBUG; // 7 + } +} + +} // namespace + +void SystemdJournalBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) +{ + sd_journal_send("PRIORITY=%d", toJournalPriority(logLevel), + "CODE_FILE=%s", file.c_str(), + "CODE_LINE=%d", line, + "CODE_FUNC=%s", func.c_str(), + "MESSAGE=%s", message.c_str(), + NULL); +} + +} // namespace logger diff --git a/common/logger/backend-journal.hpp b/common/logger/backend-journal.hpp new file mode 100644 index 0000000..e566ed1 --- /dev/null +++ b/common/logger/backend-journal.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Systemd journal backend for logger + */ + +#ifndef COMMON_LOGGER_BACKEND_JOURNAL_HPP +#define COMMON_LOGGER_BACKEND_JOURNAL_HPP + +#include "logger/backend.hpp" + +namespace logger { + +/** + * systemd journal logging backend + */ +class SystemdJournalBackend : public LogBackend { +public: + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; +}; + +} // namespace logger + +#endif // COMMON_LOGGER_BACKEND_JOURNAL_HPP diff --git a/common/logger/backend-null.hpp b/common/logger/backend-null.hpp new file mode 100644 index 0000000..4a7e8a9 --- /dev/null +++ b/common/logger/backend-null.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Pawel Broda + * + * 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 Pawel Broda (p.broda@partner.samsung.com) + * @brief Null backend for logger + */ + +#ifndef COMMON_LOGGER_BACKEND_NULL_HPP +#define COMMON_LOGGER_BACKEND_NULL_HPP + +#include "logger/backend.hpp" + +namespace logger { + +/** + * Null logging backend + */ +class NullLogger : public LogBackend { +public: + void log(LogLevel /*logLevel*/, + const std::string& /*file*/, + const unsigned int& /*line*/, + const std::string& /*func*/, + const std::string& /*message*/) override {} +}; + +} // namespace logger + +#endif // COMMON_LOGGER_BACKEND_NULL_HPP diff --git a/common/logger/backend-stderr.cpp b/common/logger/backend-stderr.cpp new file mode 100644 index 0000000..d4e36b1 --- /dev/null +++ b/common/logger/backend-stderr.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Pawel Broda + * + * 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 Pawel Broda (p.broda@partner.samsung.com) + * @brief Stderr backend for logger + */ + +#include "config.hpp" +#include "logger/backend-stderr.hpp" +#include "logger/formatter.hpp" + +#include + +namespace logger { + +void StderrBackend::log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) +{ + typedef boost::char_separator charSeparator; + typedef boost::tokenizer tokenizer; + + // example log string + // 06:52:35.123 [ERROR] src/util/fs.cpp:43 readFileContent: /file/file.txt is missing + + const std::string logColor = LogFormatter::getConsoleColor(logLevel); + const std::string defaultColor = LogFormatter::getDefaultConsoleColor(); + const std::string header = LogFormatter::getHeader(logLevel, file, line, func); + tokenizer tokens(message, charSeparator("\n")); + for (const auto& messageLine : tokens) { + if (!messageLine.empty()) { + fprintf(stderr, + "%s%s%s%s\n", + logColor.c_str(), + header.c_str(), + messageLine.c_str(), + defaultColor.c_str()); + } + } +} + +} // namespace logger diff --git a/common/logger/backend-stderr.hpp b/common/logger/backend-stderr.hpp new file mode 100644 index 0000000..4cdd0ec --- /dev/null +++ b/common/logger/backend-stderr.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Pawel Broda + * + * 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 Pawel Broda (p.broda@partner.samsung.com) + * @brief Stderr backend for logger + */ + +#ifndef COMMON_LOGGER_BACKEND_STDERR_HPP +#define COMMON_LOGGER_BACKEND_STDERR_HPP + +#include "logger/backend.hpp" + +namespace logger { + +/** + * Stderr logging backend + */ +class StderrBackend : public LogBackend { +public: + void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) override; +}; + +} // namespace logger + +#endif // COMMON_LOGGER_BACKEND_STDERR_HPP diff --git a/common/logger/backend.hpp b/common/logger/backend.hpp new file mode 100644 index 0000000..99b0c49 --- /dev/null +++ b/common/logger/backend.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Pawel Broda + * + * 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 Pawel Broda (p.broda@partner.samsung.com) + * @brief Logging backend + */ + +#ifndef COMMON_LOGGER_BACKEND_HPP +#define COMMON_LOGGER_BACKEND_HPP + +#include "logger/level.hpp" + +#include + +namespace logger { + +/** + * Abstract class for logger + */ +class LogBackend { +public: + virtual void log(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func, + const std::string& message) = 0; + virtual ~LogBackend() {} +}; + +} // namespace logger + +#endif // COMMON_LOGGER_BACKEND_HPP diff --git a/common/logger/ccolor.cpp b/common/logger/ccolor.cpp new file mode 100644 index 0000000..e5e71b0 --- /dev/null +++ b/common/logger/ccolor.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Console color for StderrBackend logger + */ + +#include "config.hpp" +#include "logger/ccolor.hpp" + +#include + +namespace logger { + +std::string getConsoleEscapeSequence(Attributes attr, Color color) +{ + char command[10]; + + // Command is the control command to the terminal + snprintf(command, sizeof(command), "%c[%d;%dm", 0x1B, attr, color); + return std::string(command); +} + +} // namespace logger diff --git a/common/logger/ccolor.hpp b/common/logger/ccolor.hpp new file mode 100644 index 0000000..47cc25e --- /dev/null +++ b/common/logger/ccolor.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Console color for StderrBackend logger + */ + +#ifndef COMMON_LOGGER_CCOLOR_HPP +#define COMMON_LOGGER_CCOLOR_HPP + +#include + +namespace logger { + +enum class Color : unsigned int { + DEFAULT = 0, + BLACK = 90, + RED = 91, + GREEN = 92, + YELLOW = 93, + BLUE = 94, + MAGENTA = 95, + CYAN = 96, + WHITE = 97 +}; + +enum class Attributes : unsigned int { + DEFAULT = 0, + BOLD = 1 +}; + +std::string getConsoleEscapeSequence(Attributes attr, Color color); + +} // namespace logger + +#endif // COMMON_LOGGER_CCOLOR_HPP diff --git a/common/logger/formatter.cpp b/common/logger/formatter.cpp new file mode 100644 index 0000000..529cd14 --- /dev/null +++ b/common/logger/formatter.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Helper formatter for logger + */ + +#include "config.hpp" +#include "logger/formatter.hpp" +#include "logger/ccolor.hpp" + +#include +#include +#include +#include +#include +#include + +namespace logger { + +namespace { + +const int TIME_COLUMN_LENGTH = 12; +const int SEVERITY_COLUMN_LENGTH = 8; +const int THREAD_COLUMN_LENGTH = 3; +const int FILE_COLUMN_LENGTH = 60; + +std::atomic gNextThreadId(1); +thread_local unsigned int gThisThreadId(0); + +} // namespace + +unsigned int LogFormatter::getCurrentThread(void) +{ + unsigned int id = gThisThreadId; + if (id == 0) { + gThisThreadId = id = gNextThreadId++; + } + + return id; +} + +std::string LogFormatter::getCurrentTime(void) +{ + char time[TIME_COLUMN_LENGTH + 1]; + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm* tm = localtime(&tv.tv_sec); + snprintf(time, + sizeof(time), + "%02d:%02d:%02d.%03d", + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + int(tv.tv_usec / 1000)); + + return std::string(time); +} + +std::string LogFormatter::getConsoleColor(LogLevel logLevel) +{ + switch (logLevel) { + case LogLevel::ERROR: + return getConsoleEscapeSequence(Attributes::BOLD, Color::RED); + case LogLevel::WARN: + return getConsoleEscapeSequence(Attributes::BOLD, Color::YELLOW); + case LogLevel::INFO: + return getConsoleEscapeSequence(Attributes::BOLD, Color::BLUE); + case LogLevel::DEBUG: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::GREEN); + case LogLevel::TRACE: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::BLACK); + case LogLevel::HELP: + return getConsoleEscapeSequence(Attributes::BOLD, Color::MAGENTA); + default: + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); + } +} + +std::string LogFormatter::getDefaultConsoleColor(void) +{ + return getConsoleEscapeSequence(Attributes::DEFAULT, Color::DEFAULT); +} + +std::string LogFormatter::stripProjectDir(const std::string& file, + const std::string& rootDir) +{ + // If rootdir is empty then return full name + if (rootDir.empty()) { + return file; + } + const std::string sourceDir = rootDir + "/"; + // If file does not belong to rootDir then also return full name + if (0 != file.compare(0, sourceDir.size(), sourceDir)) { + return file; + } + return file.substr(sourceDir.size()); +} + +std::string LogFormatter::getHeader(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func) +{ + std::ostringstream logLine; + logLine << getCurrentTime() << ' ' + << std::left << std::setw(SEVERITY_COLUMN_LENGTH) << '[' + toString(logLevel) + ']' + << std::right << std::setw(THREAD_COLUMN_LENGTH) << getCurrentThread() << ": " + << std::left << std::setw(FILE_COLUMN_LENGTH) + << file + ':' + std::to_string(line) + ' ' + func + ':'; + return logLine.str(); +} + +} // namespace logger diff --git a/common/logger/formatter.hpp b/common/logger/formatter.hpp new file mode 100644 index 0000000..3af0763 --- /dev/null +++ b/common/logger/formatter.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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 + */ + +/** + * @file + * @author Dariusz Michaluk (d.michaluk@samsung.com) + * @brief Helper formatter for logger + */ + +#ifndef COMMON_LOGGER_FORMATTER_HPP +#define COMMON_LOGGER_FORMATTER_HPP + +#include "logger/level.hpp" + +#include + +namespace logger { + +class LogFormatter { +public: + static unsigned int getCurrentThread(void); + static std::string getCurrentTime(void); + static std::string getConsoleColor(LogLevel logLevel); + static std::string getDefaultConsoleColor(void); + static std::string stripProjectDir(const std::string& file, + const std::string& rootDir); + static std::string getHeader(LogLevel logLevel, + const std::string& file, + const unsigned int& line, + const std::string& func); +}; + +} // namespace logger + +#endif // COMMON_LOGGER_FORMATTER_HPP diff --git a/common/logger/level.cpp b/common/logger/level.cpp new file mode 100644 index 0000000..bf46561 --- /dev/null +++ b/common/logger/level.cpp @@ -0,0 +1,71 @@ +/* + * 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 Functions to handle LogLevel + */ + +#include "config.hpp" +#include "logger/level.hpp" + +#include +#include + +namespace logger { + +LogLevel parseLogLevel(const std::string& level) +{ + if (boost::iequals(level, "ERROR")) { + return LogLevel::ERROR; + } else if (boost::iequals(level, "WARN")) { + return LogLevel::WARN; + } else if (boost::iequals(level, "INFO")) { + return LogLevel::INFO; + } else if (boost::iequals(level, "DEBUG")) { + return LogLevel::DEBUG; + } else if (boost::iequals(level, "TRACE")) { + return LogLevel::TRACE; + } else if (boost::iequals(level, "HELP")) { + return LogLevel::HELP; + } else { + throw std::runtime_error("Invalid LogLevel to parse"); + } +} + +std::string toString(const LogLevel logLevel) +{ + switch (logLevel) { + case LogLevel::ERROR: + return "ERROR"; + case LogLevel::WARN: + return "WARN"; + case LogLevel::INFO: + return "INFO"; + case LogLevel::DEBUG: + return "DEBUG"; + case LogLevel::TRACE: + return "TRACE"; + case LogLevel::HELP: + return "HELP"; + default: + return "UNKNOWN"; + } +} +} // namespace logger diff --git a/common/logger/level.hpp b/common/logger/level.hpp new file mode 100644 index 0000000..7902301 --- /dev/null +++ b/common/logger/level.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Dariusz Michaluk (d.michaluk@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 Dariusz Michaluk (d.michaluk@samsung.com) + * @brief LogLevel + */ + +#ifndef COMMON_LOGGER_LEVEL_HPP +#define COMMON_LOGGER_LEVEL_HPP + +#include + +namespace logger { + +enum class LogLevel { + TRACE, + DEBUG, + INFO, + WARN, + ERROR, + HELP +}; + +/** + * @param logLevel LogLevel + * @return std::sting representation of the LogLevel value + */ +std::string toString(const LogLevel logLevel); + +/** + * @param level string representation of log level + * @return parsed LogLevel value + */ +LogLevel parseLogLevel(const std::string& level); + +} // namespace logger + +#endif // COMMON_LOGGER_LEVEL_HPP diff --git a/common/logger/logger-scope.cpp b/common/logger/logger-scope.cpp new file mode 100644 index 0000000..e790bab --- /dev/null +++ b/common/logger/logger-scope.cpp @@ -0,0 +1,56 @@ +/* + * 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 Scope logger class implementation + */ + +#include "logger/logger-scope.hpp" +#include "logger/logger.hpp" + +namespace logger { + +SStreamWrapper::operator std::string() const +{ + return mSStream.str(); +} + +LoggerScope::LoggerScope(const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& message, + const std::string& rootDir): + mFile(file), + mLine(line), + mFunc(func), + mMessage(message), + mRootDir(rootDir) +{ + logger::Logger::logMessage(logger::LogLevel::TRACE, "Entering: " + mMessage, mFile, + mLine, mFunc, mRootDir); +} + +LoggerScope::~LoggerScope() +{ + logger::Logger::logMessage(logger::LogLevel::TRACE, "Leaving: " + mMessage, mFile, + mLine, mFunc, mRootDir); +} + +} // namespace logger diff --git a/common/logger/logger-scope.hpp b/common/logger/logger-scope.hpp new file mode 100644 index 0000000..cefd912 --- /dev/null +++ b/common/logger/logger-scope.hpp @@ -0,0 +1,78 @@ +/* + * 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 Scope logger class declaration + */ + +#ifndef COMMON_LOGGER_LOGGER_SCOPE_HPP +#define COMMON_LOGGER_LOGGER_SCOPE_HPP + +#include +#include + +namespace logger { + +class SStreamWrapper +{ +public: + operator std::string() const; + + template + SStreamWrapper& operator<<(const T& b) + { + this->mSStream << b; + return *this; + } + +private: + std::ostringstream mSStream; +}; + +/** + * Class specifically for scope debug logging. Should be used at the beggining of a scope. + * Constructor marks scope enterance, destructor marks scope leave. + */ +class LoggerScope +{ +public: + LoggerScope(const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& message, + const std::string& rootDir); + ~LoggerScope(); + +private: + const std::string mFile; + const unsigned int mLine; + const std::string mFunc; + const std::string mMessage; + const std::string mRootDir; +}; + +} // namespace logger + +// macro to automatically create LoggerScope object +#define LOGS(MSG) logger::LoggerScope logScopeObj(__FILE__, __LINE__, __func__, \ + logger::SStreamWrapper() << MSG, \ + PROJECT_SOURCE_DIR) + +#endif // COMMON_LOGGER_LOGGER_SCOPE_HPP diff --git a/common/logger/logger.cpp b/common/logger/logger.cpp new file mode 100644 index 0000000..aa2dccd --- /dev/null +++ b/common/logger/logger.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Pawel Broda + * + * 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 Pawel Broda (p.broda@partner.samsung.com) + * @brief Logger + */ + +#include "config.hpp" +#include "logger/logger.hpp" +#include "logger/formatter.hpp" +#include "logger/backend-null.hpp" + +#include +#include + +namespace logger { + +namespace { + +volatile LogLevel gLogLevel = LogLevel::DEBUG; +std::unique_ptr gLogBackendPtr(new NullLogger()); +std::mutex gLogMutex; + +} // namespace + +void Logger::logMessage(LogLevel logLevel, + const std::string& message, + const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& rootDir) +{ + std::string sfile = LogFormatter::stripProjectDir(file, rootDir); + std::unique_lock lock(gLogMutex); + gLogBackendPtr->log(logLevel, sfile, line, func, message); +} + +void Logger::setLogLevel(const LogLevel level) +{ + gLogLevel = level; +} + +void Logger::setLogLevel(const std::string& level) +{ + gLogLevel = parseLogLevel(level); +} + +LogLevel Logger::getLogLevel(void) +{ + return gLogLevel; +} + +void Logger::setLogBackend(LogBackend* pBackend) +{ + std::unique_lock lock(gLogMutex); + gLogBackendPtr.reset(pBackend); +} + +} // namespace logger diff --git a/common/logger/logger.hpp b/common/logger/logger.hpp new file mode 100644 index 0000000..8d8d433 --- /dev/null +++ b/common/logger/logger.hpp @@ -0,0 +1,79 @@ +/* + * 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 Logger + */ + +#ifndef COMMON_LOGGER_LOGGER_HPP +#define COMMON_LOGGER_LOGGER_HPP + +#include "logger/level.hpp" + +#include +#include + +#ifndef PROJECT_SOURCE_DIR +#define PROJECT_SOURCE_DIR "" +#endif + +namespace logger { + +class LogBackend; + +class Logger { +public: + static void logMessage(LogLevel logLevel, + const std::string& message, + const std::string& file, + const unsigned int line, + const std::string& func, + const std::string& rootDir); + + static void setLogLevel(const LogLevel level); + static void setLogLevel(const std::string& level); + static LogLevel getLogLevel(void); + static void setLogBackend(LogBackend* pBackend); +}; + +} // namespace logger + +#define LOG(SEVERITY, MESSAGE) \ + do { \ + if (logger::Logger::getLogLevel() <= logger::LogLevel::SEVERITY) { \ + std::ostringstream messageStream__; \ + messageStream__ << MESSAGE; \ + logger::Logger::logMessage(logger::LogLevel::SEVERITY, \ + messageStream__.str(), \ + __FILE__, \ + __LINE__, \ + __func__, \ + PROJECT_SOURCE_DIR); \ + } \ + } while (0) + +#define LOGE(MESSAGE) LOG(ERROR, MESSAGE) +#define LOGW(MESSAGE) LOG(WARN, MESSAGE) +#define LOGI(MESSAGE) LOG(INFO, MESSAGE) +#define LOGD(MESSAGE) LOG(DEBUG, MESSAGE) +#define LOGH(MESSAGE) LOG(HELP, MESSAGE) +#define LOGT(MESSAGE) LOG(TRACE, MESSAGE) + +#endif // COMMON_LOGGER_LOGGER_HPP diff --git a/common/netlink/netlink-message.hpp b/common/netlink/netlink-message.hpp index 971e6ad..3379009 100644 --- a/common/netlink/netlink-message.hpp +++ b/common/netlink/netlink-message.hpp @@ -31,6 +31,7 @@ #include #include #include +#include #include namespace vasum { diff --git a/common/utils/glib-utils.cpp b/common/utils/glib-utils.cpp new file mode 100644 index 0000000..93cbff9 --- /dev/null +++ b/common/utils/glib-utils.cpp @@ -0,0 +1,59 @@ +/* + * 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++ wrapper of glib main loop + */ + +#include "config.hpp" +#include "utils/glib-utils.hpp" +#include "utils/callback-wrapper.hpp" + +#include + +namespace vasum { +namespace utils { + +namespace { + +gboolean onIddle(gpointer data) +{ + const VoidCallback& callback = getCallbackFromPointer(data); + callback(); + return FALSE; +} + +} // namespace + +void executeInGlibThread(const VoidCallback& callback, const CallbackGuard& guard) +{ + if (!callback) { + return; + } + g_idle_add_full(G_PRIORITY_DEFAULT, + &onIddle, + utils::createCallbackWrapper(callback, guard.spawn()), + &utils::deleteCallbackWrapper); + +} + + +} // namespace utils +} // namespace vasum diff --git a/common/utils/glib-utils.hpp b/common/utils/glib-utils.hpp new file mode 100644 index 0000000..eaeeee8 --- /dev/null +++ b/common/utils/glib-utils.hpp @@ -0,0 +1,44 @@ +/* + * 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 Miscellaneous helpers for the Glib library + */ + +#ifndef COMMON_UTILS_GLIB_UTILS_HPP +#define COMMON_UTILS_GLIB_UTILS_HPP + +#include "utils/callback-guard.hpp" + +namespace vasum { +namespace utils { + +typedef std::function VoidCallback; + +/** + * Executes a callback in glib thread (adds an iddle event to glib) + */ +void executeInGlibThread(const VoidCallback& callback, const CallbackGuard& guard); + + +} // namespace utils +} // namespace vasum + +#endif // COMMON_UTILS_GLIB_UTILS_HPP diff --git a/packaging/vasum.spec b/packaging/vasum.spec index 6cea869..bd31d68 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -21,9 +21,6 @@ BuildRequires: boost-devel BuildRequires: libjson-devel >= 0.10 BuildRequires: libcap-ng-devel BuildRequires: lxc-devel -BuildRequires: pkgconfig(libConfig) -BuildRequires: pkgconfig(libLogger) -BuildRequires: pkgconfig(libSimpleDbus) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libsystemd-journal) BuildRequires: pkgconfig(libsystemd-daemon) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 79ced75..9470754 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -31,7 +31,7 @@ ADD_EXECUTABLE(${SERVER_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS program_options system filesystem regex) PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-journal libsystemd-daemon - libcap-ng libLogger libSimpleDbus libConfig) + libcap-ng sqlite3) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${CLIENT_FOLDER}) diff --git a/server/netdev.hpp b/server/netdev.hpp index b3c574d..eba9a01 100644 --- a/server/netdev.hpp +++ b/server/netdev.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 2a561ed..692ec4b 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -48,7 +48,7 @@ ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS}) FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-daemon - libsystemd-journal libcap-ng libLogger libSimpleDbus libConfig) + libsystemd-journal libcap-ng sqlite3) INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER} ${CLIENT_FOLDER} ${SOCKET_TEST_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) diff --git a/tests/unit_tests/socket_test_service/socket-test.cpp b/tests/unit_tests/socket_test_service/socket-test.cpp index 609bf87..2f163af 100644 --- a/tests/unit_tests/socket_test_service/socket-test.cpp +++ b/tests/unit_tests/socket_test_service/socket-test.cpp @@ -25,7 +25,7 @@ #include #include "socket-test.hpp" -#include +#include #include #include diff --git a/zone-daemon/CMakeLists.txt b/zone-daemon/CMakeLists.txt index 7baf37f..7e7bfba 100644 --- a/zone-daemon/CMakeLists.txt +++ b/zone-daemon/CMakeLists.txt @@ -20,9 +20,9 @@ MESSAGE(STATUS "") MESSAGE(STATUS "Generating makefile for the Zone Daemon...") FILE(GLOB project_SRCS *.cpp *.hpp) -FILE(GLOB common_SRCS ${COMMON_FOLDER}/dbus/*.cpp ${COMMON_FOLDER}/dbus/*.hpp - ${COMMON_FOLDER}/log/*.cpp ${COMMON_FOLDER}/log/*.hpp - ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp +FILE(GLOB common_SRCS ${COMMON_FOLDER}/dbus/*.cpp ${COMMON_FOLDER}/dbus/*.hpp + ${COMMON_FOLDER}/logger/*.cpp ${COMMON_FOLDER}/logger/*.hpp + ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp ${COMMON_FOLDER}/*.cpp) ## Setup target ################################################################ @@ -33,8 +33,8 @@ ADD_EXECUTABLE(${ZONE_DAEMON_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE (Boost COMPONENTS program_options system filesystem) -PKG_CHECK_MODULES(ZONE_DAEMON_DEPS REQUIRED gio-2.0 libsystemd-journal libcap-ng - libLogger libSimpleDbus libConfig) +PKG_CHECK_MODULES(ZONE_DAEMON_DEPS REQUIRED gio-2.0 libsystemd-journal libcap-ng) + INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${ZONE_DAEMON_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) -- 2.7.4 From 3de62e50aefd71c74eeb1cf1872699c7a759e7e0 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 22 Apr 2015 14:43:51 +0200 Subject: [PATCH 06/16] Prevent from inheriting fd by zones [Bug] Opened ipc socket are inherited by lxc proces [Cause] fork and exec copies fds [Solution] Set FD_CLOEXEC on ipc fd [Verification] N/A Change-Id: I1d2af18bbbab3be5df292770537a398ee7b47b53 --- common/ipc/internals/socket.cpp | 22 ++++++++++++++++++---- common/utils/signal.cpp | 6 +++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/common/ipc/internals/socket.cpp b/common/ipc/internals/socket.cpp index a66456e..3cdbf7c 100644 --- a/common/ipc/internals/socket.cpp +++ b/common/ipc/internals/socket.cpp @@ -44,6 +44,16 @@ namespace ipc { namespace { const int MAX_QUEUE_LENGTH = 1000; + +void setFdOptions(int fd) +{ + // Prevent from inheriting fd by zones + if (-1 == ::fcntl(fd, F_SETFD, FD_CLOEXEC)) { + LOGE("Error in fcntl: " + std::string(strerror(errno))); + throw IPCException("Error in fcntl: " + std::string(strerror(errno))); + } +} + } Socket::Socket(int socketFD) @@ -81,8 +91,9 @@ std::shared_ptr Socket::accept() int sockfd = ::accept(mFD, nullptr, nullptr); if (sockfd == -1) { LOGE("Error in accept: " << std::string(strerror(errno))); - IPCException("Error in accept: " + std::string(strerror(errno))); + throw IPCException("Error in accept: " + std::string(strerror(errno))); } + setFdOptions(sockfd); return std::make_shared(sockfd); } @@ -109,7 +120,8 @@ int Socket::getSystemdSocket(const std::string& path) for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) { - if (0 < ::sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, path.c_str(), 0)) { + if (0 < ::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0)) { + setFdOptions(fd); return fd; } } @@ -130,6 +142,7 @@ int Socket::createZoneSocket(const std::string& path) LOGE("Error in socket: " + std::string(strerror(errno))); throw IPCException("Error in socket: " + std::string(strerror(errno))); } + setFdOptions(sockfd); ::sockaddr_un serverAddress; serverAddress.sun_family = AF_UNIX; @@ -144,7 +157,7 @@ int Socket::createZoneSocket(const std::string& path) std::string message = strerror(errno); utils::close(sockfd); LOGE("Error in bind: " << message); - IPCException("Error in bind: " + message); + throw IPCException("Error in bind: " + message); } if (-1 == ::listen(sockfd, @@ -152,7 +165,7 @@ int Socket::createZoneSocket(const std::string& path) std::string message = strerror(errno); utils::close(sockfd); LOGE("Error in listen: " << message); - IPCException("Error in listen: " + message); + throw IPCException("Error in listen: " + message); } return sockfd; @@ -180,6 +193,7 @@ Socket Socket::connectSocket(const std::string& path) LOGE("Error in socket: " + std::string(strerror(errno))); throw IPCException("Error in socket: " + std::string(strerror(errno))); } + setFdOptions(fd); sockaddr_un serverAddress; serverAddress.sun_family = AF_UNIX; diff --git a/common/utils/signal.cpp b/common/utils/signal.cpp index 39e7fca..fdb571c 100644 --- a/common/utils/signal.cpp +++ b/common/utils/signal.cpp @@ -39,18 +39,18 @@ void signalBlock(const int signalToBlock) ::sigset_t set; if (-1 == ::sigemptyset(&set)) { LOGE("Error in sigemptyset: " << std::string(strerror(errno))); - UtilsException("Error in sigemptyset: " + std::string(strerror(errno))); + throw UtilsException("Error in sigemptyset: " + std::string(strerror(errno))); } if (-1 ==::sigaddset(&set, signalToBlock)) { LOGE("Error in sigaddset: " << std::string(strerror(errno))); - UtilsException("Error in sigaddset: " + std::string(strerror(errno))); + throw UtilsException("Error in sigaddset: " + std::string(strerror(errno))); } int ret = ::pthread_sigmask(SIG_BLOCK, &set, nullptr /*&oldSet*/); if (ret != 0) { LOGE("Error in pthread_sigmask: " << std::to_string(ret)); - UtilsException("Error in pthread_sigmask: " + std::to_string(ret)); + throw UtilsException("Error in pthread_sigmask: " + std::to_string(ret)); } } -- 2.7.4 From 679bf6112a48d0b064f55a57e9053c0ef22edfc3 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 22 Apr 2015 18:48:07 +0200 Subject: [PATCH 07/16] Fix doxygen comment [Bux] Can't compile with clang 3.6 [Cause] Bad format of doxygen comment [Solution] N/A [Verification] Compile with clang. Change-Id: I7dc296317bf8c380faf4ea27321f58cb477d6f33 --- common/config/kvstore.hpp | 2 +- common/config/manager.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/kvstore.hpp b/common/config/kvstore.hpp index 0717665..eaf568b 100644 --- a/common/config/kvstore.hpp +++ b/common/config/kvstore.hpp @@ -227,7 +227,7 @@ std::vector KVStore::getInternal(const std::string& key, std::vector*) * Uses '.' to connect the terms. * @param args components of the string * @tparam delim optional delimiter - * @tparam typename ... Args any type implementing str + * @tparam Args any type implementing str * @return string created from he args */ template diff --git a/common/config/manager.hpp b/common/config/manager.hpp index 0deb8d8..f3bac43 100644 --- a/common/config/manager.hpp +++ b/common/config/manager.hpp @@ -178,7 +178,7 @@ void saveToKVStore(const std::string& filename, const Config& config, const std: * Load the config from KVStore with defaults given in json * * @param kvfile path to the KVStore db - * @param jsonfile path to json file with defaults + * @param json path to json file with defaults * @param config visitable structure to save * @param kvConfigName name of the config inside the KVStore db */ -- 2.7.4 From f5632a71830b61ae81c2db084c9c44bf7b9f1864 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 22 Apr 2015 18:29:57 +0200 Subject: [PATCH 08/16] Prevent from server termination after SIGPIPE [Bug] Server killed after unexpected ipc client disconnect [Cause] Writing to a disconnected socket causes the SIGPIPE [Solution] Block signal [Verification] N/A Change-Id: I27d50be0279c87894acff74627b6385dff72b762 --- server/server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/server.cpp b/server/server.cpp index 2271f08..f64ea03 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -33,6 +33,7 @@ #include "utils/glib-loop.hpp" #include "utils/environment.hpp" #include "utils/fs.hpp" +#include "utils/signal.hpp" #include #include @@ -101,6 +102,7 @@ void Server::run(bool asRoot) signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); signal(SIGUSR1, signalHandler); + utils::signalBlock(SIGPIPE); LOGI("Starting daemon..."); { -- 2.7.4 From e781e8693f2a9ddb8bce6bd1479b3e657dbbf648 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 21 Apr 2015 13:28:19 +0200 Subject: [PATCH 09/16] Rename: DispalyOff to SwitchToDefault, ZoneDbusState to ZoneConnectionState (switch to IPC #4) [Feature] Rename: DispalyOff to SwitchToDefault, ZoneDbusState to ZoneConnectionState (with related types and variables) [Cause] Switching from Dbus to IPC [Solution] N/A [Verification] Build, install, run tests Change-Id: Ibc331cd05d0f4b5d62400f449efd996268b91456 --- client/host-dbus-connection.cpp | 10 +- client/host-dbus-connection.hpp | 6 +- client/host-ipc-connection.cpp | 12 +- client/host-ipc-connection.hpp | 6 +- client/vasum-client-impl.cpp | 8 +- client/vasum-client.h | 4 +- common/api/messages.hpp | 4 +- server/configs/templates/default.conf | 2 +- server/host-dbus-connection.cpp | 16 +- server/host-dbus-connection.hpp | 10 +- server/host-dbus-definitions.hpp | 12 +- server/host-ipc-connection.cpp | 12 +- server/host-ipc-connection.hpp | 4 +- server/host-ipc-definitions.hpp | 4 +- server/zone-config.hpp | 4 +- server/zone-connection.cpp | 8 +- server/zone-connection.hpp | 8 +- server/zone.cpp | 40 ++-- server/zone.hpp | 16 +- server/zones-manager.cpp | 26 +-- server/zones-manager.hpp | 9 +- .../ut-client/templates/console-dbus.conf.in | 2 +- tests/unit_tests/client/ut-client.cpp | 28 +-- .../configs/ut-server/templates/default.conf | 2 +- .../configs/ut-zone-admin/templates/buggy.conf | 2 +- .../configs/ut-zone-admin/templates/missing.conf | 2 +- .../ut-zone-admin/templates/test-no-shutdown.conf | 2 +- .../configs/ut-zone-admin/templates/test.conf | 2 +- .../server/configs/ut-zone/templates/buggy.conf | 2 +- .../configs/ut-zone/templates/test-dbus.conf.in | 2 +- .../server/configs/ut-zone/templates/test.conf | 2 +- .../templates/console-dbus.conf.in | 2 +- .../ut-zones-manager/templates/console.conf | 2 +- tests/unit_tests/server/ut-zone-connection.cpp | 12 +- tests/unit_tests/server/ut-zones-manager.cpp | 219 +++++++++++---------- 35 files changed, 251 insertions(+), 251 deletions(-) diff --git a/client/host-dbus-connection.cpp b/client/host-dbus-connection.cpp index 7e511fe..1f375a0 100644 --- a/client/host-dbus-connection.cpp +++ b/client/host-dbus-connection.cpp @@ -170,16 +170,16 @@ void HostDbusConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argI mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); } -void HostDbusConnection::callGetZoneDbuses(vasum::api::Dbuses& argOut) +void HostDbusConnection::callGetZoneConnections(vasum::api::Connections& argOut) { - mConnection.call(vasum::api::host::METHOD_GET_ZONE_DBUSES, argOut); + mConnection.call(vasum::api::host::METHOD_GET_ZONE_CONNECTIONS, argOut); } HostDbusConnection::SubscriptionId -HostDbusConnection::subscribeZoneDbusState(const ZoneDbusStateCallback& callback) +HostDbusConnection::subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback) { - return mConnection.signalSubscribe( - vasum::api::host::SIGNAL_ZONE_DBUS_STATE, callback); + return mConnection.signalSubscribe( + vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE, callback); } void HostDbusConnection::unsubscribe(const SubscriptionId& id) diff --git a/client/host-dbus-connection.hpp b/client/host-dbus-connection.hpp index c7cebdb..8785fa0 100644 --- a/client/host-dbus-connection.hpp +++ b/client/host-dbus-connection.hpp @@ -40,7 +40,7 @@ namespace client { class HostDbusConnection { public: typedef unsigned int SubscriptionId; - typedef std::function ZoneDbusStateCallback; + typedef std::function ZoneConnectionStateCallback; HostDbusConnection(); @@ -71,8 +71,8 @@ public: void callUnlockZone(const vasum::api::ZoneId& argIn); void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); - void callGetZoneDbuses(vasum::api::Dbuses& argOut); - SubscriptionId subscribeZoneDbusState(const ZoneDbusStateCallback& callback); + void callGetZoneConnections(vasum::api::Connections& argOut); + SubscriptionId subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback); void unsubscribe(const SubscriptionId& id); private: DbusConnection mConnection; diff --git a/client/host-ipc-connection.cpp b/client/host-ipc-connection.cpp index 6a22e6b..adb44eb 100644 --- a/client/host-ipc-connection.cpp +++ b/client/host-ipc-connection.cpp @@ -161,17 +161,17 @@ void HostIPCConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); } -void HostIPCConnection::callGetZoneDbuses(vasum::api::Dbuses& argOut) +void HostIPCConnection::callGetZoneConnections(vasum::api::Connections& argOut) { - mConnection.call(vasum::api::host::METHOD_GET_ZONE_DBUSES, argOut); + mConnection.call(vasum::api::host::METHOD_GET_ZONE_CONNECTIONS, argOut); } HostIPCConnection::SubscriptionId -HostIPCConnection::subscribeZoneDbusState(const ZoneDbusStateCallback& callback) +HostIPCConnection::subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback) { - mConnection.subscribe( - vasum::api::host::SIGNAL_ZONE_DBUS_STATE, callback); - return vasum::api::host::SIGNAL_ZONE_DBUS_STATE; + mConnection.subscribe( + vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE, callback); + return vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE; } void HostIPCConnection::unsubscribe(const SubscriptionId& id) diff --git a/client/host-ipc-connection.hpp b/client/host-ipc-connection.hpp index 83313e1..216e976 100644 --- a/client/host-ipc-connection.hpp +++ b/client/host-ipc-connection.hpp @@ -38,7 +38,7 @@ namespace client { class HostIPCConnection { public: typedef unsigned int SubscriptionId; - typedef std::function ZoneDbusStateCallback; + typedef std::function ZoneConnectionStateCallback; void createSystem(); void callGetZoneIds(vasum::api::ZoneIds& argOut); @@ -66,8 +66,8 @@ public: void callUnlockZone(const vasum::api::ZoneId& argIn); void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); - void callGetZoneDbuses(vasum::api::Dbuses& argOut); - SubscriptionId subscribeZoneDbusState(const ZoneDbusStateCallback& callback); + void callGetZoneConnections(vasum::api::Connections& argOut); + SubscriptionId subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback); void unsubscribe(const SubscriptionId& id); private: diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 2d85fb0..49b5846 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -258,8 +258,8 @@ VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* keys, VsmArrayString* valu assert(values); return coverException([&] { - api::Dbuses dbuses; - mHostClient.callGetZoneDbuses(dbuses); + api::Connections dbuses; + mHostClient.callGetZoneConnections(dbuses); convert(dbuses, *keys, *values); }); } @@ -397,7 +397,7 @@ VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback zoneDbusStateC assert(zoneDbusStateCallback); return coverException([&] { - auto onSigal = [=](const api::DbusState& dbus) + auto onSigal = [=](const api::ConnectionState& dbus) { zoneDbusStateCallback(dbus.first.c_str(), dbus.second.c_str(), @@ -405,7 +405,7 @@ VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback zoneDbusStateC }; VsmSubscriptionId id; - id = mHostClient.subscribeZoneDbusState(onSigal); + id = mHostClient.subscribeZoneConnectionState(onSigal); if (subscriptionId) { *subscriptionId = id; } diff --git a/client/vasum-client.h b/client/vasum-client.h index c252b32..50ed162 100644 --- a/client/vasum-client.h +++ b/client/vasum-client.h @@ -293,11 +293,11 @@ void vsm_netdev_free(VsmNetdev netdev); * Zone's D-Bus state change callback function signature. * * @param[in] zoneId affected zone id - * @param[in] dbusAddress new D-Bus address + * @param[in] address new D-Bus address * @param data custom user's data pointer passed to vsm_add_state_callback() function */ typedef void (*VsmZoneDbusStateCallback)(const char* zoneId, - const char* dbusAddress, + const char* address, void* data); /** diff --git a/common/api/messages.hpp b/common/api/messages.hpp index de606c0..ca4cab2 100644 --- a/common/api/messages.hpp +++ b/common/api/messages.hpp @@ -84,13 +84,13 @@ typedef api::StringPair RemoveDeclarationIn; typedef api::StringPair CreateZoneIn; typedef api::StringPair RevokeDeviceIn; typedef api::StringPair DestroyNetDevIn; -typedef api::StringPair DbusState; +typedef api::StringPair ConnectionState; typedef api::StringPair NotifActiveZoneIn; typedef api::StringPair FileMoveRequestIn; typedef api::VectorOfStrings ZoneIds; typedef api::VectorOfStrings Declarations; typedef api::VectorOfStrings NetDevList; -typedef api::VectorOfStringPairs Dbuses; +typedef api::VectorOfStringPairs Connections; typedef api::VectorOfStringPairs GetNetDevAttrs; struct ZoneInfoOut { diff --git a/server/configs/templates/default.conf b/server/configs/templates/default.conf index 697be47..3a99d20 100644 --- a/server/configs/templates/default.conf +++ b/server/configs/templates/default.conf @@ -10,7 +10,7 @@ "vt" : 0, "shutdownTimeout" : 10, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "runMountPoint" : "~NAME~/run", "provisions" : [], "permittedToSend" : [ "/tmp/.*" ], diff --git a/server/host-dbus-connection.cpp b/server/host-dbus-connection.cpp index b3eb19d..76f5bb8 100644 --- a/server/host-dbus-connection.cpp +++ b/server/host-dbus-connection.cpp @@ -112,9 +112,9 @@ void HostDbusConnection::setProxyCallCallback(const ProxyCallCallback& callback) mProxyCallCallback = callback; } -void HostDbusConnection::setGetZoneDbusesCallback(const GetZoneDbusesCallback& callback) +void HostDbusConnection::setGetZoneConnectionsCallback(const GetZoneConnectionsCallback& callback) { - mGetZoneDbusesCallback = callback; + mGetZoneConnectionsCallback = callback; } void HostDbusConnection::setGetZoneIdsCallback(const GetZoneIdsCallback& callback) @@ -264,10 +264,10 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_ZONE_DBUSES) { - if (mGetZoneDbusesCallback) { - auto rb = std::make_shared>(result); - mGetZoneDbusesCallback(rb); + if (methodName == api::host::METHOD_GET_ZONE_CONNECTIONS) { + if (mGetZoneConnectionsCallback) { + auto rb = std::make_shared>(result); + mGetZoneConnectionsCallback(rb); } return; } @@ -569,12 +569,12 @@ void HostDbusConnection::proxyCallAsync(const std::string& busName, callback); } -void HostDbusConnection::signalZoneDbusState(const api::DbusState& state) +void HostDbusConnection::signalZoneConnectionState(const api::ConnectionState& state) { GVariant* parameters = g_variant_new("(ss)", state.first.c_str(), state.second.c_str()); mDbusConnection->emitSignal(api::host::OBJECT_PATH, api::host::INTERFACE, - api::host::SIGNAL_ZONE_DBUS_STATE, + api::host::SIGNAL_ZONE_CONNECTION_STATE, parameters); } diff --git a/server/host-dbus-connection.hpp b/server/host-dbus-connection.hpp index 980b5e9..455437d 100644 --- a/server/host-dbus-connection.hpp +++ b/server/host-dbus-connection.hpp @@ -57,7 +57,7 @@ public: dbus::MethodResultBuilder::Pointer result )> ProxyCallCallback; typedef std::function GetZoneDbusesCallback; + )> GetZoneConnectionsCallback; typedef std::function GetZoneIdsCallback; typedef std::function" " " - " " - " " + " " + " " " " " " " " @@ -196,9 +196,9 @@ const std::string DEFINITION = " " " " " " - " " + " " " " - " " + " " " " " " ""; diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp index bb8d081..817e62f 100644 --- a/server/host-ipc-connection.cpp +++ b/server/host-ipc-connection.cpp @@ -52,11 +52,11 @@ HostIPCConnection::~HostIPCConnection() { } -void HostIPCConnection::setGetZoneDbusesCallback(const Callback::type& callback) +void HostIPCConnection::setGetZoneConnectionsCallback(const Callback::type& callback) { - typedef Callback Callback; + typedef Callback Callback; mService->setMethodHandler( - api::host::METHOD_GET_ZONE_DBUSES, + api::host::METHOD_GET_ZONE_CONNECTIONS, Callback::getCallbackWrapper(callback)); } @@ -263,10 +263,10 @@ void HostIPCConnection::setRevokeDeviceCallback(const Callbacksignal(api::host::SIGNAL_ZONE_DBUS_STATE, - std::make_shared(dbusState)); + mService->signal(api::host::SIGNAL_ZONE_CONNECTION_STATE, + std::make_shared(connectionState)); } } // namespace vasum diff --git a/server/host-ipc-connection.hpp b/server/host-ipc-connection.hpp index e8c1c8d..61c8f4a 100644 --- a/server/host-ipc-connection.hpp +++ b/server/host-ipc-connection.hpp @@ -81,7 +81,7 @@ public: HostIPCConnection(); ~HostIPCConnection(); - void setGetZoneDbusesCallback(const Callback::type& callback); + void setGetZoneConnectionsCallback(const Callback::type& callback); void setGetZoneIdsCallback(const Callback::type& callback); void setGetActiveZoneIdCallback(const Callback::type& callback); void setGetZoneInfoCallback(const Callback::type& callback); @@ -107,7 +107,7 @@ public: void setUnlockZoneCallback(const Callback::type& callback); void setGrantDeviceCallback(const Callback::type& callback); void setRevokeDeviceCallback(const Callback::type& callback); - void signalZoneDbusState(const api::DbusState& dbusState); + void signalZoneConnectionState(const api::ConnectionState& connectionState); private: epoll::ThreadDispatcher mDispatcher; diff --git a/server/host-ipc-definitions.hpp b/server/host-ipc-definitions.hpp index 4cd06e7..b1fca09 100644 --- a/server/host-ipc-definitions.hpp +++ b/server/host-ipc-definitions.hpp @@ -31,7 +31,7 @@ namespace vasum { namespace api { namespace host { -const vasum::ipc::MethodID METHOD_GET_ZONE_DBUSES = 1; +const vasum::ipc::MethodID METHOD_GET_ZONE_CONNECTIONS = 1; const vasum::ipc::MethodID METHOD_GET_ZONE_ID_LIST = 2; const vasum::ipc::MethodID METHOD_GET_ACTIVE_ZONE_ID = 3; const vasum::ipc::MethodID METHOD_GET_ZONE_INFO = 4; @@ -58,7 +58,7 @@ const vasum::ipc::MethodID METHOD_UNLOCK_ZONE = 24; const vasum::ipc::MethodID METHOD_GRANT_DEVICE = 25; const vasum::ipc::MethodID METHOD_REVOKE_DEVICE = 26; -const vasum::ipc::MethodID SIGNAL_ZONE_DBUS_STATE = 27; +const vasum::ipc::MethodID SIGNAL_ZONE_CONNECTION_STATE = 27; } // namespace host } // namespace api diff --git a/server/zone-config.hpp b/server/zone-config.hpp index 8d92800..67b5f93 100644 --- a/server/zone-config.hpp +++ b/server/zone-config.hpp @@ -63,7 +63,7 @@ struct ZoneConfig { * Specify, if D-Bus communication with the zone will be enabled. * Setting this value to "false" will make the zone API not work inside the zone. */ - bool enableDbusIntegration; + bool enableZoneConnection; /** * Zone's CFS quota in us when it's in the foreground @@ -106,7 +106,7 @@ struct ZoneConfig { initWithArgs, privilege, // TODO not needed? switchToDefaultAfterTimeout, // TODO move to dynamic and add an API to change - enableDbusIntegration, + enableZoneConnection, cpuQuotaForeground, cpuQuotaBackground, permittedToSend, // TODO move to dynamic and add an API to change diff --git a/server/zone-connection.cpp b/server/zone-connection.cpp index a86886c..56aa547 100644 --- a/server/zone-connection.cpp +++ b/server/zone-connection.cpp @@ -137,9 +137,9 @@ void ZoneConnection::setNotifyActiveZoneCallback( mNotifyActiveZoneCallback = callback; } -void ZoneConnection::setDisplayOffCallback(const DisplayOffCallback& callback) +void ZoneConnection::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) { - mDisplayOffCallback = callback; + mSwitchToDefaultCallback = callback; } void ZoneConnection::setFileMoveCallback( @@ -223,8 +223,8 @@ void ZoneConnection::onSignalReceived(const std::string& senderBusName, if (objectPath == fake_power_manager_api::OBJECT_PATH && interface == fake_power_manager_api::INTERFACE) { //power-manager sent us a signal, check it - if (signalName == fake_power_manager_api::SIGNAL_DISPLAY_OFF && mDisplayOffCallback) { - mDisplayOffCallback(); + if (signalName == fake_power_manager_api::SIGNAL_DISPLAY_OFF && mSwitchToDefaultCallback) { + mSwitchToDefaultCallback(); } } } diff --git a/server/zone-connection.hpp b/server/zone-connection.hpp index 8f025b0..441f645 100644 --- a/server/zone-connection.hpp +++ b/server/zone-connection.hpp @@ -39,7 +39,7 @@ class ZoneConnection { public: typedef std::function OnNameLostCallback; - typedef std::function DisplayOffCallback; + typedef std::function SwitchToDefaultCallback; ZoneConnection(const std::string& address, const OnNameLostCallback& callback); ~ZoneConnection(); @@ -71,9 +71,9 @@ public: void setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback); /** - * Register callback to handle turning off the display + * Register switch to default request callback */ - void setDisplayOffCallback(const DisplayOffCallback& callback); + void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); /* * Register file move request callback @@ -110,7 +110,7 @@ private: bool mNameLost; OnNameLostCallback mOnNameLostCallback; NotifyActiveZoneCallback mNotifyActiveZoneCallback; - DisplayOffCallback mDisplayOffCallback; + SwitchToDefaultCallback mSwitchToDefaultCallback; FileMoveCallback mFileMoveCallback; ProxyCallCallback mProxyCallCallback; diff --git a/server/zone.cpp b/server/zone.cpp index e26da52..2e47f25 100644 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -164,12 +164,12 @@ void Zone::start() Lock lock(mReconnectMutex); updateRequestedState(STATE_RUNNING); mProvision->start(); - if (mConfig.enableDbusIntegration) { + if (mConfig.enableZoneConnection) { mConnectionTransport.reset(new ZoneConnectionTransport(mRunMountPoint)); } mAdmin->start(); - if (mConfig.enableDbusIntegration) { + if (mConfig.enableZoneConnection) { // Increase cpu quota before connect, otherwise it'd take ages. goForeground(); connect(); @@ -196,14 +196,14 @@ void Zone::stop(bool saveState) void Zone::connect() { // assume called under reconnect lock - mDbusAddress = mConnectionTransport->acquireAddress(); - mConnection.reset(new ZoneConnection(mDbusAddress, - std::bind(&Zone::onNameLostCallback, this))); + mConnectionAddress = mConnectionTransport->acquireAddress(); + mConnection.reset(new ZoneConnection(mConnectionAddress, + std::bind(&Zone::onNameLostCallback, this))); if (mNotifyCallback) { mConnection->setNotifyActiveZoneCallback(mNotifyCallback); } - if (mDisplayOffCallback) { - mConnection->setDisplayOffCallback(mDisplayOffCallback); + if (mSwitchToDefaultCallback) { + mConnection->setSwitchToDefaultCallback(mSwitchToDefaultCallback); } if (mFileMoveCallback) { mConnection->setFileMoveCallback(mFileMoveCallback); @@ -211,8 +211,8 @@ void Zone::connect() if (mProxyCallCallback) { mConnection->setProxyCallCallback(mProxyCallCallback); } - if (mDbusStateChangedCallback) { - mDbusStateChangedCallback(mDbusAddress); + if (mConnectionStateChangedCallback) { + mConnectionStateChangedCallback(mConnectionAddress); } } @@ -221,18 +221,18 @@ void Zone::disconnect() // assume called under reconnect lock if (mConnection) { mConnection.reset(); - mDbusAddress.clear(); - if (mDbusStateChangedCallback) { - // notify about invalid dbusAddress for this zone - mDbusStateChangedCallback(std::string()); + mConnectionAddress.clear(); + if (mConnectionStateChangedCallback) { + // notify about invalid address for this zone + mConnectionStateChangedCallback(std::string()); } } } -std::string Zone::getDbusAddress() const +std::string Zone::getConnectionAddress() const { Lock lock(mReconnectMutex); - return mDbusAddress; + return mConnectionAddress; } int Zone::getVT() const @@ -407,13 +407,13 @@ void Zone::sendNotification(const std::string& zone, } } -void Zone::setDisplayOffCallback(const DisplayOffCallback& callback) +void Zone::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) { Lock lock(mReconnectMutex); - mDisplayOffCallback = callback; + mSwitchToDefaultCallback = callback; if (mConnection) { - mConnection->setDisplayOffCallback(callback); + mConnection->setSwitchToDefaultCallback(callback); } } @@ -437,9 +437,9 @@ void Zone::setProxyCallCallback(const ProxyCallCallback& callback) } } -void Zone::setDbusStateChangedCallback(const DbusStateChangedCallback& callback) +void Zone::setConnectionStateChangedCallback(const ConnectionStateChangedCallback& callback) { - mDbusStateChangedCallback = callback; + mConnectionStateChangedCallback = callback; } void Zone::proxyCallAsync(const std::string& busName, diff --git a/server/zone.hpp b/server/zone.hpp index 687077f..e7e929a 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -66,11 +66,11 @@ public: ~Zone(); typedef ZoneConnection::NotifyActiveZoneCallback NotifyActiveZoneCallback; - typedef ZoneConnection::DisplayOffCallback DisplayOffCallback; + typedef ZoneConnection::SwitchToDefaultCallback SwitchToDefaultCallback; typedef ZoneConnection::FileMoveCallback FileMoveCallback; typedef ZoneConnection::ProxyCallCallback ProxyCallCallback; - typedef std::function DbusStateChangedCallback; + typedef std::function ConnectionStateChangedCallback; typedef std::function StartAsyncResultCallback; /** @@ -189,7 +189,7 @@ public: /** * Register callback used when switching to default zone. */ - void setDisplayOffCallback(const DisplayOffCallback& callback); + void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); /** * Register proxy call callback @@ -215,7 +215,7 @@ public: /** * Register dbus state changed callback */ - void setDbusStateChangedCallback(const DbusStateChangedCallback& callback); + void setConnectionStateChangedCallback(const ConnectionStateChangedCallback& callback); /** * Make a proxy call @@ -230,7 +230,7 @@ public: /** * Get a dbus address */ - std::string getDbusAddress() const; + std::string getConnectionAddress() const; /** * Get id of VT @@ -328,11 +328,11 @@ private: std::unique_ptr mProvision; mutable std::recursive_mutex mReconnectMutex; NotifyActiveZoneCallback mNotifyCallback; - DisplayOffCallback mDisplayOffCallback; + SwitchToDefaultCallback mSwitchToDefaultCallback; FileMoveCallback mFileMoveCallback; ProxyCallCallback mProxyCallCallback; - DbusStateChangedCallback mDbusStateChangedCallback; - std::string mDbusAddress; + ConnectionStateChangedCallback mConnectionStateChangedCallback; + std::string mConnectionAddress; std::string mRunMountPoint; std::string mRootPath; std::string mDbPath; diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 11589bd..1b6edf3 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -132,8 +132,8 @@ ZonesManager::ZonesManager(const std::string& configPath) this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); #endif - mHostConnection.setGetZoneDbusesCallback(bind(&ZonesManager::handleGetZoneDbusesCall, - this, _1)); + mHostConnection.setGetZoneConnectionsCallback(bind(&ZonesManager::handleGetZoneConnectionsCall, + this, _1)); mHostConnection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall, this, _1)); @@ -319,7 +319,7 @@ void ZonesManager::insertZone(const std::string& zoneId, const std::string& zone zone->setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, this, zoneId, _1, _2, _3)); - zone->setDisplayOffCallback(bind(&ZonesManager::handleDisplayOffCall, + zone->setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, this, zoneId)); zone->setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, @@ -328,8 +328,8 @@ void ZonesManager::insertZone(const std::string& zoneId, const std::string& zone zone->setProxyCallCallback(bind(&ZonesManager::handleProxyCall, this, zoneId, _1, _2, _3, _4, _5, _6, _7)); - zone->setDbusStateChangedCallback(bind(&ZonesManager::handleDbusStateChanged, - this, zoneId, _1)); + zone->setConnectionStateChangedCallback(bind(&ZonesManager::handleConnectionStateChanged, + this, zoneId, _1)); mZones.push_back(std::move(zone)); @@ -578,7 +578,7 @@ void ZonesManager::handleNotifyActiveZoneCall(const std::string& caller, } } -void ZonesManager::handleDisplayOffCall(const std::string& /*caller*/) +void ZonesManager::handleSwitchToDefaultCall(const std::string& /*caller*/) { // get config of currently set zone and switch if switchToDefaultAfterTimeout is true Lock lock(mMutex); @@ -750,21 +750,21 @@ void ZonesManager::handleProxyCall(const std::string& caller, asyncResultCallback); } -void ZonesManager::handleGetZoneDbusesCall(api::MethodResultBuilder::Pointer result) +void ZonesManager::handleGetZoneConnectionsCall(api::MethodResultBuilder::Pointer result) { Lock lock(mMutex); - auto dbuses = std::make_shared(); + auto connections = std::make_shared(); for (auto& zone : mZones) { - dbuses->values.push_back({zone->getId(), zone->getDbusAddress()}); + connections->values.push_back({zone->getId(), zone->getConnectionAddress()}); } - result->set(dbuses); + result->set(connections); } -void ZonesManager::handleDbusStateChanged(const std::string& zoneId , - const std::string& dbusAddress) +void ZonesManager::handleConnectionStateChanged(const std::string& zoneId , + const std::string& address) { - mHostConnection.signalZoneDbusState({zoneId, dbusAddress}); + mHostConnection.signalZoneConnectionState({zoneId, address}); } void ZonesManager::handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result) diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 84285f3..31c90cd 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -160,7 +160,7 @@ private: const std::string& appliaction, const std::string& message, api::MethodResultBuilder::Pointer result); - void handleDisplayOffCall(const std::string& caller); + void handleSwitchToDefaultCall(const std::string& caller); void handleFileMoveCall(const std::string& srcZoneId, const std::string& dstZoneId, const std::string& path, @@ -173,10 +173,9 @@ private: const std::string& targetMethod, GVariant* parameters, dbus::MethodResultBuilder::Pointer result); - void handleGetZoneDbusesCall(api::MethodResultBuilder::Pointer result); - - void handleDbusStateChanged(const std::string& zoneId, - const std::string& dbusAddress); + void handleGetZoneConnectionsCall(api::MethodResultBuilder::Pointer result); + void handleConnectionStateChanged(const std::string& zoneId, + const std::string& address); // Host's handlers -------------------------------------------------------- void handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result); void handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer result); diff --git a/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in index 7df03e4..3481c09 100644 --- a/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in +++ b/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in @@ -7,7 +7,7 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : true, + "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 40372f4..d53238f 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -88,7 +88,7 @@ struct Fixture { }; const int EVENT_TIMEOUT = 5000; ///< ms -const std::map EXPECTED_DBUSES_STARTED = { +const std::map EXPECTED_CONNECTIONS = { { "zone1", "unix:path=/tmp/ut-run/zone1/dbus/system_bus_socket" @@ -157,12 +157,12 @@ BOOST_AUTO_TEST_CASE(NotRunningServer) VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect_custom(client, - EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + EXPECTED_CONNECTIONS.begin()->second.c_str()); BOOST_CHECK_EQUAL(VSMCLIENT_IO_ERROR, status); vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(GetZoneDbuses) +BOOST_AUTO_TEST_CASE(GetZoneConnections) { VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); @@ -172,14 +172,14 @@ BOOST_AUTO_TEST_CASE(GetZoneDbuses) //TODO: Clean up if BOOST_REQUIRE_EQUAL fail (remove client). Same in other client tests. BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_DBUSES_STARTED.size() + 1u), - EXPECTED_DBUSES_STARTED.size()); - BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1u), - EXPECTED_DBUSES_STARTED.size()); + BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_CONNECTIONS.size() + 1u), + EXPECTED_CONNECTIONS.size()); + BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_CONNECTIONS.size() + 1u), + EXPECTED_CONNECTIONS.size()); std::map zones; convertDictToMap(keys, values, zones); - BOOST_CHECK(zones == EXPECTED_DBUSES_STARTED); + BOOST_CHECK(zones == EXPECTED_CONNECTIONS); vsm_array_string_free(keys); vsm_array_string_free(values); vsm_client_free(client); @@ -193,14 +193,14 @@ BOOST_AUTO_TEST_CASE(GetZoneIds) VsmArrayString values; status = vsm_get_zone_ids(client, &values); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1u), - EXPECTED_DBUSES_STARTED.size()); + BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_CONNECTIONS.size() + 1u), + EXPECTED_CONNECTIONS.size()); std::set zones; convertArrayToSet(values, zones); for (const auto& zone : zones) { - BOOST_CHECK(EXPECTED_DBUSES_STARTED.find(zone) != EXPECTED_DBUSES_STARTED.cend()); + BOOST_CHECK(EXPECTED_CONNECTIONS.find(zone) != EXPECTED_CONNECTIONS.cend()); } vsm_array_string_free(values); vsm_client_free(client); @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(FileMoveRequest) const std::string secondZone = "fake_zone"; VsmClient client = vsm_client_create(); - VsmStatus status = vsm_connect_custom(client, EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + VsmStatus status = vsm_connect_custom(client, EXPECTED_CONNECTIONS.begin()->second.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); status = vsm_file_move_request(client, secondZone.c_str(), path.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_CUSTOM_ERROR, status); @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(Notification) CallbackData callbackData; std::map clients; - for (const auto& it : EXPECTED_DBUSES_STARTED) { + for (const auto& it : EXPECTED_CONNECTIONS) { VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect_custom(client, it.second.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); @@ -398,7 +398,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIdByPidTestMultiple) BOOST_CHECK(ids.count("host") == 1); - for (const auto& dbus : EXPECTED_DBUSES_STARTED) { + for (const auto& dbus : EXPECTED_CONNECTIONS) { BOOST_CHECK(ids.count(dbus.first) == 1); } } diff --git a/tests/unit_tests/server/configs/ut-server/templates/default.conf b/tests/unit_tests/server/configs/ut-server/templates/default.conf index b637d72..d07ecc6 100644 --- a/tests/unit_tests/server/configs/ut-server/templates/default.conf +++ b/tests/unit_tests/server/configs/ut-server/templates/default.conf @@ -7,7 +7,7 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf index c40ab33..c3b07fe 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf index 99e893d..7e20d62 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf index 363c7df..4aa7bd2 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf index df787df..5083c0e 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf b/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf index 91a9f7f..1e71ece 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in b/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in index 7d71f2d..da02e3b 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : true, + "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone/templates/test.conf b/tests/unit_tests/server/configs/ut-zone/templates/test.conf index a58f932..7827fe3 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/test.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/test.conf @@ -7,7 +7,7 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in index 7df03e4..3481c09 100644 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in @@ -7,7 +7,7 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : true, + "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf b/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf index 5d5509b..d9f69ec 100644 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf +++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf @@ -7,7 +7,7 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableDbusIntegration" : false, + "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/ut-zone-connection.cpp b/tests/unit_tests/server/ut-zone-connection.cpp index 5f2c63b..c374c81 100644 --- a/tests/unit_tests/server/ut-zone-connection.cpp +++ b/tests/unit_tests/server/ut-zone-connection.cpp @@ -196,18 +196,18 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApi) BOOST_CHECK(signalEmitted.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(SignalDisplayOffApi) +BOOST_AUTO_TEST_CASE(SignalSwitchToDefaultApi) { - Latch displayOffCalled; + Latch switchToDefaultCalled; ZoneConnection connection(acquireAddress(), nullptr); DbusConnection::Pointer client = DbusConnection::create(acquireAddress()); auto callback = [&]() { - displayOffCalled.set(); + switchToDefaultCalled.set(); }; - connection.setDisplayOffCallback(callback); + connection.setSwitchToDefaultCallback(callback); client->emitSignal(fake_power_manager_api::OBJECT_PATH, fake_power_manager_api::INTERFACE, @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(SignalDisplayOffApi) nullptr); // timeout should occur, since no name is set to client - BOOST_CHECK(!displayOffCalled.wait(EVENT_TIMEOUT)); + BOOST_CHECK(!switchToDefaultCalled.wait(EVENT_TIMEOUT)); DbusNameSetter setter; @@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(SignalDisplayOffApi) nullptr); // now signal should be delivered correctly - BOOST_CHECK(displayOffCalled.wait(EVENT_TIMEOUT)); + BOOST_CHECK(switchToDefaultCalled.wait(EVENT_TIMEOUT)); } diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp index 12a3dbe..5a9693f 100644 --- a/tests/unit_tests/server/ut-zones-manager.cpp +++ b/tests/unit_tests/server/ut-zones-manager.cpp @@ -82,7 +82,7 @@ const std::string FILE_CONTENT = "File content\n" const std::string NON_EXISTANT_ZONE_ID = "NON_EXISTANT_ZONE_ID"; const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf const std::string SIMPLE_TEMPLATE = "console"; -const std::string DBUS_TEMPLATE = "console-dbus"; +const std::string ZONE_ACCESS_TEMPLATE = "console-dbus"; #ifdef DBUS_CONNECTION /** @@ -110,9 +110,9 @@ public: )> TestApiMethodCallback; typedef std::function VoidResultCallback; typedef std::function SignalCallback; + const std::string& address)> SignalCallback; - typedef std::map Dbuses; + typedef std::map Connections; DbusAccessory() : mId(0), @@ -168,7 +168,7 @@ public: mClient->signalSubscribe(callback, isHost() ? api::host::BUS_NAME : api::zone::BUS_NAME); } - void subscribeZoneDbusState(const SignalCallback& callback) { + void subscribeZoneConnectionState(const SignalCallback& callback) { assert(isHost()); auto onSignal = [callback] (const std::string& /*senderBusName*/, const std::string& objectPath, @@ -177,12 +177,12 @@ public: GVariant* parameters) { if (objectPath == api::host::OBJECT_PATH && interface == api::host::INTERFACE && - signalName == api::host::SIGNAL_ZONE_DBUS_STATE) { + signalName == api::host::SIGNAL_ZONE_CONNECTION_STATE) { const gchar* zoneId = NULL; - const gchar* dbusAddress = NULL; - g_variant_get(parameters, "(&s&s)", &zoneId, &dbusAddress); - callback(zoneId, dbusAddress); + const gchar* address = NULL; + g_variant_get(parameters, "(&s&s)", &zoneId, &address); + callback(zoneId, address); } }; mClient->signalSubscribe(onSignal, api::host::BUS_NAME); @@ -285,14 +285,14 @@ public: return GVariantPtr(unpackedResult, g_variant_unref); } - Dbuses callMethodGetZoneDbuses() + Connections callMethodGetZoneConnections() { assert(isHost()); - Dbuses dbuses; + Connections connections; GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, api::host::OBJECT_PATH, api::host::INTERFACE, - api::host::METHOD_GET_ZONE_DBUSES, + api::host::METHOD_GET_ZONE_CONNECTIONS, NULL, "(a(ss))"); GVariant* array = NULL; @@ -301,11 +301,11 @@ public: size_t count = g_variant_n_children(array); for (size_t n = 0; n < count; ++n) { const char* zoneId = NULL; - const char* dbusAddress = NULL; - g_variant_get_child(array, n, "(&s&s)", &zoneId, &dbusAddress); - dbuses.insert(Dbuses::value_type(zoneId, dbusAddress)); + const char* address = NULL; + g_variant_get_child(array, n, "(&s&s)", &zoneId, &address); + connections.insert(Connections::value_type(zoneId, address)); } - return dbuses; + return connections; } std::vector callMethodGetZoneIds() @@ -502,9 +502,9 @@ public: )> TestApiMethodCallback; typedef std::function VoidResultCallback; typedef std::function SignalCallback; + const std::string& address)> SignalCallback; - typedef std::map Dbuses; + typedef std::map Connections; HostIPCAccessory() : mClient(mDispatcher.getPoll(), HOST_IPC_SOCKET) @@ -512,23 +512,24 @@ public: mClient.start(); } - void subscribeZoneDbusState(const SignalCallback& callback) + void subscribeZoneConnectionState(const SignalCallback& callback) { - auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { + auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { callback(data->first, data->second); }; - mClient.setSignalHandler(api::host::SIGNAL_ZONE_DBUS_STATE, callbackWrapper); + mClient.setSignalHandler(api::host::SIGNAL_ZONE_CONNECTION_STATE, + callbackWrapper); } - Dbuses callMethodGetZoneDbuses() + Connections callMethodGetZoneConnections() { - const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_DBUSES, - std::make_shared()); - Dbuses dbuses; + const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_CONNECTIONS, + std::make_shared()); + Connections connections; for (const auto& dbus : out->values) { - dbuses.insert(Dbuses::value_type(dbus.first, dbus.second)); + connections.insert(Connections::value_type(dbus.first, dbus.second)); } - return dbuses; + return connections; } std::vector callMethodGetZoneIds() @@ -629,7 +630,7 @@ public: MethodResultBuilder::Pointer result )> TestApiMethodCallback; - typedef std::map Dbuses; + typedef std::map Connections; ZoneDbusAccessory(int id) : mId(id), @@ -891,17 +892,17 @@ BOOST_AUTO_TEST_CASE(Focus) BOOST_AUTO_TEST_CASE(NotifyActiveZone) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); Latch signalReceivedLatch; std::map> signalReceivedSourcesMap; - std::map> dbuses; + std::map> connections; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); + connections[i] = std::unique_ptr(new ZoneAccessory(i)); } auto handler = [](Latch& latch, @@ -930,16 +931,16 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) using namespace std::placeholders; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - dbuses[i]->signalSubscribe(std::bind(handler, + connections[i]->signalSubscribe(std::bind(handler, std::ref(signalReceivedLatch), std::ref(signalReceivedSourcesMap[i]), _1, _2, _3, _4, _5)); } - for (auto& dbus : dbuses) { + for (auto& dbus : connections) { dbus.second->callMethodNotify(); } - BOOST_REQUIRE(signalReceivedLatch.waitForN(dbuses.size() - 1u, EVENT_TIMEOUT)); + BOOST_REQUIRE(signalReceivedLatch.waitForN(connections.size() - 1u, EVENT_TIMEOUT)); BOOST_REQUIRE(signalReceivedLatch.empty()); //check if there are no signals that was received more than once @@ -949,21 +950,21 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) source), 1); } //check if all signals was received by active zone - BOOST_CHECK_EQUAL(signalReceivedSourcesMap[1].size(), dbuses.size() - 1); + BOOST_CHECK_EQUAL(signalReceivedSourcesMap[1].size(), connections.size() - 1); //check if no signals was received by inactive zone - for (size_t i = 2; i <= dbuses.size(); ++i) { + for (size_t i = 2; i <= connections.size(); ++i) { BOOST_CHECK(signalReceivedSourcesMap[i].empty()); } - dbuses.clear(); + connections.clear(); } -BOOST_AUTO_TEST_CASE(DisplayOff) +BOOST_AUTO_TEST_CASE(SwitchToDefault) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); std::vector> clients; @@ -998,9 +999,9 @@ BOOST_AUTO_TEST_CASE(DisplayOff) BOOST_AUTO_TEST_CASE(MoveFile) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); Latch notificationLatch; @@ -1008,9 +1009,9 @@ BOOST_AUTO_TEST_CASE(MoveFile) std::string notificationPath; std::string notificationRetcode; - std::map> dbuses; + std::map> connections; for (int i = 1; i <= 2; ++i) { - dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); + connections[i] = std::unique_ptr(new ZoneAccessory(i)); } auto handler = [&](const std::string& /*senderBusName*/, @@ -1037,7 +1038,7 @@ BOOST_AUTO_TEST_CASE(MoveFile) }; // subscribe the second (destination) zone for notifications - dbuses.at(2)->signalSubscribe(handler); + connections.at(2)->signalSubscribe(handler); const std::string TMP = "/tmp/ut-zones"; const std::string NO_PATH = "path_doesnt_matter_here"; @@ -1049,28 +1050,28 @@ BOOST_AUTO_TEST_CASE(MoveFile) const std::string ZONE2PATH = TMP + "/" + ZONE2 + TMP; // sending to a non existing zone - BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(BUGGY_ZONE, NO_PATH), + BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(BUGGY_ZONE, NO_PATH), api::zone::FILE_MOVE_DESTINATION_NOT_FOUND); BOOST_CHECK(notificationLatch.empty()); // sending to self - BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(ZONE1, NO_PATH), + BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE1, NO_PATH), api::zone::FILE_MOVE_WRONG_DESTINATION); BOOST_CHECK(notificationLatch.empty()); // no permission to send - BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(ZONE2, "/etc/secret1"), + BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, "/etc/secret1"), api::zone::FILE_MOVE_NO_PERMISSIONS_SEND); BOOST_CHECK(notificationLatch.empty()); // no permission to receive // TODO uncomment this after adding an api to change 'permittedTo*' config - //BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(ZONE2, "/etc/secret2"), + //BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, "/etc/secret2"), // api::zone::FILE_MOVE_NO_PERMISSIONS_RECEIVE); //BOOST_CHECK(notificationLatch.empty()); // non existing file - BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(ZONE2, BUGGY_PATH), + BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, BUGGY_PATH), api::zone::FILE_MOVE_FAILED); BOOST_CHECK(notificationLatch.empty()); @@ -1083,7 +1084,7 @@ BOOST_AUTO_TEST_CASE(MoveFile) BOOST_REQUIRE(fs::create_directories(ZONE2PATH, ec)); BOOST_REQUIRE(utils::saveFileContent(ZONE1PATH + "/file", FILE_CONTENT)); - BOOST_CHECK_EQUAL(dbuses.at(1)->callMethodMove(ZONE2, TMP + "/file"), + BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, TMP + "/file"), api::zone::FILE_MOVE_SUCCEEDED); BOOST_REQUIRE(notificationLatch.wait(EVENT_TIMEOUT)); BOOST_REQUIRE(notificationLatch.empty()); @@ -1100,9 +1101,9 @@ BOOST_AUTO_TEST_CASE(MoveFile) BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); std::vector> clients; @@ -1150,18 +1151,18 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) BOOST_AUTO_TEST_CASE(ProxyCall) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); - std::map> dbuses; - dbuses[0] = std::unique_ptr(new HostAccessory()); + std::map> connections; + connections[0] = std::unique_ptr(new HostAccessory()); for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - dbuses[i] = std::unique_ptr(new ZoneAccessory(i)); + connections[i] = std::unique_ptr(new ZoneAccessory(i)); } - for (auto& dbus : dbuses) { + for (auto& dbus : connections) { dbus.second->setName(testapi::BUS_NAME); const int id = dbus.first; @@ -1178,58 +1179,58 @@ BOOST_AUTO_TEST_CASE(ProxyCall) // host -> zone2 BOOST_CHECK_EQUAL("reply from 2: param1", - dbuses.at(0)->testApiProxyCall("zone2", + connections.at(0)->testApiProxyCall("zone2", "param1")); // host -> host BOOST_CHECK_EQUAL("reply from 0: param2", - dbuses.at(0)->testApiProxyCall("host", + connections.at(0)->testApiProxyCall("host", "param2")); // zone1 -> host BOOST_CHECK_EQUAL("reply from 0: param3", - dbuses.at(1)->testApiProxyCall("host", + connections.at(1)->testApiProxyCall("host", "param3")); // zone1 -> zone2 BOOST_CHECK_EQUAL("reply from 2: param4", - dbuses.at(1)->testApiProxyCall("zone2", + connections.at(1)->testApiProxyCall("zone2", "param4")); // zone2 -> zone2 BOOST_CHECK_EQUAL("reply from 2: param5", - dbuses.at(2)->testApiProxyCall("zone2", + connections.at(2)->testApiProxyCall("zone2", "param5")); // host -> unknown - BOOST_CHECK_EXCEPTION(dbuses.at(0)->testApiProxyCall("unknown", "param"), + BOOST_CHECK_EXCEPTION(connections.at(0)->testApiProxyCall("unknown", "param"), DbusCustomException, WhatEquals("Unknown proxy call target")); // forwarding error - BOOST_CHECK_EXCEPTION(dbuses.at(0)->testApiProxyCall("host", ""), + BOOST_CHECK_EXCEPTION(connections.at(0)->testApiProxyCall("host", ""), DbusCustomException, WhatEquals("Test error")); // forbidden call - BOOST_CHECK_EXCEPTION(dbuses.at(0)->proxyCall("host", - "org.fake", - "/a/b", - "c.d", - "foo", - g_variant_new("(s)", "arg")), + BOOST_CHECK_EXCEPTION(connections.at(0)->proxyCall("host", + "org.fake", + "/a/b", + "c.d", + "foo", + g_variant_new("(s)", "arg")), DbusCustomException, WhatEquals("Proxy call forbidden")); } #endif // DBUS_CONNECTION namespace { - const HostAccessory::Dbuses EXPECTED_DBUSES_NONE = { + const HostAccessory::Connections EXPECTED_CONNECTIONS_NONE = { {"zone1", ""}, {"zone2", ""}, {"zone3", ""}}; - const HostAccessory::Dbuses EXPECTED_DBUSES_ALL = { + const HostAccessory::Connections EXPECTED_CONNECTIONS_ALL = { {"zone1", "unix:path=/tmp/ut-run/zone1/dbus/system_bus_socket"}, {"zone2", @@ -1238,22 +1239,22 @@ namespace { "unix:path=/tmp/ut-run/zone3/dbus/system_bus_socket"}}; } // namespace -BOOST_AUTO_TEST_CASE(GetZoneDbuses) +BOOST_AUTO_TEST_CASE(GetZoneConnections) { ZonesManager cm(TEST_CONFIG_PATH); HostAccessory host; - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); - BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); cm.restoreAll(); - BOOST_CHECK(EXPECTED_DBUSES_ALL == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_ALL == host.callMethodGetZoneConnections()); cm.shutdownAll(); - BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); } -BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbus) +BOOST_AUTO_TEST_CASE(GetZoneConnectionsNoDbus) { ZonesManager cm(TEST_CONFIG_PATH); HostAccessory host; @@ -1261,43 +1262,43 @@ BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbus) cm.createZone("zone2", SIMPLE_TEMPLATE); cm.createZone("zone3", SIMPLE_TEMPLATE); - BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); cm.restoreAll(); - BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); cm.shutdownAll(); - BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); + BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); } -BOOST_AUTO_TEST_CASE(ZoneDbusesSignals) +BOOST_AUTO_TEST_CASE(ZoneConnectionsSignals) { Latch signalLatch; - HostAccessory::Dbuses collectedDbuses; - std::mutex collectedDbusesMutex; + HostAccessory::Connections collectedConnections; + std::mutex collectedConnectionsMutex; - auto onSignal = [&] (const std::string& zoneId, const std::string& dbusAddress) { - std::unique_lock lock(collectedDbusesMutex); - collectedDbuses.insert(HostAccessory::Dbuses::value_type(zoneId, dbusAddress)); + auto onSignal = [&] (const std::string& zoneId, const std::string& address) { + std::unique_lock lock(collectedConnectionsMutex); + collectedConnections.insert(HostAccessory::Connections::value_type(zoneId, address)); signalLatch.set(); }; { ZonesManager cm(TEST_CONFIG_PATH); HostAccessory host; - host.subscribeZoneDbusState(onSignal); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + host.subscribeZoneConnectionState(onSignal); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); BOOST_CHECK(signalLatch.empty()); - BOOST_CHECK(collectedDbuses.empty()); + BOOST_CHECK(collectedConnections.empty()); cm.restoreAll(); BOOST_REQUIRE(signalLatch.waitForN(TEST_DBUS_CONNECTION_ZONES_COUNT, EVENT_TIMEOUT)); BOOST_CHECK(signalLatch.empty()); - std::unique_lock lock(collectedDbusesMutex); - BOOST_CHECK(EXPECTED_DBUSES_ALL == collectedDbuses); - collectedDbuses.clear(); + std::unique_lock lock(collectedConnectionsMutex); + BOOST_CHECK(EXPECTED_CONNECTIONS_ALL == collectedConnections); + collectedConnections.clear(); } } @@ -1544,8 +1545,8 @@ BOOST_AUTO_TEST_CASE(StartShutdownZone) const std::string zone2 = "zone2"; ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone(zone1, DBUS_TEMPLATE); - cm.createZone(zone2, DBUS_TEMPLATE); + cm.createZone(zone1, ZONE_ACCESS_TEMPLATE); + cm.createZone(zone2, ZONE_ACCESS_TEMPLATE); Latch callDone; auto resultCallback = [&]() { @@ -1581,9 +1582,9 @@ BOOST_AUTO_TEST_CASE(StartShutdownZone) BOOST_AUTO_TEST_CASE(LockUnlockZone) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", DBUS_TEMPLATE); - cm.createZone("zone2", DBUS_TEMPLATE); - cm.createZone("zone3", DBUS_TEMPLATE); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); HostAccessory host; -- 2.7.4 From 0091391085870ba5d68c77b50f2e63a89fd93e66 Mon Sep 17 00:00:00 2001 From: Krzysztof Dynowski Date: Fri, 24 Apr 2015 12:51:19 +0200 Subject: [PATCH 10/16] Vasum Wrapper: wrap old api client library #1 [Bug/Feature] Old API wrapper [Cause] wrap to vasum lib [Solution] #1 add copy of old API headers [Verification] Build Change-Id: I00b7c8cb102bbc30503be37611ffd3dd3a997a4f --- client/sc_adt.h | 91 +++ client/vasum.h | 1647 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1738 insertions(+) create mode 100644 client/sc_adt.h create mode 100644 client/vasum.h diff --git a/client/sc_adt.h b/client/sc_adt.h new file mode 100644 index 0000000..ec4c498 --- /dev/null +++ b/client/sc_adt.h @@ -0,0 +1,91 @@ +#ifndef __SCX_ADT_LIST_H__ +#define __SCX_ADT_LIST_H__ + +struct adt_list { + struct adt_list* next; + struct adt_list* prev; +}; + +#define adt_iterate_list(__iterator, __list) \ + for (__iterator = (__list)->next; \ + __iterator != __list; \ + __iterator = (__iterator)->next) + +#define adt_reverse_iterate_list(__iterator, __list) \ + for (__iterator = __list; \ + (__iterator)->next != __list; \ + __iterator = (__iterator)->next); \ + for ( ; \ + __iterator != __list; \ + __iterator = (__iterator)->prev) + +#define ADT_INIT_LIST(name) { &(name), &(name) } + +static inline void adt_init_list(struct adt_list* list) +{ + list->next = list->prev = list; +} + +static inline int adt_empty_list(struct adt_list* list) +{ + return (list == list->next) && (list == list->prev); +} + +static inline void __adt_list_add(struct adt_list* _new, + struct adt_list* prev, + struct adt_list* next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +static inline void adt_link_list(struct adt_list* head, struct adt_list* list) +{ + __adt_list_add(list, head, head->next); +} + +static inline void adt_unlink_list(struct adt_list* list) +{ + struct adt_list* next, *prev; + + next = list->next; + prev = list->prev; + next->prev = prev; + prev->next = next; +} + +static inline void adt_sort_list(struct adt_list* head, + int (*compare_func)(struct adt_list *, struct adt_list *)) +{ + struct adt_list *it, *jt, *kt; + + if (adt_empty_list(head)) + return; + + for (it = head->next->next; it != head; it = it->next) { + for (jt = head->next; jt != it; jt = jt->next) { + if (compare_func(it, jt) < 0) { + kt = it; + it = it->prev; + adt_unlink_list(kt); + adt_link_list(jt->prev, kt); + break; + } + } + } +} + +static inline struct adt_list *adt_find_list(struct adt_list* head, + int (*equal_func)(struct adt_list *, void *), void *value) +{ + struct adt_list *it; + adt_iterate_list(it, head) { + if (equal_func(it, value)) + return it; + } + return NULL; +} + +#endif /*!__ADT_LIST_H__*/ diff --git a/client/vasum.h b/client/vasum.h new file mode 100644 index 0000000..f7393ff --- /dev/null +++ b/client/vasum.h @@ -0,0 +1,1647 @@ +/* + * Container Control Framework + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Krzysztof Dynowski + * + * 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. + * + */ +#ifndef __VASUM_H__ +#define __VASUM_H__ + +#include +#include +#include +#include +#include + +#include "sc_adt.h" + +#ifndef API +#define API __attribute__((visibility("default"))) +#endif // API + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @file vasum.h + * @version 0.2 + * @brief This file contains APIs of the Container control Framework + */ + +/* + * + * + * Revision History: + * + * + */ + +/** + * @addtogroup ZONE_CONTROL Zone Control + * @{ +*/ + +typedef enum { + VSM_ERROR_NONE, /* The operation was successful */ + VSM_ERROR_GENERIC, /* Non-specific cause */ + VSM_ERROR_INVALID, /* Invalid argument */ + VSM_ERROR_CANCELED, /* The requested operation was cancelled */ + VSM_ERROR_ABORTED, /* Operation aborted */ + VSM_ERROR_REFUSED, /* Connection refused */ + VSM_ERROR_EXIST, /* Target exists */ + VSM_ERROR_BUSY, /* Resource is busy */ + VSM_ERROR_IO, /* I/O error*/ + VSM_ERROR_TIMEOUT, /* Timer expired */ + VSM_ERROR_OVERFLOW, /* Value too large to be stored in data type */ + VSM_ERROR_OUT_OF_MEMORY, /* No memory space */ + VSM_ERROR_OUT_OF_RANGE, /* Input is out of range */ + VSM_ERROR_NOT_PERMITTED, /* Operation not permitted */ + VSM_ERROR_NOT_IMPLEMENTED, /* Function is not implemented yet */ + VSM_ERROR_NOT_SUPPORTED, /* Operation is not supported */ + VSM_ERROR_ACCESS_DENIED, /* Access privilege is not sufficient */ + VSM_ERROR_NO_OBJECT, /* Object not found */ + VSM_ERROR_BAD_STATE, /* Bad state */ + VSM_MAX_ERROR = VSM_ERROR_BAD_STATE +}vsm_error_t; + +/** + *@brief struct vsm_context keeps track of an execution state of the container control framework. + */ +struct vsm_context { + /// — Used for internal — + void *data; + /// Error code + vsm_error_t error; + /// RWLock for list members + pthread_rwlock_t lock; + /// List of callback function for changing state + struct adt_list listeners; + /// Root(host) of zones (except for stopped zones) + struct vsm_zone *root_zone; + /// Foreground zone + struct vsm_zone *foreground_zone; +}; + +/** + * @brief Get last error string. + * + * \par Synopsis: + * \code + * #include + * + * const char *vsm_error_string(struct vsm_context *ctx); + * \endcode + * + * \par Description: + * vsm_error_string return last error string for debug or logging. + * + * \param[in] ctx vsm context + * + * \return string for last error in context. + * + * \par Known issues/bugs: + * None + * + * \pre None + * + * \post None + * + * \see struct vsm_context + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * struct vsm_zone * zone; + * + * ctx = vsm_create_context(); + * zone = vsm_lookup_zone_by_pid(ctx, pid); + * if(zone == NULL) + * { + * fprintf(stderr, "API Failed : %s", vsm_error_string(ctx)); + * } + * ... + * \endcode + * +*/ + +API const char *vsm_error_string(struct vsm_context *ctx); + +/** + * @brief Create vsm context + * + * \par Synopsis: + * \code + * #include + * + * struct vsm_context *vsm_create_context(void *) + * \endcode + * + * \par Description: + * The vsm context is an abstraction of the logical connection between the zone controller and it's clients. + * The vsm context must be initialized before attempting to use almost any of the APIs, + * and it should be finalized when interaction with the zone controller is no longer required.\n + * \n + * A call to vsm_create_context() makes a connection to zone controller(vsm-zone-svc), + * and creates a new instance of struct vsm_context called vsm context.\n + * + * \param None + * + * \return An instance of vsm context on success, or NULL on error (in which case, errno is set appropriately) + * + * \par Known issues/bugs: + * None + * + * \pre vsm-zone-svc must be started + * + * \post None + * + * \see vsm_cleanup_context() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * + * ctx = vsm_create_context(); + * if(ctx == NULL) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API struct vsm_context *vsm_create_context(void); + +/** + * @brief Cleanup zone control context + * + * \par Synopsis: + * \code + * #include + * + * int vsm_cleanup_context(struct vsm_context *ctx) + *\endcode + * + * \par Description: + * vsm_cleanup_context() finalizes vsm context and release all resources allocated to the vsm context.\n + * \n + * This function should be called if interaction with the zone controller is no longer required. + * + * \param[in] ctx vsm context + * + * \return 0 on success, or -1 on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post vsm context will not be valid after calling this API + * + * \see vsm_create_context() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * retval = vsm_cleanup_context(ctx); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_cleanup_context(struct vsm_context *ctx); + +/** + * @brief Get file descriptor associated with event dispatcher of zone control context + * + * \par Synopsis: + * \code + * #include + * + * int vsm_get_poll_fd(struct vsm_context *ctx) + * \endcode + * + * \par Description: + * The function vsm_get_poll_fd() returns the file descriptor associated with the event dispatcher of vsm context.\n + * The file descriptor can be bound to another I/O multiplexing facilities like epoll, select, and poll. + * + * \param[in] ctx vsm context + * + * \return On success, a nonnegative file descriptor is returned. On error -1 is returned. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_enter_eventloop() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int fd; + * struct vsm_context *ctx; + * ... + * fd = vsm_get_poll_fd(ctx); + * while (1) { + * ... + * epoll_wait(fd, events, MAX_EPOLL_EVENTS, -1); + * ... + * if (vsm_enter_eventloop(ctx, 0, 0) < 0) + * break; + * ... + * } + * ... + * \endcode + * +*/ +API int vsm_get_poll_fd(struct vsm_context *ctx); +/** + * @brief Wait for an I/O event on a VSM context + * + * \par Synopsis: + * \code + * #incldue + * + * int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout) + * \endcode + * + * \par Description: + * vsm_enter_eventloop() waits for event on the vsm context.\n + *\n + * The call waits for a maximum time of timout milliseconds. Specifying a timeout of -1 makes vsm_enter_eventloop() wait indefinitely, + * while specifying a timeout equal to zero makes vsm_enter_eventloop() to return immediately even if no events are available. + * + * \param[in] ctx vsm context + * \param[in] flags Reserved + * \param[in] timeout Timeout time (milisecond), -1 is infinite + * + * \return 0 on success, or -1 on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_get_poll_fd() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * ... + * while (vsm_enter_eventloop(ctx, 0, -1)) { + * ... + * } + * ... + * \endcode + * +*/ +API int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout); + +/** + * @brief Definition for default zone name. + * Default zone is started at boot sequence by systemd. +*/ +#define VSM_DEFAULT_ZONE "personal" + +/** + * @brief Definition for zone states. + * This definition shows the available states. + * Zone is started from VSM_ZONE_STATE_STOPPED state. During start up, zone controller instantiates zone and + * starts the first process in the zone. + * Once the first process has started, the state of the zone will not be changed unless + * the process is killed. +*/ + +typedef enum { + VSM_ZONE_STATE_STOPPED, + VSM_ZONE_STATE_STARTING, + VSM_ZONE_STATE_RUNNING, + VSM_ZONE_STATE_STOPPING, + VSM_ZONE_STATE_ABORTING, + VSM_ZONE_STATE_FREEZING, + VSM_ZONE_STATE_FROZEN, + VSM_ZONE_STATE_THAWED, + VSM_ZONE_MAX_STATE = VSM_ZONE_STATE_THAWED +} vsm_zone_state_t; + +typedef enum { + VSM_ZONE_EVENT_NONE, + VSM_ZONE_EVENT_CREATED, + VSM_ZONE_EVENT_DESTROYED, + VSM_ZONE_EVENT_SWITCHED, + VSM_ZONE_MAX_EVENT = VSM_ZONE_EVENT_SWITCHED +} vsm_zone_event_t; + +/** + * @brief Zone structure which is used to represent an instance of container. + */ +struct vsm_zone { + /// Parent + struct vsm_zone *parent; + /// Name (null-terminated string) + char *name; + /// Zone type (null-terminated string) + char *type; + /// Domain's Virtual Terminal number + int terminal; + /// State + vsm_zone_state_t state; + /// Container's rootfs path + char *rootfs_path; + /// RWLock for list members + pthread_rwlock_t lock; + /// List of child zones + struct adt_list children; + /// List of devices in zone + struct adt_list devices; + /// List of network devices in zone + struct adt_list netdevs; + /// Pointer of user-defined data for clients. + void *user_data; + ///List head + struct adt_list list; +}; + +/** + * @brief Create a new persistent zone + * + * \par Synopsis + * \code + * #include + * + * int vsm_create_zone(struct vsm_context *ctx, const char *name, const char *template_name, int flag) + * \endcode + * + * \par Description: + * vsm_create_zone() triggers zone controller to create new persistent zone.\n + * \n + * The zone controller distinguishes two types of zones: peristent and transient. + * Persistent zones exist indefinitely in storage. + * While, transient zones are created and started on-the-fly.\n + * \n + * Creating zone requires template. + * In general, creating a zone involves constructing root file filesystem and + * generating configuration files which is used to feature the zone. + * Moreover, it often requires downloading tools and applications pages, + * which are not available in device. + * In that reason, this Domain Separation Framework delegates this work to templates. + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * \param[in] template_name template name to be used for constructing the zone + * \param[in] flag Reserved + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_start_zone(), vsm_shutdown_zone(), vsm_destroy_zone() + * + * \remarks By default, a zone is in an inactive state even if it has succefully created. + * Thus, the zone should be unlocked explicitly to start its execution.\n + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * retval = vsm_create_zone(ctx, "personal", "tizen", 0); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_create_zone(struct vsm_context *ctx, const char *zone_name, const char *template_name, int flag); +/** + * @brief Destroy persistent zone + * + * \par Synopsis: + * \code + * #include + * + * int vsm_destroy_zone(struct vsm_context *ctx, const char *name, int force) + * \endcode + * + * \par Description: + * The function vsm_destroy_zone() triggers zone controller to destroy persistent zone corresponding to the given name.\n + * All data stored in the repository of the zone are also deleted if force argument is set. + * Once the zone repository is deleted, it cannot be recovered. + * + * \param[in] ctx vsm context + * \param[in] zone_name Domain name + * \param[in] force + * - 0 is Remaining the zone when the zone is running + * - non-zero is Destroy the zone even though the zone is running + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * Parameter "force" is not implemented yet, now it works as non-zero. + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_create_zone(), vsm_shutdown_zone(), vsm_destroy_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * retval = vsm_destroy_zone(ctx, "personal", 1); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_destroy_zone(struct vsm_context *ctx, const char *zone_name, int force); +/** + * @brief Start an execution of a persistent zone + * + * \par Synopsis: + * \code + * #include + * + * int vsm_start_zone(struct vsm_context *ctx, const char *name) + * \endcode + * + * \par Description: + * The function vsm_start_zone() triggers zone controller to start zone corresponding to the given name.\n + * Caller can speficy the type of zones: transient and peristent. + * Persistent zones need to be defined before being start up(see vsm_create_zone()) + * While, transient zones are created and started on-the-fly. + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_shutdown_zone(), vsm_create_zone(), vsm_destroy_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * retval = vsm_start_zone(ctx, "personal"); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_start_zone(struct vsm_context *ctx, const char *zone_name); +/** + * @brief Stop an execution of running zone + * + * \par Synopsys + * \code + * #include + * + * int vsm_shutdown_zone(struct vsm_context * ctx, struct zone * zone, int force) + * \endcode + * + * \par Description: + * vsm_shutdown_zone() triggers zone controller to stop execution of the zone corresponsing to the given zone.\n + * + * \par Important notes: + * None + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * \param[in] force option to shutdown. + * Without if 0 send SIGPWR signal to init process in zone, + otherwise, terminate all processes in zone forcefully. + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_create_zone(), vsm_destroy_zone(), vsm_start_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * retval = vsm_shutdown_zone(ctx, "zone", 1); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_shutdown_zone(struct vsm_context *ctx, const char *zone_name, int force); + +/** + * @brief Prevent starting zone + * + * \par Synopsys + * \code + * #include + * + * int vsm_lock_zone(struct vsm_context *ctx, const char *name, int shutdown); + * \endcode + * + * \par Description: + * Prevent starting a zone + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_create_zone(), vsm_start_zone(), vsm_unlock_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * ... + * ret = vsm_lock_zone(ctx, "zone"); + * if(ret < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_lock_zone(struct vsm_context *ctx, const char *zone_name, int shutdown); + +/** + * @brief Allow a zone to be launched + * + * \par Synopsys + * \code + * #include + * + * int vsm_unlock_zone(struct vsm_context *ctx, const char *name) + * \endcode + * + * \par Description: + * Remove lock applied to the zone corresponding to the given name. + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_lock_zone(), vsm_create_zone(), vsm_start_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * ... + * if (vsm_unlock_zone(ctx, "zone") < 0) { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_unlock_zone(struct vsm_context *ctx, const char *zone_name); + + +API int vsm_set_foreground(struct vsm_zone * zone); + + +typedef struct vsm_attach_command_t { + /** @brief excutable file path */ + char * exec; + /** @brief arguments including the executable binary itself in argv[0] */ + char ** argv; +} vsm_attach_command_t; + +/** + * @brief Domain attach option + */ +typedef struct vsm_attach_options_t { + /** @brief user id */ + uid_t uid; + /** @brief group id */ + gid_t gid; + /** @brief number of environment variables */ + int env_num; + /** @brief environment variables */ + char **extra_env; +} vsm_attach_options_t; + +#define VSM_ATTACH_OPT_DEFAULT \ +{ \ + /*.uid =*/ (uid_t)0, \ + /*.gid =*/ (gid_t)0, \ + /*.env_num=*/ 0, \ + /*.extra_env = */ NULL \ +} + +/** + * @brief Launch a process in a running zone. + * + * \par Synopsys + * \code + * #include + * + * int vsm_attach_zone(struct vsm_context *ctx, const char * name, vsm_attach_command_t * command, vsm_attach_options_t * opt) + * \endcode + * + * \par Description: + * Execute specific command inside the container with given arguments and environment + * + * \param[in] ctx vsm context + * \param[in] zone_name zone name + * \param[in] command vsm attach command + * \param[in] opt vsm attach options (can be NULL) + * + * \return On sucess, exit code of attached process. + * otherwise, a negative value. + * + * \par Known issues/bugs: + * + * \pre None + * + * \post None + * + * \see vsm_start_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * struct vsm_zone *zone; + * vsm_attach_command_t comm; + * vsm_attach_options_t opts = VSM_ATTACH_OPT_DEFAULT; + * char * attach_argv[] = {"-al", "/proc/"}; + * + * comm.exec = "ls"; + * comm.argc = 2; + * comm.argv = attach_argv; + * + * opts.uid = 5000; + * opts.gid = 5000; + * opts.env_num = 0; + * + * ... + * res = vsm_attach_zone(ctx, zone, &comm, &opts); + * ... + * \endcode + * + */ + +API int vsm_attach_zone(struct vsm_context *ctx, struct vsm_zone *zone, vsm_attach_command_t * command, vsm_attach_options_t * opt, pid_t *attached_process); + + +API int vsm_attach_zone_wait(struct vsm_context *ctx, struct vsm_zone *zone, vsm_attach_command_t * command, vsm_attach_options_t * opt); + +/** + * @brief Interate all zone instances which are in running state + * + * \par Synopsys + * \code + * #include + * + * int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data) + * \endcode + * + * \par Description: + * The function vsm_iterate_zone() traverses all zones which are in running state, and callback function will be called on every entry. + * + * \param[in] ctx vsm context + * \param[in] callback Function to be executed in iteration, which can be NULL + * \param[in] user_data Parameter to be passed to callback function + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_lock_zone(), vsm_unlock_zone(), vsm_start_zone(), vsm_shutdown_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_context *ctx; + * ... + * void callback(struct vsm_zone *zone, void *user_data) + * { + * printf("Zone : %s\n", zone->name); + * } + * ... + * zone = vsm_iterate_zone(ctx, callback, NULL); + * if(netdev == NULL) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data); + +/** + * @brif Find zone corresponding to the name + * + * \par Synopsys + * \code + * #include + * + * struct zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path) + * \endcode + * + * \par Description: + * The function vsm_lookup_zone_by_name() looks for the zone instance corresponding to the given name. + * + * \param[in] ctx vsm context + * \param[in] path zone path to search + * + * \return Zone instance on success, or NULL on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_lookup_zone_by_pid(), vsm_lookup_zone_by_terminal(), vsm_iterate_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_zone *zone; + * struct vsm_context *ctx; + * ... + * zone = vsm_lookup_zone_by_name(ctx, "personal"); + * if(zone == NULL) + * { + * printf("Knox isn't exist or isn't running\n"); + * } else { + * printf("%s is found", zone->name); + * } + * ... + * \endcode + * +*/ +API struct vsm_zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path); + +/** + * @brief Find zone instance associated with the process id + * + * \par Synopsis: + * \code + * #include + * + * struct zone * vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid) + * \endcode + * + * \par Description: + * The function vsm_lookup_zone_by_pid() looks for the zone instance associated with the given pid. + * + * \param[in] ctx vsm context + * \param[in] pid Process id + * + * \return Zone instance on success, or NULL on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_lookup_zone_by_name(), vsm_lookup_zone_by_terminal(), vsm_iterate_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_zone *zone; + * struct vsm_context *ctx; + * ... + * zone = vsm_lookup_zone_by_pid(ctx, 1208); + * if(zone == NULL) + * { + * printf("Not found\n"); + * } else { + * printf("%s is found", zone->name); + * } + * ... + * \endcode + * +*/ +API struct vsm_zone *vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid); + +/** + * @brief Find zone instance associated with the given terminal + * + * \par Synopsis: + * \code + * #include + * + * struct zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal) + * \endcode + * + * \par Purpose: + * The function vsm_lookup_zone_by_terminal_id() search zone instance which is associated with the given terminal. + * In general, the terminal id would be tty number. + * + * \param[in] ctx vsm context + * \param[in] terminal Terminal id to search + * + * \return Zone instance on success, or NULL on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_start_context(), vsm_shutdown_context(), vsm_lookup_zone_by_name(), vsm_lookup_zone_by_pid(), vsm_iterate_zone() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_zone *zone; + * struct vsm_context *ctx; + * ... + * zone = vsm_lookup_zone_by_terminal_id(ctx, 2); + * if(zone == NULL) + * { + * printf("Not found\n"); + * } else { + * printf("%s is found", zone->name); + * } + * ... + * \endcode + * +*/ +API struct vsm_zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal); + +/** + * @brief Definition for zone event callback function. + */ +typedef int (*vsm_zone_state_cb)(struct vsm_zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data); + +/** + * @brief Register a callback to be notified when zone state has changed + * + * \par Synopsis: + * \code + * #include + * + * int vsm_add_state_callback(struct vsm_context *ctx, zone_state_cb callback, void *user_data) + * \endcode + * + * \par Description: + * Register a callback to be notified when zone state event occurs. + * + * \param[in] ctx vsm context + * \param[in] callback Callback function to invoke when zone satte event occurs + * + * \return Callback ID on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_del_state_callback(), vsm_enter_eventloop(), vsm_get_poll_fd() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_context *ctx; + * ... + * void callback(struct zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data) + * { + * if (state == VSM_ZONE_STATE_RUNNING) + * printf("Domain(%s) is running\n", zone->name); + * } + * ... + * retval = vsm_add_state_callback(ctx, callback, NULL); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_add_state_callback(struct vsm_context *ctx, vsm_zone_state_cb callback, void *user_data); +/** + * @brief Remove zone event callback + * + * \par Synopsis + * \code + * #include + * + * \endcode + * + * \par Description: + * Remove an event callback from the zone control context. + * + * \par Important notes: + * None + * + * \param[in] ctx vsm context + * \param[in] handle Callback Id to remove + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_context(), vsm_cleanup_context(), vsm_add_state_callback() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int id; + * struct vsm_context *ctx; + * ... + * void callback(struct zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data) + * { + * if (state == VSM_ZONE_STATE_RUNNING) + * printf("Domain(%s) is running\n", zone->name); + * } + * ... + * id = vsm_add_state_callback(ctx, callback, NULL); + * ... + * vsm_del_state_callback(ctx, id); + * ... + * \endcode + * +*/ +API int vsm_del_state_callback(struct vsm_context *ctx, int handle); + +/// @} + +/** + * @addtogroup DEVICE_CONTROL + * @{ +*/ + +/** + * @brief Grant device to zone + * + * \par Synopsys: + * \code + * #include + * + * int vsm_grant_device(struct vsm_zone *zone, const char *name, uint32_t flags) + * \endcode + * + * \par Description: + * The function vsm_grant_device() permits the zone using the device corresponding to the given name. + * + * \param[in] zone Zone + * \param[in] name Path of device to grant + * \param[in] flags O_RDWR, O_WRONLY, O_RDONLY + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre None + * + * \post None + * + * \see vsm_revoke_device() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_zone *zone; + * ... + * retval = vsm_grant_device(zone, "/dev/dri/card0", O_RDWR); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_grant_device(struct vsm_zone *dom, const char *name, uint32_t flags); +/** + * @brief Revoke device from the zone + * + * \par Synopsis: + * \code + * #include + * + * int vsm_revoke_device(struct vsm_zone *zone, const char *name) + * \endcode + * + * \par Description: + * + * \param[in] zone Zone + * \param[in] name Host-side path of device to revoke + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_grant_device() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_zone *zone; + * ... + * retval = vsm_revoke_device(dom, "/dev/samsung_sdb"); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_revoke_device(struct vsm_zone *dom, const char *name); + +/// @} + +/** + * @addtogroup NETWORK_CONTROL + * @{ +*/ + +/** + * @brief Types of virtual network interfaces + */ +typedef enum { + ///Virtual Ethernet(veth), this type device will be attached to host-side network bridge + VSM_NETDEV_VETH, + ///Physical device + VSM_NETDEV_PHYS, + ///Mac VLAN, this type isn't implemented yet + VSM_NETDEV_MACVLAN +} vsm_netdev_type_t; + +/** + * @brief Network device information + */ +struct vsm_netdev { + /// Domain + struct vsm_zone *zone; + /// Device name + char *name; + /// Type + vsm_netdev_type_t type; + + ///List head + struct adt_list list; +}; + +/** + * @brief Create a new network device and assisgn it to zone + * + * \par Synopsis: + * \code + * #include + * + * struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev) + * \endcode + * + * \par Description: + * This function creates net netdev instance and assign it to the given zone. + * + * \param[in] zone Zone + * \param[in] type Type of network device to be create + * \param[in] target + * - If type is veth, this will be bridge name to attach. + * - If type is phys, this will be ignored. + * \param[in] netdev Name of network device to be create + * + * \return Network devce on success, or NULL on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_netdev() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int retval; + * struct vsm_netdev *netdev; + * ... + * netdev = vsm_create_netdev(zone, VSM_NETDEV_VETH, "virbr0", "vethKnox"); + * if(retval < 0) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * + * Macvlan isn't implemented yet. +*/ +API struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev); +/** + * @brief Removes a network device from zone control context + * + * \par Synopsis: + * \code + * #include + * + * int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev) + * \endcode + * + * \par Description: + * This function remove the given netdev instance from the zone control context. + * + * \param[in] zone zone + * \param[in] netdev network device to be removed + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_destroy_netdev() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_zone *zone; + * struct vsm_netdev *netdev; + * ... + * netdev = vsm_create_netdev(zone, VSM_NETDEV_VETH, "virbr0", "vethKnox"); + * if(netdev == NULL) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * vsm_destroy_netdev(zone, netdev); + * ... + * \endcode + * +*/ +API int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev); + +/** + * @brief Iterates network devices found in the zone vsm context and executes callback() on each interface. + * + * \par Synopsis: + * \code + * #include + * + * int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data) + * \endcode + * + * \par Description: + * vsm_destroy_netdev() scans all network interfaces which are registered in the vsm context, and calls callback() on each entry. + * + * \param[in] zone Zone + * \param[in] callback Function to be executed in iteration, which can be NULL + * \param[in] user_data Parameter to be delivered to callback function + * + * \return 0 on success, or negative integer error code on error. + * + * \par Known issues/bugs: + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_create_netdev(), vsm_destroy_netdev() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct zone *zone; + * ... + * void callback(struct vsm_neatdev *netdev, void *user_data) + * { + * printf("Network device : %s\n", netdev->name); + * } + * ... + * netdev = vsm_iterate_netdev(zone, callback, NULL); + * if(netdev == NULL) + * { + * printf("Error has occurred\n"); + * exit(0); + * } + * ... + * \endcode + * +*/ +API int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data); + +/** + * @brief Find a network device corresponding to the name + * + * \par Synopsis: + * \code + * #include + * + * struct zone_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name) + * \endcode + * + * \par Description: + * The function vsm_lookup_netdev_by_name() looks for a network interface corresponding to the given name. + * + * \param[in] zone Zone + * \param[in] name Network device name to search + * + * \return Network device on success, or NULL on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_iterate_netdev() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * struct vsm_zone *zone; + * struct vsm_netdev *netdev; + * ... + * netdev = vsm_lookup_netdev(zone, "vethKnox"); + * if(netdev == NULL) + * { + * printf("Network device isn't exist\n"); + * } else { + * printf("There is %s in %s", netdev->name); + * } + * ... + * \endcode + * +*/ +API struct vsm_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name); + +/// @} + +/** + * @addtogroup RESOURCE_PROVISIONING + * @{ + */ + +typedef enum { + VSM_FSO_TYPE_DIR, + VSM_FSO_TYPE_REG, + VSM_FSO_TYPE_FIFO, + VSM_FSO_TYPE_SOCK, + VSM_FSO_TYPE_DEV, + VSM_FSO_MAX_TYPE = VSM_FSO_TYPE_DEV +} vsm_fso_type_t; + +typedef mode_t vsm_mode_t; + +/** + * @brief Register file system object to vsm context. + * + * \par Synopsis: + * \code + * #include + * + * int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode) + * \endcode + * + * \par Description: + * Register file system object to vsm context. Once the object is registered to the context, it will be populated when + * any zone is started.\n + * + * \param[in] ctx vsm context + * \param[in] type Type of file system object + * \param[in] path Path for the file system object + * \param[in] flags Flasg + * \param[in] mode mode + * + * \return zero on success, or negative value on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_declare_mount(), vsm_declare_link() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int ret; + * struct vsm_zone *zone; + * ... + * ret = vsm_declare_file(zone, VSM_FSO_TYPE_DIR, "/vethKnox", 0666); + * if(ret < 0) + * { + * printf("Failed to declare file system object\n"); + * } + * + * ... + * \endcode + * +*/ + +API int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode); + +/** + * @brief Register file system object to vsm context. + * + * \par Synopsis: + * \code + * #include + * + * int vsm_declare_mount(struct vsm_context *ctx, const char *source, const char *target, const char *fstype, unsigned long flags, const void *data) + * \endcode + * + * \par Description: + * Register mount to vsm context. Once the mount is registered to the context, it will be populated when + * any zone is started.\n + * + * \param[in] ctx vsm context + * \param[in] source filesystem source + * \param[in] target mount point + * \param[in] fstype filesystem type + * \param[in] flags mount options + * \param[in] data filesystem specific data + * + * \return zero on success, or negative value on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_decalre_file(), vsm_declare_link() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int ret; + * struct vsm_zone *zone; + * ... + * ret = vsm_declare_file(zone, "/dev/block0", "/mnt/target", "ext4", 0, NULL); + * if(ret < 0) + * { + * printf("Failed to declare file system object\n"); + * } + * + * ... + * \endcode + * +*/ + +API int vsm_declare_mount(struct vsm_context *ctx, const char *source, const char *target, const char *fstype, unsigned long flags, const void *data); + +/** + * @brief Declare hardlink to vsm context. + * + * \par Synopsis: + * \code + * #include + * + * int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target) + * \endcode + * + * \par Description: + * Declare hardlink to the vsm context.\n + * In general, this function is used to create shared socket. + * + * \param[in] ctx vsm context + * \param[in] source source + * \param[in] target target + * + * \return zero on success, or negative value on error. + * + * \par Known issues/bugs: + * None + * + * \pre vsm context must be initialized by vsm_create_context() + * + * \post None + * + * \see vsm_declare_file(), vsm_declare_mount() + * + * \remarks None + * + * \par Sample code: + * \code + * #include + * ... + * int ret; + * struct vsm_zone *zone; + * ... + * ret = vsm_declare_link(zone, "/tmp/sock", "/tmp/sock"); + * if(ret < 0) + * { + * printf("Failed to declare file system object\n"); + * } + * + * ... + * \endcode + * +*/ + +API int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target); + +/// @} + +#ifdef __cplusplus +} +#endif + +#endif /*! __VASUM_H__ */ -- 2.7.4 From 236d6e7e0cf238e0ed8f3cd507a749cb1beeae62 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 27 Apr 2015 13:47:31 +0200 Subject: [PATCH 11/16] Make tests independent from running Vasum server instance [Bug] Running tests when Vasum server was up caused "Connection refused" error in vasum-cli. [Cause] Unit tests used vasum-ipc.socket, which overriden the connection between CLI and Vasum server. [Solution] Separate unit-tests IPC socket from Vasum server socket. Unit-tests now create and use their own socket: vasum-ipc-unit-tests.socket [Verification] Build, install, run Vasum service, run all tests. Ensure that CLI works after tests finish running. Change-Id: Ic94500b743e990273361d85dffecfbe17ddc0347 --- CMakeLists.txt | 3 ++- client/CMakeLists.txt | 6 ++++-- server/CMakeLists.txt | 1 + tests/unit_tests/CMakeLists.txt | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a87b41..308fb45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,6 @@ ADD_DEFINITIONS(-DVASUM_USER="${VASUM_USER}") ADD_DEFINITIONS(-DINPUT_EVENT_GROUP="${INPUT_EVENT_GROUP}") ADD_DEFINITIONS(-DDISK_GROUP="${DISK_GROUP}") ADD_DEFINITIONS(-DTTY_GROUP="${TTY_GROUP}") -ADD_DEFINITIONS(-DHOST_IPC_SOCKET="/var/run/vasum-ipc.socket") #ADD_DEFINITIONS(-DDBUS_CONNECTION) ## Python packages directory ################################################### @@ -170,6 +169,8 @@ IF(NOT DEFINED DATA_DIR) ENDIF(NOT DEFINED DATA_DIR) SET(VSM_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/vasum) +SET(VSM_SERVER_IPC_SOCKET_PATH /var/run/vasum-ipc.socket) +SET(VSM_UNIT_TESTS_IPC_SOCKET_PATH /var/run/vasum-ipc-unit-tests.socket) ADD_SUBDIRECTORY(${CLIENT_FOLDER}) ADD_SUBDIRECTORY(${SERVER_FOLDER}) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 296e638..afe609f 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -42,8 +42,10 @@ ADD_DEFINITIONS(-fvisibility=hidden) ## Setup target ################################################################ ADD_LIBRARY(${PROJECT_NAME} SHARED ${project_SRCS} ${common_SRCS}) -SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY SOVERSION ${_LIB_SOVERSION_}) -SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY VERSION ${_LIB_VERSION_}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES + SOVERSION ${_LIB_SOVERSION_} + VERSION ${_LIB_VERSION_} + COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_SERVER_IPC_SOCKET_PATH}") ## Link libraries ############################################################## diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 9470754..2dbc322 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) SET_TARGET_PROPERTIES(${SERVER_CODENAME} PROPERTIES COMPILE_FLAGS "-pthread" + COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_SERVER_IPC_SOCKET_PATH}" LINK_FLAGS "-pthread" ) diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 692ec4b..bed7d37 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -55,11 +55,13 @@ INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) SET_TARGET_PROPERTIES(${UT_SERVER_CODENAME} PROPERTIES COMPILE_FLAGS "-pthread" + COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_UNIT_TESTS_IPC_SOCKET_PATH}" LINK_FLAGS "-pthread" ) SET_TARGET_PROPERTIES(${SOCKET_TEST_CODENAME} PROPERTIES COMPILE_FLAGS "-pthread" + COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_UNIT_TESTS_IPC_SOCKET_PATH}" LINK_FLAGS "-pthread" ) -- 2.7.4 From 0a250ce53b2b03f663b70ef83a0f3988b4117687 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 4 May 2015 17:33:28 +0200 Subject: [PATCH 12/16] Remove libvirt code [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] N/A Change-Id: Ic288d52a0408d17a6b898d7ab96ef9ed116b4af5 --- client/utils.cpp | 77 +---------------------------- server/zone.hpp | 2 +- tests/unit_tests/client/ut-client-utils.cpp | 4 -- 3 files changed, 2 insertions(+), 81 deletions(-) diff --git a/client/utils.cpp b/client/utils.cpp index 305b848..7e5655e 100644 --- a/client/utils.cpp +++ b/client/utils.cpp @@ -31,10 +31,6 @@ namespace { const std::string CPUSET_HOST = "/"; const std::string CPUSET_LXC_PREFIX = "/lxc/"; -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 parseLxcFormat(const std::string& cpuset, std::string& id) { @@ -46,75 +42,6 @@ bool parseLxcFormat(const std::string& cpuset, std::string& id) return true; } -bool parseOldLibvirtFormat(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 int a = unhex(value[inPos+1]); - const int b = unhex(value[inPos+2]); - value[outPos++] = (char) ((a << 4) | b); - inPos += 3; - } else { - value[outPos++] = c; - } - } - value.resize(outPos); -} - -bool parseNewLibvirtFormat(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 parseZoneIdFromCpuSet(const std::string& cpuset, std::string& id) @@ -124,8 +51,6 @@ bool parseZoneIdFromCpuSet(const std::string& cpuset, std::string& id) return true; } - return parseLxcFormat(cpuset, id) || - parseNewLibvirtFormat(cpuset, id) || - parseOldLibvirtFormat(cpuset, id); + return parseLxcFormat(cpuset, id); } diff --git a/server/zone.hpp b/server/zone.hpp index e7e929a..f24a6e6 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -152,7 +152,7 @@ public: /** * Check if the zone is stopped. It's NOT equivalent to !isRunning, - * because it checks different internal libvirt's states. There are other states, + * because it checks different internal LXC states. There are other states, * (e.g. paused) when the zone isn't running nor stopped. * * @return Is the zone stopped? diff --git a/tests/unit_tests/client/ut-client-utils.cpp b/tests/unit_tests/client/ut-client-utils.cpp index 459a1b1..7a1b5ac 100644 --- a/tests/unit_tests/client/ut-client-utils.cpp +++ b/tests/unit_tests/client/ut-client-utils.cpp @@ -47,10 +47,6 @@ BOOST_AUTO_TEST_CASE(ParseZoneIdFromCpuSet) 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"); - testOK("/lxc/test", "test"); } -- 2.7.4 From d8fa598081d29556dcaaca00a1a67084d47cdce7 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 27 Apr 2015 11:12:06 +0200 Subject: [PATCH 13/16] Remove zone-host connection [Feature] No dbus connection with zone [Cause] N/A [Solution] Remove code responsible for zone connection [Verification] Build with and without DBUS_CONNECTION macro, run tests for each build (NOTE: ClientSuite/NotRunningServer will fail) Change-Id: Ida474fba31111eb431ddc97c4bc3def1eeb932c7 --- client/dbus-connection.cpp | 119 ---- client/dbus-connection.hpp | 135 ---- client/host-dbus-connection.cpp | 191 ------ client/host-dbus-connection.hpp | 84 --- client/host-ipc-connection.cpp | 194 ++++-- client/host-ipc-connection.hpp | 23 +- client/ipc-connection.cpp | 47 -- client/ipc-connection.hpp | 90 --- client/vasum-client-impl.cpp | 137 +--- client/vasum-client-impl.hpp | 11 - client/zone-dbus-connection.cpp | 71 -- client/zone-dbus-connection.hpp | 60 -- ...dbus-definitions.hpp => common-definitions.hpp} | 26 +- server/configs/lxc-templates/template.sh | 1 - server/configs/templates/default.conf | 1 - server/host-dbus-connection.cpp | 141 ++-- server/host-dbus-connection.hpp | 37 + server/host-dbus-definitions.hpp | 48 +- server/host-ipc-connection.cpp | 244 +++---- server/host-ipc-connection.hpp | 102 ++- server/host-ipc-definitions.hpp | 15 +- server/ipc-callback-wrapper.hpp | 107 +++ server/zone-config.hpp | 7 - server/zone-connection-transport.cpp | 125 ---- server/zone-connection-transport.hpp | 63 -- server/zone-connection.cpp | 263 -------- server/zone-connection.hpp | 137 ---- server/zone-dbus-definitions.hpp | 85 --- server/zone.cpp | 195 +----- server/zone.hpp | 82 +-- server/zones-manager.cpp | 179 +++-- server/zones-manager.hpp | 17 +- tests/unit_tests/client/configs/CMakeLists.txt | 2 + .../ut-client/templates/console-dbus.conf.in | 1 - .../ut-client/templates/console-ipc.conf.in | 18 + tests/unit_tests/client/ut-client.cpp | 115 +--- tests/unit_tests/lxc/templates/minimal-dbus.sh | 1 - tests/unit_tests/server/configs/CMakeLists.txt | 7 +- .../configs/ut-server/templates/default.conf | 1 - .../configs/ut-zone-admin/templates/buggy.conf | 1 - .../configs/ut-zone-admin/templates/missing.conf | 1 - .../ut-zone-admin/templates/test-no-shutdown.conf | 1 - .../configs/ut-zone-admin/templates/test.conf | 1 - .../server/configs/ut-zone-connection/ut-dbus.conf | 18 - .../server/configs/ut-zone/templates/buggy.conf | 1 - .../configs/ut-zone/templates/test-dbus.conf.in | 1 - .../server/configs/ut-zone/templates/test.conf | 1 - .../templates/console-dbus.conf.in | 1 - .../ut-zones-manager/templates/console-ipc.conf.in | 18 + .../ut-zones-manager/templates/console.conf | 1 - tests/unit_tests/server/ut-zone-connection.cpp | 234 ------- tests/unit_tests/server/ut-zone.cpp | 3 +- tests/unit_tests/server/ut-zones-manager.cpp | 746 ++++++--------------- 53 files changed, 1021 insertions(+), 3189 deletions(-) delete mode 100644 client/dbus-connection.cpp delete mode 100644 client/dbus-connection.hpp delete mode 100644 client/host-dbus-connection.cpp delete mode 100644 client/host-dbus-connection.hpp delete mode 100644 client/ipc-connection.cpp delete mode 100644 client/ipc-connection.hpp delete mode 100644 client/zone-dbus-connection.cpp delete mode 100644 client/zone-dbus-connection.hpp rename server/{common-dbus-definitions.hpp => common-definitions.hpp} (52%) create mode 100644 server/ipc-callback-wrapper.hpp delete mode 100644 server/zone-connection-transport.cpp delete mode 100644 server/zone-connection-transport.hpp delete mode 100644 server/zone-connection.cpp delete mode 100644 server/zone-connection.hpp delete mode 100644 server/zone-dbus-definitions.hpp create mode 100644 tests/unit_tests/client/configs/ut-client/templates/console-ipc.conf.in delete mode 100644 tests/unit_tests/server/configs/ut-zone-connection/ut-dbus.conf create mode 100644 tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in delete mode 100644 tests/unit_tests/server/ut-zone-connection.cpp diff --git a/client/dbus-connection.cpp b/client/dbus-connection.cpp deleted file mode 100644 index b52bd71..0000000 --- a/client/dbus-connection.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2015 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 SimpleDbus's wrapper - */ - -#include -#include "dbus-connection.hpp" -#include "exception.hpp" -#include -#include - -using namespace vasum::client; - - -DbusConnection::DbusConnection(const std::string& definition, - const std::string& busName, - const std::string& objectPath, - const std::string& interface) - : mDefinition(definition) - , mBusName(busName) - , mObjectPath(objectPath) - , mInterface(interface) -{ -} - -DbusConnection::~DbusConnection() -{ -} - -void DbusConnection::create(const std::shared_ptr& connection) -{ - mConnection = connection; -} - -void DbusConnection::callMethod(const std::string& method, - GVariant* args_in, - const std::string& args_spec_out, - GVariant** args_out) -{ - dbus::GVariantPtr ret = mConnection->callMethod(mBusName, - mObjectPath, - mInterface, - method, - args_in, - args_spec_out); - if (args_out != NULL) { - *args_out = ret.release(); - } -} - -DbusConnection::SubscriptionId DbusConnection::signalSubscribe(const std::string& signal, - const SignalCallback& signalCallback) -{ - auto onSignal = [this, signal, signalCallback](const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant * parameters) { - if (objectPath == mObjectPath && - interface == mInterface && - signalName == signal) { - - signalCallback(parameters); - } - }; - return mConnection->signalSubscribe(onSignal, mBusName); -} - -void DbusConnection::signalUnsubscribe(SubscriptionId id) -{ - mConnection->signalUnsubscribe(id); -} - -std::string DbusConnection::getArgsOutSpec(const std::string& methodName) -{ - //TODO: Information about output argumnets of all methods can be computed in constuctor - GError *error = NULL; - GDBusNodeInfo* nodeInfo = g_dbus_node_info_new_for_xml(mDefinition.c_str(), &error); - if (error) { - std::string msg = error->message; - g_error_free (error); - throw ClientException("Invalid xml: " + msg); - } - GDBusInterfaceInfo* interfaceInfo = g_dbus_node_info_lookup_interface(nodeInfo, mInterface.c_str()); - if (interfaceInfo == NULL) { - throw ClientException("Invalid xml: can't find interface: " + mInterface); - } - GDBusMethodInfo* methodInfo = g_dbus_interface_info_lookup_method(interfaceInfo, methodName.c_str()); - if (methodInfo == NULL) { - throw ClientException("Invalid xml: can't find method: " + methodName); - } - - std::string signature; - for (GDBusArgInfo** argInfo = methodInfo->out_args; *argInfo; ++argInfo) { - signature += (*argInfo)->signature; - } - g_dbus_node_info_unref(nodeInfo); - return "(" + signature + ")"; -} diff --git a/client/dbus-connection.hpp b/client/dbus-connection.hpp deleted file mode 100644 index 3cb37ad..0000000 --- a/client/dbus-connection.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2015 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 SimpleDbus's wrapper - */ - -#ifndef VASUM_CLIENT_DBUS_CONNECTION_HPP -#define VASUM_CLIENT_DBUS_CONNECTION_HPP - -#include -#include -#include -#include -#include -#include - -namespace vasum { -namespace client { - -/** - * SimpleDbus client definition. - * - * DbusConnection uses SimpleDbus API. - */ -class DbusConnection { -public: - typedef unsigned int SubscriptionId; - - DbusConnection(const std::string& definition, - const std::string& busName, - const std::string& objectPath, - const std::string& interface); - virtual ~DbusConnection(); - void create(const std::shared_ptr& connection); - - template - typename std::enable_if::value>::type - call(const std::string& method, const ArgIn& argIn, ArgOut& argOut); - - template - typename std::enable_if::value>::type - call(const std::string& method, const ArgIn& argIn, ArgOut& argOut); - - template - typename std::enable_if::value>::type - call(const std::string& method, ArgOut& argOut) { - vasum::api::Void argIn; - call(method, argIn, argOut); - } - - template - typename std::enable_if::value>::type - call(const std::string& method, ArgIn& argIn) { - vasum::api::Void argOut; - call(method, argIn, argOut); - } - - template - SubscriptionId signalSubscribe(const std::string& signal, - const std::function& signalCallback); - void signalUnsubscribe(SubscriptionId id); - -private: - typedef std::function SignalCallback; - - std::shared_ptr mConnection; - const std::string mDefinition; - const std::string mBusName; - const std::string mObjectPath; - const std::string mInterface; - - void callMethod(const std::string& method, - GVariant* args_in, - const std::string& args_spec_out, - GVariant** args_out); - SubscriptionId signalSubscribe(const std::string& signal, const SignalCallback& signalCallback); - - /** - * Get signature of method output parameters - */ - std::string getArgsOutSpec(const std::string& methodName); -}; - -template -typename std::enable_if::value>::type -DbusConnection::call(const std::string& method, const ArgIn& argIn, ArgOut& argOut) -{ - GVariant* gArgOut = NULL; - callMethod(method, config::saveToGVariant(argIn), getArgsOutSpec(method), &gArgOut); - config::loadFromGVariant(gArgOut, argOut); - g_variant_unref(gArgOut); -} - -template -typename std::enable_if::value>::type -DbusConnection::call(const std::string& method, const ArgIn& argIn, ArgOut& /* argOut */) -{ - callMethod(method, config::saveToGVariant(argIn), "", NULL); -} - -template -DbusConnection::SubscriptionId DbusConnection::signalSubscribe(const std::string& signal, - const std::function& signalCallback) -{ - SignalCallback callback = [signalCallback](GVariant* parameters) { - Arg param; - config::loadFromGVariant(parameters, param); - signalCallback(param); - }; - return signalSubscribe(signal, callback); -} - -} // namespace client -} // namespace vasum - -#endif /* VASUM_CLIENT_DBUS_CONNECTION_HPP */ diff --git a/client/host-dbus-connection.cpp b/client/host-dbus-connection.cpp deleted file mode 100644 index 1f375a0..0000000 --- a/client/host-dbus-connection.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2015 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 Host client class - */ - - -#include -#include "host-dbus-connection.hpp" -#include -#include - -namespace vasum { -namespace client { - -HostDbusConnection::HostDbusConnection() - : mConnection(vasum::api::host::DEFINITION, - vasum::api::host::BUS_NAME, - vasum::api::host::OBJECT_PATH, - vasum::api::host::INTERFACE) -{ -} - -void HostDbusConnection::create(const std::shared_ptr& connection) -{ - mConnection.create(connection); -} - -void HostDbusConnection::callGetZoneIds(vasum::api::ZoneIds& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_ZONE_ID_LIST, argOut); -} - -void HostDbusConnection::callGetActiveZoneId(vasum::api::ZoneId& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_ACTIVE_ZONE_ID, argOut); -} - -void HostDbusConnection::callSetActiveZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_SET_ACTIVE_ZONE, argIn); -} - -void HostDbusConnection::callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_ZONE_INFO, argIn, argOut); -} - -void HostDbusConnection::callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_SET_NETDEV_ATTRS, argIn); -} - -void HostDbusConnection::callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_NETDEV_ATTRS, argIn, argOut); -} - -void HostDbusConnection::callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_NETDEV_LIST, argIn, argOut); -} - -void HostDbusConnection::callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_VETH, argIn); -} - -void HostDbusConnection::callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_MACVLAN, argIn); -} - -void HostDbusConnection::callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_PHYS, argIn); -} - -void HostDbusConnection::callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_DESTROY_NETDEV, argIn); -} - -void HostDbusConnection::callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, argIn); -} - -void HostDbusConnection::callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut) -{ - mConnection.call(vasum::api::host::METHOD_DECLARE_FILE, argIn, argOut); -} - -void HostDbusConnection::callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut) -{ - mConnection.call(vasum::api::host::METHOD_DECLARE_MOUNT, argIn, argOut); -} - -void HostDbusConnection::callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut) -{ - mConnection.call(vasum::api::host::METHOD_DECLARE_LINK, argIn, argOut); -} - -void HostDbusConnection::callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_DECLARATIONS, argIn, argOut); -} - -void HostDbusConnection::callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_REMOVE_DECLARATION, argIn); -} - -void HostDbusConnection::callCreateZone(const vasum::api::CreateZoneIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_CREATE_ZONE, argIn); -} - -void HostDbusConnection::callDestroyZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_DESTROY_ZONE, argIn); -} - -void HostDbusConnection::callShutdownZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_SHUTDOWN_ZONE, argIn); -} - -void HostDbusConnection::callStartZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_START_ZONE, argIn); -} - -void HostDbusConnection::callLockZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_LOCK_ZONE, argIn); -} - -void HostDbusConnection::callUnlockZone(const vasum::api::ZoneId& argIn) -{ - mConnection.call(vasum::api::host::METHOD_UNLOCK_ZONE, argIn); -} - -void HostDbusConnection::callGrantDevice(const vasum::api::GrantDeviceIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_GRANT_DEVICE, argIn); -} - -void HostDbusConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn) -{ - mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); -} - -void HostDbusConnection::callGetZoneConnections(vasum::api::Connections& argOut) -{ - mConnection.call(vasum::api::host::METHOD_GET_ZONE_CONNECTIONS, argOut); -} - -HostDbusConnection::SubscriptionId -HostDbusConnection::subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback) -{ - return mConnection.signalSubscribe( - vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE, callback); -} - -void HostDbusConnection::unsubscribe(const SubscriptionId& id) -{ - mConnection.signalUnsubscribe(id); -} - -} // namespace client -} // namespace vasum diff --git a/client/host-dbus-connection.hpp b/client/host-dbus-connection.hpp deleted file mode 100644 index 8785fa0..0000000 --- a/client/host-dbus-connection.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2015 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 Host client class - */ - -#ifndef VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP -#define VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP - -#include "dbus-connection.hpp" -#include - -namespace vasum { -namespace client { - -/** - * vasum's client definition. - * - * HostDbusConnection is used for communication with the vasum's server from host through dbus - */ -class HostDbusConnection { -public: - typedef unsigned int SubscriptionId; - typedef std::function ZoneConnectionStateCallback; - - HostDbusConnection(); - - void create(const std::shared_ptr& connection); - - void callGetZoneIds(vasum::api::ZoneIds& argOut); - void callGetActiveZoneId(vasum::api::ZoneId& argOut); - void callSetActiveZone(const vasum::api::ZoneId& argIn); - void callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut); - void callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn); - void callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut); - void callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut); - void callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn); - void callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn); - void callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn); - void callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn); - void callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn); - void callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut); - void callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut); - void callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut); - void callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut); - void callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn); - void callCreateZone(const vasum::api::CreateZoneIn& argIn); - void callDestroyZone(const vasum::api::ZoneId& argIn); - void callShutdownZone(const vasum::api::ZoneId& argIn); - void callStartZone(const vasum::api::ZoneId& argIn); - void callLockZone(const vasum::api::ZoneId& argIn); - void callUnlockZone(const vasum::api::ZoneId& argIn); - void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); - void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); - void callGetZoneConnections(vasum::api::Connections& argOut); - SubscriptionId subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback); - void unsubscribe(const SubscriptionId& id); -private: - DbusConnection mConnection; -}; - -} // namespace client -} // namespace vasum - -#endif /* VASUM_CLIENT_HOST_DBUS_CONNECTION_HPP */ diff --git a/client/host-ipc-connection.cpp b/client/host-ipc-connection.cpp index adb44eb..121f7ad 100644 --- a/client/host-ipc-connection.cpp +++ b/client/host-ipc-connection.cpp @@ -33,150 +33,228 @@ namespace client { void HostIPCConnection::createSystem() { - mConnection.createSystem(); + mClient.reset(new ipc::Client(mDispatcher.getPoll(), HOST_IPC_SOCKET)); + mClient->start(); } -void HostIPCConnection::callGetZoneIds(vasum::api::ZoneIds& argOut) +void HostIPCConnection::create(const std::string& address) { - mConnection.call(vasum::api::host::METHOD_GET_ZONE_ID_LIST, argOut); + mClient.reset(new ipc::Client(mDispatcher.getPoll(), address)); + mClient->start(); } -void HostIPCConnection::callGetActiveZoneId(vasum::api::ZoneId& argOut) +void HostIPCConnection::callGetZoneIds(api::ZoneIds& argOut) { - mConnection.call(vasum::api::host::METHOD_GET_ACTIVE_ZONE_ID, argOut); + api::Void argVoid; + call(api::METHOD_GET_ZONE_ID_LIST, argVoid, argOut); } -void HostIPCConnection::callSetActiveZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callGetActiveZoneId(api::ZoneId& argOut) { - mConnection.call(vasum::api::host::METHOD_SET_ACTIVE_ZONE, argIn); + api::Void argVoid; + call(api::METHOD_GET_ACTIVE_ZONE_ID, argVoid, argOut); } -void HostIPCConnection::callGetZoneInfo(const vasum::api::ZoneId& argIn, vasum::api::ZoneInfoOut& argOut) +void HostIPCConnection::callSetActiveZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_GET_ZONE_INFO, argIn, argOut); + mClient->callSync( + api::METHOD_SET_ACTIVE_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callSetNetdevAttrs(const vasum::api::SetNetDevAttrsIn& argIn) +void HostIPCConnection::callGetZoneInfo(const api::ZoneId& argIn, api::ZoneInfoOut& argOut) { - mConnection.call(vasum::api::host::METHOD_SET_NETDEV_ATTRS, argIn); + argOut = *mClient->callSync( + api::METHOD_GET_ZONE_INFO, + std::make_shared(argIn)); } -void HostIPCConnection::callGetNetdevAttrs(const vasum::api::GetNetDevAttrsIn& argIn, vasum::api::GetNetDevAttrs& argOut) +void HostIPCConnection::callSetNetdevAttrs(const api::SetNetDevAttrsIn& argIn) { - mConnection.call(vasum::api::host::METHOD_GET_NETDEV_ATTRS, argIn, argOut); + mClient->callSync( + api::METHOD_SET_NETDEV_ATTRS, + std::make_shared(argIn)); + + api::Void argVoid; + call(api::METHOD_SET_NETDEV_ATTRS, argIn, argVoid); +} + +void HostIPCConnection::callGetNetdevAttrs(const api::GetNetDevAttrsIn& argIn, api::GetNetDevAttrs& argOut) +{ + argOut = *mClient->callSync( + api::METHOD_GET_NETDEV_ATTRS, + std::make_shared(argIn)); } -void HostIPCConnection::callGetNetdevList(const vasum::api::ZoneId& argIn, vasum::api::NetDevList& argOut) +void HostIPCConnection::callGetNetdevList(const api::ZoneId& argIn, api::NetDevList& argOut) { - mConnection.call(vasum::api::host::METHOD_GET_NETDEV_LIST, argIn, argOut); + argOut = *mClient->callSync( + api::METHOD_GET_NETDEV_LIST, + std::make_shared(argIn)); } -void HostIPCConnection::callCreateNetdevVeth(const vasum::api::CreateNetDevVethIn& argIn) +void HostIPCConnection::callCreateNetdevVeth(const api::CreateNetDevVethIn& argIn) { - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_VETH, argIn); + mClient->callSync( + api::METHOD_CREATE_NETDEV_VETH, + std::make_shared(argIn)); } -void HostIPCConnection::callCreateNetdevMacvlan(const vasum::api::CreateNetDevMacvlanIn& argIn) +void HostIPCConnection::callCreateNetdevMacvlan(const api::CreateNetDevMacvlanIn& argIn) { - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_MACVLAN, argIn); + mClient->callSync( + api::METHOD_CREATE_NETDEV_MACVLAN, + std::make_shared(argIn)); } -void HostIPCConnection::callCreateNetdevPhys(const vasum::api::CreateNetDevPhysIn& argIn) +void HostIPCConnection::callCreateNetdevPhys(const api::CreateNetDevPhysIn& argIn) { - mConnection.call(vasum::api::host::METHOD_CREATE_NETDEV_PHYS, argIn); + mClient->callSync( + api::METHOD_CREATE_NETDEV_PHYS, + std::make_shared(argIn)); } -void HostIPCConnection::callDestroyNetdev(const vasum::api::DestroyNetDevIn& argIn) +void HostIPCConnection::callDestroyNetdev(const api::DestroyNetDevIn& argIn) { - mConnection.call(vasum::api::host::METHOD_DESTROY_NETDEV, argIn); + mClient->callSync( + api::METHOD_DESTROY_NETDEV, + std::make_shared(argIn)); } -void HostIPCConnection::callDeleteNetdevIpAddress(const vasum::api::DeleteNetdevIpAddressIn& argIn) +void HostIPCConnection::callDeleteNetdevIpAddress(const api::DeleteNetdevIpAddressIn& argIn) { - mConnection.call(vasum::api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, argIn); + mClient->callSync( + api::METHOD_DELETE_NETDEV_IP_ADDRESS, + std::make_shared(argIn)); } -void HostIPCConnection::callDeclareFile(const vasum::api::DeclareFileIn& argIn, vasum::api::Declaration& argOut) +void HostIPCConnection::callDeclareFile(const api::DeclareFileIn& argIn, api::Declaration& argOut) { - mConnection.call(vasum::api::host::METHOD_DECLARE_FILE, argIn, argOut); + argOut = *mClient->callSync( + api::METHOD_DECLARE_FILE, + std::make_shared(argIn)); } -void HostIPCConnection::callDeclareMount(const vasum::api::DeclareMountIn& argIn, vasum::api::Declaration& argOut) +void HostIPCConnection::callDeclareMount(const api::DeclareMountIn& argIn, api::Declaration& argOut) { - mConnection.call(vasum::api::host::METHOD_DECLARE_MOUNT, argIn, argOut); + argOut = *mClient->callSync( + api::METHOD_DECLARE_MOUNT, + std::make_shared(argIn)); } -void HostIPCConnection::callDeclareLink(const vasum::api::DeclareLinkIn& argIn, vasum::api::Declaration& argOut) +void HostIPCConnection::callDeclareLink(const api::DeclareLinkIn& argIn, api::Declaration& argOut) { - mConnection.call(vasum::api::host::METHOD_DECLARE_LINK, argIn, argOut); + argOut = *mClient->callSync( + api::METHOD_DECLARE_LINK, + std::make_shared(argIn)); } -void HostIPCConnection::callGetDeclarations(const vasum::api::ZoneId& argIn, vasum::api::Declarations& argOut) +void HostIPCConnection::callGetDeclarations(const api::ZoneId& argIn, api::Declarations& argOut) { - mConnection.call(vasum::api::host::METHOD_GET_DECLARATIONS, argIn, argOut); + argOut = *mClient->callSync( + api::METHOD_GET_DECLARATIONS, + std::make_shared(argIn)); } -void HostIPCConnection::callRemoveDeclaration(const vasum::api::RemoveDeclarationIn& argIn) +void HostIPCConnection::callRemoveDeclaration(const api::RemoveDeclarationIn& argIn) { - mConnection.call(vasum::api::host::METHOD_REMOVE_DECLARATION, argIn); + mClient->callSync( + api::METHOD_REMOVE_DECLARATION, + std::make_shared(argIn)); } -void HostIPCConnection::callCreateZone(const vasum::api::CreateZoneIn& argIn) +void HostIPCConnection::callCreateZone(const api::CreateZoneIn& argIn) { - mConnection.call(vasum::api::host::METHOD_CREATE_ZONE, argIn); + mClient->callSync( + api::METHOD_CREATE_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callDestroyZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callDestroyZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_DESTROY_ZONE, argIn); + mClient->callSync( + api::METHOD_DESTROY_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callShutdownZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callShutdownZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_SHUTDOWN_ZONE, argIn); + mClient->callSync( + api::METHOD_SHUTDOWN_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callStartZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callStartZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_START_ZONE, argIn); + mClient->callSync( + api::METHOD_START_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callLockZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callLockZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_LOCK_ZONE, argIn); + mClient->callSync( + api::METHOD_LOCK_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callUnlockZone(const vasum::api::ZoneId& argIn) +void HostIPCConnection::callUnlockZone(const api::ZoneId& argIn) { - mConnection.call(vasum::api::host::METHOD_UNLOCK_ZONE, argIn); + mClient->callSync( + api::METHOD_UNLOCK_ZONE, + std::make_shared(argIn)); } -void HostIPCConnection::callGrantDevice(const vasum::api::GrantDeviceIn& argIn) +void HostIPCConnection::callGrantDevice(const api::GrantDeviceIn& argIn) { - mConnection.call(vasum::api::host::METHOD_GRANT_DEVICE, argIn); + mClient->callSync( + api::METHOD_GRANT_DEVICE, + std::make_shared(argIn)); } -void HostIPCConnection::callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn) +void HostIPCConnection::callRevokeDevice(const api::RevokeDeviceIn& argIn) { - mConnection.call(vasum::api::host::METHOD_REVOKE_DEVICE, argIn); + mClient->callSync( + api::METHOD_REVOKE_DEVICE, + std::make_shared(argIn)); } -void HostIPCConnection::callGetZoneConnections(vasum::api::Connections& argOut) +void HostIPCConnection::callNotifyActiveZone(const api::NotifActiveZoneIn& argIn) { - mConnection.call(vasum::api::host::METHOD_GET_ZONE_CONNECTIONS, argOut); + mClient->callSync( + api::METHOD_NOTIFY_ACTIVE_ZONE, + std::make_shared(argIn)); +} + +void HostIPCConnection::callFileMoveRequest(const api::FileMoveRequestIn& argIn, + api::FileMoveRequestStatus& argOut) +{ + argOut = *mClient->callSync( + api::METHOD_FILE_MOVE_REQUEST, + std::make_shared(argIn)); +} + +void HostIPCConnection::signalSwitchToDefault() +{ + + mClient->signal(api::SIGNAL_SWITCH_TO_DEFAULT, + std::make_shared()); } HostIPCConnection::SubscriptionId -HostIPCConnection::subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback) +HostIPCConnection::subscribeNotification(const NotificationCallback& callback) { - mConnection.subscribe( - vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE, callback); - return vasum::api::host::SIGNAL_ZONE_CONNECTION_STATE; + auto callbackWrapper = [callback] (const ipc::PeerID, + std::shared_ptr& data) { + callback(*data); + }; + mClient->setSignalHandler(api::SIGNAL_NOTIFICATION, callbackWrapper); + return api::SIGNAL_NOTIFICATION; } void HostIPCConnection::unsubscribe(const SubscriptionId& id) { - mConnection.unsubscribe(id); + mClient->removeMethod(id); } } // namespace client diff --git a/client/host-ipc-connection.hpp b/client/host-ipc-connection.hpp index 216e976..8fa6e06 100644 --- a/client/host-ipc-connection.hpp +++ b/client/host-ipc-connection.hpp @@ -26,8 +26,11 @@ #ifndef VASUM_CLIENT_HOST_IPC_CONNECTION_HPP #define VASUM_CLIENT_HOST_IPC_CONNECTION_HPP -#include "ipc-connection.hpp" #include +#include +#include + +#include namespace vasum { namespace client { @@ -38,8 +41,9 @@ namespace client { class HostIPCConnection { public: typedef unsigned int SubscriptionId; - typedef std::function ZoneConnectionStateCallback; + typedef std::function NotificationCallback; void createSystem(); + void create(const std::string& address); void callGetZoneIds(vasum::api::ZoneIds& argOut); void callGetActiveZoneId(vasum::api::ZoneId& argOut); @@ -67,11 +71,22 @@ public: void callGrantDevice(const vasum::api::GrantDeviceIn& argIn); void callRevokeDevice(const vasum::api::RevokeDeviceIn& argIn); void callGetZoneConnections(vasum::api::Connections& argOut); - SubscriptionId subscribeZoneConnectionState(const ZoneConnectionStateCallback& callback); + void callNotifyActiveZone(const vasum::api::NotifActiveZoneIn& argIn); + void callFileMoveRequest(const vasum::api::FileMoveRequestIn& argIn, + vasum::api::FileMoveRequestStatus& argOut); + void signalSwitchToDefault(); + SubscriptionId subscribeNotification(const NotificationCallback& callback); void unsubscribe(const SubscriptionId& id); private: - IPCConnection mConnection; + epoll::ThreadDispatcher mDispatcher; + std::unique_ptr mClient; + + template + void call(const ipc::MethodID method, const ArgIn& argIn, ArgOut& argOut, int timeout = 5000) { + auto out = mClient->callSync(method, std::make_shared(argIn), timeout); + argOut = *out; + } }; } // namespace client diff --git a/client/ipc-connection.cpp b/client/ipc-connection.cpp deleted file mode 100644 index 04954bc..0000000 --- a/client/ipc-connection.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2015 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 IPCConnection class - */ - -#include -#include "ipc-connection.hpp" - -namespace { - -const std::string SOCKET_PATH = HOST_IPC_SOCKET; - -} // namespace - -vasum::client::IPCConnection::IPCConnection() -{ -} - -vasum::client::IPCConnection::~IPCConnection() -{ -} - -void vasum::client::IPCConnection::createSystem() -{ - mClient.reset(new ipc::Client(mDispatcher.getPoll(), SOCKET_PATH)); - mClient->start(); -} diff --git a/client/ipc-connection.hpp b/client/ipc-connection.hpp deleted file mode 100644 index 1cb4d10..0000000 --- a/client/ipc-connection.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2015 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 IPCConnection class - */ - -#ifndef VASUM_CLIENT_IPC_CONNECTION_HPP -#define VASUM_CLIENT_IPC_CONNECTION_HPP - -#include -#include -#include -#include -#include -#include - -namespace vasum { -namespace client { - -/** - * IPCConnection class - */ -class IPCConnection { -public: - IPCConnection(); - virtual ~IPCConnection(); - - void createSystem(); - - template - typename std::enable_if::value>::type - call(const ipc::MethodID method, const ArgIn& argIn, ArgOut& argOut, unsigned int timeout = 50000) { - auto out = mClient->callSync(method, std::make_shared(argIn), timeout); - argOut = *out; - } - - template - typename std::enable_if::value>::type - call(const ipc::MethodID method, ArgOut& argOut, unsigned int timeout = 50000) { - vasum::api::Void argIn; - call(method, argIn, argOut, timeout); - } - - template - typename std::enable_if::value>::type - call(const ipc::MethodID method, ArgIn& argIn, unsigned int timeout = 50000) { - vasum::api::Void argOut; - call(method, argIn, argOut, timeout); - } - - template - void subscribe(const ipc::MethodID signal, const Callback& callback) { - auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { - callback(*data); - }; - mClient->setSignalHandler(signal, callbackWrapper); - } - - void unsubscribe(const ipc::MethodID signal) { - mClient->removeMethod(signal); - } - -private: - epoll::ThreadDispatcher mDispatcher; - std::unique_ptr mClient; -}; - -} // namespace client -} // namespace vasum - -#endif /* VASUM_CLIENT_IPC_CONNECTION_HPP */ diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 49b5846..8866e5f 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -27,14 +27,7 @@ #include "vasum-client-impl.hpp" #include "utils.hpp" #include "exception.hpp" -#include "host-dbus-connection.hpp" #include "host-ipc-connection.hpp" -#include "zone-dbus-connection.hpp" -#include - -#include -#include -#include #include #include @@ -52,8 +45,6 @@ using namespace vasum; namespace { -unique_ptr gGlibLoop; - VsmZoneState getZoneState(const char* state) { if (strcmp(state, "STOPPED") == 0) { @@ -90,16 +81,6 @@ void convert(const api::VectorOfStrings& in, VsmArrayString& out) } } -void convert(const api::VectorOfStringPairs& in, VsmArrayString& keys, VsmArrayString& values) -{ - keys = reinterpret_cast(calloc(in.values.size() + 1, sizeof(char*))); - values = reinterpret_cast(calloc(in.values.size() + 1, sizeof(char*))); - for (size_t i = 0; i < in.values.size(); ++i) { - keys[i] = ::strdup(in.values[i].first.c_str()); - values[i] = ::strdup(in.values[i].second.c_str()); - } -} - void convert(const api::ZoneInfoOut& info, VsmZone& zone) { VsmZone vsmZone = reinterpret_cast(malloc(sizeof(*vsmZone))); @@ -145,23 +126,13 @@ bool readFirstLineOfFile(const string& path, string& ret) VsmStatus Client::vsm_start_glib_loop() noexcept { - try { - if (!gGlibLoop) { - gGlibLoop.reset(new utils::ScopedGlibLoop()); - } - } catch (const exception&) { - return VSMCLIENT_OTHER_ERROR; - } + // TPDP: Remove vsm_start_glib_loop from API return VSMCLIENT_SUCCESS; } VsmStatus Client::vsm_stop_glib_loop() noexcept { - try { - gGlibLoop.reset(); - } catch (const exception&) { - return VSMCLIENT_OTHER_ERROR; - } + // TPDP: Remove vsm_stop_glib_loop from API return VSMCLIENT_SUCCESS; } @@ -198,16 +169,10 @@ VsmStatus Client::coverException(const function& worker) noexcept mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what()); } catch (const vasum::ClientException& ex) { mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); - } catch (const dbus::DbusCustomException& ex) { + } catch (const ipc::IPCUserException& ex) { mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); - } catch (const dbus::DbusIOException& ex) { + } catch (const ipc::IPCException& ex) { mStatus = Status(VSMCLIENT_IO_ERROR, ex.what()); - } catch (const dbus::DbusOperationException& ex) { - mStatus = Status(VSMCLIENT_OPERATION_FAILED, ex.what()); - } catch (const dbus::DbusInvalidArgumentException& ex) { - mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what()); - } catch (const dbus::DbusException& ex) { - mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what()); } catch (const exception& ex) { mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what()); } @@ -217,28 +182,14 @@ VsmStatus Client::coverException(const function& worker) noexcept VsmStatus Client::createSystem() noexcept { return coverException([&] { - shared_ptr connection(dbus::DbusConnection::createSystem().release()); - -#ifdef DBUS_CONNECTION - mHostClient.create(connection); -#else mHostClient.createSystem(); -#endif - mZoneClient.create(connection); }); } VsmStatus Client::create(const string& address) noexcept { return coverException([&] { - shared_ptr connection(dbus::DbusConnection::create(address).release()); - -#ifdef DBUS_CONNECTION - mHostClient.create(connection); -#else - mHostClient.createSystem(); -#endif - mZoneClient.create(connection); + mHostClient.create(address); }); } @@ -252,15 +203,11 @@ VsmStatus Client::vsm_get_status() const noexcept return mStatus.mVsmStatus; } -VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* keys, VsmArrayString* values) noexcept +VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* /*keys*/, VsmArrayString* /*values*/) noexcept { - assert(keys); - assert(values); - return coverException([&] { - api::Connections dbuses; - mHostClient.callGetZoneConnections(dbuses); - convert(dbuses, *keys, *values); + //TODO: Remove vsm_get_zone_dbuses from API + throw OperationFailedException("Not implemented"); }); } @@ -322,6 +269,7 @@ VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept VsmStatus Client::vsm_lookup_zone_by_terminal_id(int, VsmString*) noexcept { return coverException([&] { + //TODO: Implement vsm_lookup_zone_by_terminal_id throw OperationFailedException("Not implemented"); }); } @@ -390,25 +338,13 @@ VsmStatus Client::vsm_unlock_zone(const char* id) noexcept }); } -VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback zoneDbusStateCallback, - void* data, - VsmSubscriptionId* subscriptionId) noexcept +VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback /* zoneDbusStateCallback */, + void* /* data */, + VsmSubscriptionId* /* subscriptionId */) noexcept { - assert(zoneDbusStateCallback); - return coverException([&] { - auto onSigal = [=](const api::ConnectionState& dbus) - { - zoneDbusStateCallback(dbus.first.c_str(), - dbus.second.c_str(), - data); - }; - - VsmSubscriptionId id; - id = mHostClient.subscribeZoneConnectionState(onSigal); - if (subscriptionId) { - *subscriptionId = id; - } + //TODO: Implement vsm_add_state_callback + throw OperationFailedException("Not implemented"); }); } @@ -758,57 +694,36 @@ VsmStatus Client::vsm_remove_declaration(const char* id, VsmString declaration) }); } -VsmStatus Client::vsm_notify_active_zone(const char* application, const char* message) noexcept +VsmStatus Client::vsm_notify_active_zone(const char* /*application*/, const char* /*message*/) noexcept { - assert(application); - assert(message); - return coverException([&] { - mZoneClient.callNotifyActiveZone({ application, message }); + //TODO: Implement vsm_notify_active_zone + throw OperationFailedException("Not implemented"); }); } -VsmStatus Client::vsm_file_move_request(const char* destZone, const char* path) noexcept +VsmStatus Client::vsm_file_move_request(const char* /*destZone*/, const char* /*path*/) noexcept { - assert(destZone); - assert(path); - return coverException([&] { - api::FileMoveRequestStatus status; - mZoneClient.callFileMoveRequest({ destZone, path }, status); - if (status.value != api::zone::FILE_MOVE_SUCCEEDED) { - throw ClientException(status.value); - } + //TODO: Implement vsm_file_move_request + throw OperationFailedException("Not implemented"); }); } -VsmStatus Client::vsm_add_notification_callback(VsmNotificationCallback notificationCallback, - void* data, - VsmSubscriptionId* subscriptionId) noexcept +VsmStatus Client::vsm_add_notification_callback(VsmNotificationCallback /*notificationCallback*/, + void* /*data*/, + VsmSubscriptionId* /*subscriptionId*/) noexcept { - assert(notificationCallback); - return coverException([&] { - auto onSignal = [=](const api::Notification& notification) - { - notificationCallback(notification.zone.c_str(), - notification.application.c_str(), - notification.message.c_str(), - data); - }; - - VsmSubscriptionId id; - id = mZoneClient.subscribeNotification(onSignal); - if (subscriptionId) { - *subscriptionId = id; - } + //TODO: Implement vsm_add_notification_callback + throw OperationFailedException("Not implemented"); }); } VsmStatus Client::vsm_del_notification_callback(VsmSubscriptionId subscriptionId) noexcept { return coverException([&] { - mZoneClient.unsubscribe(subscriptionId); + mHostClient.unsubscribe(subscriptionId); }); } diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 9e8118c..3f3b13a 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -27,12 +27,7 @@ #define VASUM_CLIENT_IMPL_HPP #include "vasum-client.h" -#ifdef DBUS_CONNECTION -#include "host-dbus-connection.hpp" -#else #include "host-ipc-connection.hpp" -#endif -#include "zone-dbus-connection.hpp" #include #include @@ -324,12 +319,7 @@ public: */ static VsmStatus vsm_stop_glib_loop() noexcept; private: -#ifdef DBUS_CONNECTION - typedef vasum::client::HostDbusConnection HostConnection; -#else typedef vasum::client::HostIPCConnection HostConnection; -#endif - typedef vasum::client::ZoneDbusConnection ZoneConnection; struct Status { Status(); Status(VsmStatus status, const std::string& msg = ""); @@ -340,7 +330,6 @@ private: Status mStatus; HostConnection mHostClient; - ZoneConnection mZoneClient; VsmStatus coverException(const std::function& worker) noexcept; VsmStatus vsm_netdev_get_ip_addr(const char* zone, diff --git a/client/zone-dbus-connection.cpp b/client/zone-dbus-connection.cpp deleted file mode 100644 index b7f82a8..0000000 --- a/client/zone-dbus-connection.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015 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 Zone client class - */ - -#include -#include "zone-dbus-connection.hpp" -#include -#include - -namespace vasum { -namespace client { - -ZoneDbusConnection::ZoneDbusConnection() - : mConnection(vasum::api::zone::DEFINITION, - vasum::api::zone::BUS_NAME, - vasum::api::zone::OBJECT_PATH, - vasum::api::zone::INTERFACE) -{ -} - -void ZoneDbusConnection::create(const std::shared_ptr& connection) -{ - mConnection.create(connection); -} - -void ZoneDbusConnection::callNotifyActiveZone(const vasum::api::NotifActiveZoneIn& argIn) -{ - mConnection.call(vasum::api::zone::METHOD_NOTIFY_ACTIVE_ZONE, argIn); -} - -void ZoneDbusConnection::callFileMoveRequest(const vasum::api::FileMoveRequestIn& argIn, - vasum::api::FileMoveRequestStatus& argOut) -{ - mConnection.call(vasum::api::zone::METHOD_FILE_MOVE_REQUEST, argIn, argOut); -} - -ZoneDbusConnection::SubscriptionId -ZoneDbusConnection::subscribeNotification(const NotificationCallback& callback) -{ - return mConnection.signalSubscribe( - vasum::api::zone::SIGNAL_NOTIFICATION, callback); -} - -void ZoneDbusConnection::unsubscribe(const SubscriptionId& id ) -{ - mConnection.signalUnsubscribe(id); -} - -} // namespace client -} // namespace vasum diff --git a/client/zone-dbus-connection.hpp b/client/zone-dbus-connection.hpp deleted file mode 100644 index 576b4cb..0000000 --- a/client/zone-dbus-connection.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015 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 Zone client class - */ - -#ifndef VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP -#define VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP - -#include "dbus-connection.hpp" -#include - -namespace vasum { -namespace client { - -/** - * vasum's client definition. - * - * ZoneDbusConnection is used for communication with the vasum's server from zone through dbus - */ -class ZoneDbusConnection { -public: - typedef unsigned int SubscriptionId; - typedef std::function NotificationCallback; - - ZoneDbusConnection(); - void create(const std::shared_ptr& connection); - - void callNotifyActiveZone(const vasum::api::NotifActiveZoneIn& argIn); - void callFileMoveRequest(const vasum::api::FileMoveRequestIn& argIn, - vasum::api::FileMoveRequestStatus& argOut); - SubscriptionId subscribeNotification(const NotificationCallback& callback); - void unsubscribe(const SubscriptionId& id); -private: - DbusConnection mConnection; -}; - -} // namespace client -} // namespace vasum - -#endif /* VASUM_CLIENT_ZONE_DBUS_CONNECTION_HPP */ diff --git a/server/common-dbus-definitions.hpp b/server/common-definitions.hpp similarity index 52% rename from server/common-dbus-definitions.hpp rename to server/common-definitions.hpp index 178f363..5e85f92 100644 --- a/server/common-dbus-definitions.hpp +++ b/server/common-definitions.hpp @@ -19,27 +19,33 @@ /** * @file * @author Jan Olszak (j.olszak@samsung.com) - * @brief Common dbus api definitions + * @brief Common (dbus, IPC) api definitions */ -#ifndef SERVER_COMMON_DBUS_DEFINITIONS_HPP -#define SERVER_COMMON_DBUS_DEFINITIONS_HPP +#ifndef SERVER_COMMON_DEFINITIONS_HPP +#define SERVER_COMMON_DEFINITIONS_HPP #include namespace vasum { namespace api { -const std::string ERROR_FORBIDDEN = "org.tizen.vasum.Error.Forbidden"; -const std::string ERROR_FORWARDED = "org.tizen.vasum.Error.Forwarded"; -const std::string ERROR_INVALID_ID = "org.tizen.vasum.Error.InvalidId"; -const std::string ERROR_INVALID_STATE = "org.tizen.vasum.Error.InvalidState"; -const std::string ERROR_INTERNAL = "org.tizen.vasum.Error.Internal"; -const std::string METHOD_PROXY_CALL = "ProxyCall"; +/** + * Error codes that can be set in API handlers + */ +//TODO: Errors should use exception handling mechanism +///@{ +const std::string ERROR_FORBIDDEN = "org.tizen.vasum.Error.Forbidden"; +const std::string ERROR_FORWARDED = "org.tizen.vasum.Error.Forwarded"; +const std::string ERROR_INVALID_ID = "org.tizen.vasum.Error.InvalidId"; +const std::string ERROR_INVALID_STATE = "org.tizen.vasum.Error.InvalidState"; +const std::string ERROR_INTERNAL = "org.tizen.vasum.Error.Internal"; +const std::string ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.Error.ZonesNotRunning"; +///@} } // namespace api } // namespace vasum -#endif // SERVER_COMMON_DBUS_DEFINITIONS_HPP +#endif // SERVER_COMMON_DEFINITIONS_HPP diff --git a/server/configs/lxc-templates/template.sh b/server/configs/lxc-templates/template.sh index e7d5533..82cd0f9 100755 --- a/server/configs/lxc-templates/template.sh +++ b/server/configs/lxc-templates/template.sh @@ -40,7 +40,6 @@ lxc.pts = 256 lxc.tty = 0 lxc.mount.auto = proc sys cgroup -lxc.mount.entry = /var/run/zones/${name}/run var/run none rw,bind 0 0 # create a separate network per zone # - it forbids traffic sniffing (like macvlan in bridge mode) diff --git a/server/configs/templates/default.conf b/server/configs/templates/default.conf index 3a99d20..ce88c6e 100644 --- a/server/configs/templates/default.conf +++ b/server/configs/templates/default.conf @@ -10,7 +10,6 @@ "vt" : 0, "shutdownTimeout" : 10, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "runMountPoint" : "~NAME~/run", "provisions" : [], "permittedToSend" : [ "/tmp/.*" ], diff --git a/server/host-dbus-connection.cpp b/server/host-dbus-connection.cpp index 76f5bb8..b93ad21 100644 --- a/server/host-dbus-connection.cpp +++ b/server/host-dbus-connection.cpp @@ -53,27 +53,31 @@ HostDbusConnection::HostDbusConnection() mDbusConnection = dbus::DbusConnection::createSystem(); LOGT("Setting DBUS name"); - mDbusConnection->setName(api::host::BUS_NAME, + mDbusConnection->setName(api::BUS_NAME, std::bind(&HostDbusConnection::onNameAcquired, this), std::bind(&HostDbusConnection::onNameLost, this)); if (!waitForName(NAME_ACQUIRED_TIMEOUT)) { - LOGE("Could not acquire dbus name: " << api::host::BUS_NAME); - throw HostConnectionException("Could not acquire dbus name: " + api::host::BUS_NAME); + LOGE("Could not acquire dbus name: " << api::BUS_NAME); + throw HostConnectionException("Could not acquire dbus name: " + api::BUS_NAME); } LOGT("Registering DBUS interface"); using namespace std::placeholders; - mDbusConnection->registerObject(api::host::OBJECT_PATH, - api::host::DEFINITION, + mDbusConnection->registerObject(api::OBJECT_PATH, + api::DEFINITION, std::bind(&HostDbusConnection::onMessageCall, - this, _1, _2, _3, _4, _5)); + this, _1, _2, _3, _4, _5)); + mSubscriptionId = mDbusConnection->signalSubscribe(std::bind(&HostDbusConnection::onSignalCall, + this, _1, _2, _3, _4, _5), + std::string()); LOGD("Connected"); } HostDbusConnection::~HostDbusConnection() { + mDbusConnection->signalUnsubscribe(mSubscriptionId); } bool HostDbusConnection::waitForName(const unsigned int timeoutMs) @@ -242,6 +246,20 @@ void HostDbusConnection::setRevokeDeviceCallback(const RevokeDeviceCallback& cal mRevokeDeviceCallback = callback; } +void HostDbusConnection::setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback) +{ + mNotifyActiveZoneCallback = callback; +} + +void HostDbusConnection::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) +{ + mSwitchToDefaultCallback = callback; +} + +void HostDbusConnection::setFileMoveCallback(const FileMoveCallback& callback) +{ + mFileMoveCallback = callback; +} void HostDbusConnection::onMessageCall(const std::string& objectPath, const std::string& interface, @@ -249,11 +267,11 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, GVariant* parameters, dbus::MethodResultBuilder::Pointer result) { - if (objectPath != api::host::OBJECT_PATH || interface != api::host::INTERFACE) { + if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) { return; } - if (methodName == api::host::METHOD_SET_ACTIVE_ZONE) { + if (methodName == api::METHOD_SET_ACTIVE_ZONE) { api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); @@ -264,14 +282,6 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_ZONE_CONNECTIONS) { - if (mGetZoneConnectionsCallback) { - auto rb = std::make_shared>(result); - mGetZoneConnectionsCallback(rb); - } - return; - } - if (methodName == api::METHOD_PROXY_CALL) { const gchar* target = NULL; const gchar* targetBusName = NULL; @@ -301,7 +311,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_ZONE_ID_LIST) { + if (methodName == api::METHOD_GET_ZONE_ID_LIST) { if (mGetZoneIdsCallback) { auto rb = std::make_shared>(result); mGetZoneIdsCallback(rb); @@ -309,7 +319,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_ACTIVE_ZONE_ID) { + if (methodName == api::METHOD_GET_ACTIVE_ZONE_ID) { if (mGetActiveZoneIdCallback) { auto rb = std::make_shared>(result); mGetActiveZoneIdCallback(rb); @@ -317,7 +327,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_ZONE_INFO) { + if (methodName == api::METHOD_GET_ZONE_INFO) { api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); @@ -328,7 +338,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_SET_NETDEV_ATTRS) { + if (methodName == api::METHOD_SET_NETDEV_ATTRS) { api::SetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); @@ -339,7 +349,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_NETDEV_ATTRS) { + if (methodName == api::METHOD_GET_NETDEV_ATTRS) { api::GetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); @@ -350,7 +360,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_NETDEV_LIST) { + if (methodName == api::METHOD_GET_NETDEV_LIST) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -361,7 +371,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_CREATE_NETDEV_VETH) { + if (methodName == api::METHOD_CREATE_NETDEV_VETH) { api::CreateNetDevVethIn data; config::loadFromGVariant(parameters, data); @@ -372,7 +382,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_CREATE_NETDEV_MACVLAN) { + if (methodName == api::METHOD_CREATE_NETDEV_MACVLAN) { api::CreateNetDevMacvlanIn data; config::loadFromGVariant(parameters, data); @@ -382,7 +392,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_CREATE_NETDEV_PHYS) { + if (methodName == api::METHOD_CREATE_NETDEV_PHYS) { api::CreateNetDevPhysIn data; config::loadFromGVariant(parameters, data); @@ -392,7 +402,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_DESTROY_NETDEV) { + if (methodName == api::METHOD_DESTROY_NETDEV) { api::DestroyNetDevIn data; config::loadFromGVariant(parameters, data); @@ -402,7 +412,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_DELETE_NETDEV_IP_ADDRESS) { + if (methodName == api::METHOD_DELETE_NETDEV_IP_ADDRESS) { api::DeleteNetdevIpAddressIn data; config::loadFromGVariant(parameters, data); if (mDeleteNetdevIpAddressCallback) { @@ -411,7 +421,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_DECLARE_FILE) { + if (methodName == api::METHOD_DECLARE_FILE) { api::DeclareFileIn data; config::loadFromGVariant(parameters, data); @@ -422,7 +432,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_DECLARE_MOUNT) { + if (methodName == api::METHOD_DECLARE_MOUNT) { api::DeclareMountIn data; config::loadFromGVariant(parameters, data); @@ -433,7 +443,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_DECLARE_LINK) { + if (methodName == api::METHOD_DECLARE_LINK) { api::DeclareLinkIn data; config::loadFromGVariant(parameters, data); @@ -444,7 +454,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GET_DECLARATIONS) { + if (methodName == api::METHOD_GET_DECLARATIONS) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -455,7 +465,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_REMOVE_DECLARATION) { + if (methodName == api::METHOD_REMOVE_DECLARATION) { api::RemoveDeclarationIn data; config::loadFromGVariant(parameters, data); @@ -466,7 +476,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_CREATE_ZONE) { + if (methodName == api::METHOD_CREATE_ZONE) { api::CreateZoneIn data; config::loadFromGVariant(parameters, data); @@ -477,7 +487,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_DESTROY_ZONE) { + if (methodName == api::METHOD_DESTROY_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -488,7 +498,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_SHUTDOWN_ZONE) { + if (methodName == api::METHOD_SHUTDOWN_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -498,7 +508,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_START_ZONE) { + if (methodName == api::METHOD_START_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -508,7 +518,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::host::METHOD_LOCK_ZONE) { + if (methodName == api::METHOD_LOCK_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -519,7 +529,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_UNLOCK_ZONE) { + if (methodName == api::METHOD_UNLOCK_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -530,7 +540,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_GRANT_DEVICE) { + if (methodName == api::METHOD_GRANT_DEVICE) { api::GrantDeviceIn data; config::loadFromGVariant(parameters, data); @@ -541,7 +551,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::host::METHOD_REVOKE_DEVICE) { + if (methodName == api::METHOD_REVOKE_DEVICE) { api::RevokeDeviceIn data; config::loadFromGVariant(parameters, data); @@ -551,6 +561,43 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } return; } + + if (methodName == api::METHOD_NOTIFY_ACTIVE_ZONE) { + api::NotifActiveZoneIn data; + config::loadFromGVariant(parameters, data); + + if (mNotifyActiveZoneCallback) { + auto rb = std::make_shared>(result); + mNotifyActiveZoneCallback(data, rb); + } + } + + if (methodName == api::METHOD_FILE_MOVE_REQUEST) { + api::FileMoveRequestIn data; + config::loadFromGVariant(parameters, data); + + if (mFileMoveCallback) { + auto rb = std::make_shared>(result); + mFileMoveCallback(data, rb); + } + } +} + +void HostDbusConnection::onSignalCall(const std::string& /* senderBusName */, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant* /* parameters */) +{ + if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) { + return; + } + + if (signalName == api::SIGNAL_SWITCH_TO_DEFAULT) { + if (mSwitchToDefaultCallback) { + mSwitchToDefaultCallback(); + } + } } void HostDbusConnection::proxyCallAsync(const std::string& busName, @@ -569,14 +616,16 @@ void HostDbusConnection::proxyCallAsync(const std::string& busName, callback); } -void HostDbusConnection::signalZoneConnectionState(const api::ConnectionState& state) +void HostDbusConnection::sendNotification(const api::Notification& notify) { - GVariant* parameters = g_variant_new("(ss)", state.first.c_str(), state.second.c_str()); - mDbusConnection->emitSignal(api::host::OBJECT_PATH, - api::host::INTERFACE, - api::host::SIGNAL_ZONE_CONNECTION_STATE, + GVariant* parameters = g_variant_new("(sss)", + notify.zone.c_str(), + notify.application.c_str(), + notify.message.c_str()); + mDbusConnection->emitSignal(api::OBJECT_PATH, + api::INTERFACE, + api::SIGNAL_NOTIFICATION, parameters); } - } // namespace vasum diff --git a/server/host-dbus-connection.hpp b/server/host-dbus-connection.hpp index 455437d..cdd8dda 100644 --- a/server/host-dbus-connection.hpp +++ b/server/host-dbus-connection.hpp @@ -131,6 +131,14 @@ public: typedef std::function RevokeDeviceCallback; + typedef std::function NotifyActiveZoneCallback; + typedef std::function FileMoveCallback; + typedef std::function SwitchToDefaultCallback; + /** * Register proxy call callback @@ -273,6 +281,26 @@ public: void setRevokeDeviceCallback(const RevokeDeviceCallback& callback); /** + * Register notification request callback + */ + void setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback); + + /** + * Register switch to default request callback + */ + void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); + + /* + * Register file move request callback + */ + void setFileMoveCallback(const FileMoveCallback& callback); + + /** + * Send notification signal to this zone + */ + void sendNotification(const api::Notification& notify); + + /** * Make a proxy call */ void proxyCallAsync(const std::string& busName, @@ -288,6 +316,7 @@ private: std::condition_variable mNameCondition; bool mNameAcquired; bool mNameLost; + dbus::DbusConnection::SubscriptionId mSubscriptionId; ProxyCallCallback mProxyCallCallback; GetZoneConnectionsCallback mGetZoneConnectionsCallback; GetZoneIdsCallback mGetZoneIdsCallback; @@ -315,6 +344,9 @@ private: UnlockZoneCallback mUnlockZoneCallback; GrantDeviceCallback mGrantDeviceCallback; RevokeDeviceCallback mRevokeDeviceCallback; + NotifyActiveZoneCallback mNotifyActiveZoneCallback; + SwitchToDefaultCallback mSwitchToDefaultCallback; + FileMoveCallback mFileMoveCallback; void onNameAcquired(); void onNameLost(); @@ -325,6 +357,11 @@ private: const std::string& methodName, GVariant* parameters, dbus::MethodResultBuilder::Pointer result); + void onSignalCall(const std::string& senderBusName, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant* parameters); }; diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index b814c90..208276e 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -25,20 +25,16 @@ #ifndef SERVER_HOST_DBUS_DEFINITIONS_HPP #define SERVER_HOST_DBUS_DEFINITIONS_HPP -#include "common-dbus-definitions.hpp" - +#include namespace vasum { namespace api { -namespace host { const std::string BUS_NAME = "org.tizen.vasum.host"; const std::string OBJECT_PATH = "/org/tizen/vasum/host"; const std::string INTERFACE = "org.tizen.vasum.host.manager"; -const std::string ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.host.Error.ZonesNotRunning"; -const std::string METHOD_GET_ZONE_CONNECTIONS = "GetZoneConnections"; const std::string METHOD_GET_ZONE_ID_LIST = "GetZoneIds"; const std::string METHOD_GET_ACTIVE_ZONE_ID = "GetActiveZoneId"; const std::string METHOD_GET_ZONE_INFO = "GetZoneInfo"; @@ -64,8 +60,19 @@ const std::string METHOD_LOCK_ZONE = "LockZone"; const std::string METHOD_UNLOCK_ZONE = "UnlockZone"; const std::string METHOD_GRANT_DEVICE = "GrantDevice"; const std::string METHOD_REVOKE_DEVICE = "RevokeDevice"; +const std::string METHOD_PROXY_CALL = "ProxyCall"; + +const std::string METHOD_NOTIFY_ACTIVE_ZONE = "NotifyActiveZone"; +const std::string METHOD_FILE_MOVE_REQUEST = "FileMoveRequest"; +const std::string SIGNAL_NOTIFICATION = "Notification"; +const std::string SIGNAL_SWITCH_TO_DEFAULT = "SwitchToDefault"; -const std::string SIGNAL_ZONE_CONNECTION_STATE = "ZoneConnectionState"; +const std::string FILE_MOVE_DESTINATION_NOT_FOUND = "FILE_MOVE_DESTINATION_NOT_FOUND"; +const std::string FILE_MOVE_WRONG_DESTINATION = "FILE_MOVE_WRONG_DESTINATION"; +const std::string FILE_MOVE_NO_PERMISSIONS_SEND = "FILE_MOVE_NO_PERMISSIONS_SEND"; +const std::string FILE_MOVE_NO_PERMISSIONS_RECEIVE = "FILE_MOVE_NO_PERMISSIONS_RECEIVE"; +const std::string FILE_MOVE_FAILED = "FILE_MOVE_FAILED"; +const std::string FILE_MOVE_SUCCEEDED = "FILE_MOVE_SUCCEEDED"; const std::string DEFINITION = @@ -80,9 +87,6 @@ const std::string DEFINITION = " " " " " " - " " - " " - " " " " " " " " @@ -196,14 +200,34 @@ const std::string DEFINITION = " " " " " " - " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " - " " + " " + " " + " " + " " " " " " ""; -} // namespace host } // namespace api } // namespace vasum diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp index 817e62f..1bf2e78c 100644 --- a/server/host-ipc-connection.cpp +++ b/server/host-ipc-connection.cpp @@ -31,17 +31,10 @@ namespace vasum { -namespace { - -const std::string SOCKET_PATH = HOST_IPC_SOCKET; - -} // namespace - - HostIPCConnection::HostIPCConnection() { LOGT("Connecting to host IPC socket"); - mService.reset(new ipc::Service(mDispatcher.getPoll(), SOCKET_PATH)); + mService.reset(new ipc::Service(mDispatcher.getPoll(), HOST_IPC_SOCKET)); LOGT("Starting IPC"); mService->start(); @@ -52,221 +45,238 @@ HostIPCConnection::~HostIPCConnection() { } -void HostIPCConnection::setGetZoneConnectionsCallback(const Callback::type& callback) +void HostIPCConnection::setGetZoneIdsCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_ZONE_CONNECTIONS, - Callback::getCallbackWrapper(callback)); + api::METHOD_GET_ZONE_ID_LIST, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetZoneIdsCallback(const Callback::type& callback) +void HostIPCConnection::setGetActiveZoneIdCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_ZONE_ID_LIST, - Callback::getCallbackWrapper(callback)); + api::METHOD_GET_ACTIVE_ZONE_ID, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetActiveZoneIdCallback(const Callback::type& callback) +void HostIPCConnection::setGetZoneInfoCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_ACTIVE_ZONE_ID, - Callback::getCallbackWrapper(callback)); - + api::METHOD_GET_ZONE_INFO, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetZoneInfoCallback(const Callback::type& callback) +void HostIPCConnection::setSetNetdevAttrsCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_ZONE_INFO, - Callback::getCallbackWrapper(callback)); + api::METHOD_SET_NETDEV_ATTRS, + Callback::getWrapper(callback)); } -void HostIPCConnection::setSetNetdevAttrsCallback(const Callback::type& callback) +void HostIPCConnection::setGetNetdevAttrsCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_SET_NETDEV_ATTRS, - Callback::getCallbackWrapper(callback)); + api::METHOD_GET_NETDEV_ATTRS, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetNetdevAttrsCallback(const Callback::type& callback) +void HostIPCConnection::setGetNetdevListCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_NETDEV_ATTRS, - Callback::getCallbackWrapper(callback)); + api::METHOD_GET_NETDEV_LIST, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetNetdevListCallback(const Callback::type& callback) +void HostIPCConnection::setCreateNetdevVethCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_NETDEV_LIST, - Callback::getCallbackWrapper(callback)); + api::METHOD_CREATE_NETDEV_VETH, + Callback::getWrapper(callback)); } -void HostIPCConnection::setCreateNetdevVethCallback(const Callback::type& callback) +void HostIPCConnection::setCreateNetdevMacvlanCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_CREATE_NETDEV_VETH, - Callback::getCallbackWrapper(callback)); + api::METHOD_CREATE_NETDEV_MACVLAN, + Callback::getWrapper(callback)); } -void HostIPCConnection::setCreateNetdevMacvlanCallback(const Callback::type& callback) +void HostIPCConnection::setCreateNetdevPhysCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_CREATE_NETDEV_MACVLAN, - Callback::getCallbackWrapper(callback)); + api::METHOD_CREATE_NETDEV_PHYS, + Callback::getWrapper(callback)); } -void HostIPCConnection::setCreateNetdevPhysCallback(const Callback::type& callback) +void HostIPCConnection::setDestroyNetdevCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_CREATE_NETDEV_PHYS, - Callback::getCallbackWrapper(callback)); + api::METHOD_DESTROY_NETDEV, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDestroyNetdevCallback(const Callback::type& callback) +void HostIPCConnection::setDeleteNetdevIpAddressCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DESTROY_NETDEV, - Callback::getCallbackWrapper(callback)); + api::METHOD_DELETE_NETDEV_IP_ADDRESS, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDeleteNetdevIpAddressCallback(const Callback::type& callback) +void HostIPCConnection::setDeclareFileCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DELETE_NETDEV_IP_ADDRESS, - Callback::getCallbackWrapper(callback)); + api::METHOD_DECLARE_FILE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDeclareFileCallback(const Callback::type& callback) +void HostIPCConnection::setDeclareMountCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DECLARE_FILE, - Callback::getCallbackWrapper(callback)); + api::METHOD_DECLARE_MOUNT, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDeclareMountCallback(const Callback::type& callback) +void HostIPCConnection::setDeclareLinkCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DECLARE_MOUNT, - Callback::getCallbackWrapper(callback)); + api::METHOD_DECLARE_LINK, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDeclareLinkCallback(const Callback::type& callback) +void HostIPCConnection::setGetDeclarationsCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DECLARE_LINK, - Callback::getCallbackWrapper(callback)); + api::METHOD_GET_DECLARATIONS, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGetDeclarationsCallback(const Callback::type& callback) +void HostIPCConnection::setRemoveDeclarationCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GET_DECLARATIONS, - Callback::getCallbackWrapper(callback)); + api::METHOD_REMOVE_DECLARATION, + Callback::getWrapper(callback)); } -void HostIPCConnection::setRemoveDeclarationCallback(const Callback::type& callback) +void HostIPCConnection::setSetActiveZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_REMOVE_DECLARATION, - Callback::getCallbackWrapper(callback)); + api::METHOD_SET_ACTIVE_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setSetActiveZoneCallback(const Callback::type& callback) +void HostIPCConnection::setCreateZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_SET_ACTIVE_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_CREATE_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setCreateZoneCallback(const Callback::type& callback) +void HostIPCConnection::setDestroyZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_CREATE_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_DESTROY_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setDestroyZoneCallback(const Callback::type& callback) +void HostIPCConnection::setShutdownZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_DESTROY_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_SHUTDOWN_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setShutdownZoneCallback(const Callback::type& callback) +void HostIPCConnection::setStartZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_SHUTDOWN_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_START_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setStartZoneCallback(const Callback::type& callback) +void HostIPCConnection::setLockZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_START_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_LOCK_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setLockZoneCallback(const Callback::type& callback) +void HostIPCConnection::setUnlockZoneCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_LOCK_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_UNLOCK_ZONE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setUnlockZoneCallback(const Callback::type& callback) +void HostIPCConnection::setGrantDeviceCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_UNLOCK_ZONE, - Callback::getCallbackWrapper(callback)); + api::METHOD_GRANT_DEVICE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setGrantDeviceCallback(const Callback::type& callback) +void HostIPCConnection::setRevokeDeviceCallback(const Method::type& callback) { - typedef Callback Callback; + typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::host::METHOD_GRANT_DEVICE, - Callback::getCallbackWrapper(callback)); + api::METHOD_REVOKE_DEVICE, + Callback::getWrapper(callback)); } -void HostIPCConnection::setRevokeDeviceCallback(const Callback::type& callback) +void HostIPCConnection::setNotifyActiveZoneCallback( + const Method::type& callback) { - typedef Callback Callback; - mService->setMethodHandler( - api::host::METHOD_REVOKE_DEVICE, - Callback::getCallbackWrapper(callback)); + typedef IPCMethodWrapper Method; + mService->setMethodHandler( + api::METHOD_NOTIFY_ACTIVE_ZONE, + Method::getWrapper(callback)); +} + +void HostIPCConnection::setSwitchToDefaultCallback(const Signal::type& callback) +{ + typedef IPCSignalWrapper Signal; + mService->setSignalHandler( + api::SIGNAL_SWITCH_TO_DEFAULT, + Signal::getWrapper(callback)); +} + +void HostIPCConnection::setFileMoveCallback(const Method::type& callback) +{ + typedef IPCMethodWrapper Method; + mService->setMethodHandler( + api::METHOD_FILE_MOVE_REQUEST, + Method::getWrapper(callback)); } -void HostIPCConnection::signalZoneConnectionState(const api::ConnectionState& connectionState) +void HostIPCConnection::sendNotification(const api::Notification& notification) { - mService->signal(api::host::SIGNAL_ZONE_CONNECTION_STATE, - std::make_shared(connectionState)); + mService->signal(api::SIGNAL_NOTIFICATION, + std::make_shared(notification)); } } // namespace vasum diff --git a/server/host-ipc-connection.hpp b/server/host-ipc-connection.hpp index 61c8f4a..d5144fd 100644 --- a/server/host-ipc-connection.hpp +++ b/server/host-ipc-connection.hpp @@ -27,87 +27,61 @@ #define SERVER_HOST_IPC_CONNECTION_HPP #include "api/messages.hpp" -#include "api/method-result-builder.hpp" -#include "api/ipc-method-result-builder.hpp" #include "epoll/thread-dispatcher.hpp" #include "ipc/service.hpp" - -#include +#include "ipc-callback-wrapper.hpp" namespace vasum { - class HostIPCConnection { public: - template - class Callback { + template + class Method { public: - typedef typename std::remove_cv::type in; - typedef ArgOut out; - typedef std::function type; - - static typename ipc::MethodHandler::type - getCallbackWrapper(const type& callback) { - return [callback](const ipc::PeerID, - const std::shared_ptr& argIn, - ipc::MethodResult::Pointer&& argOut) - { - auto rb = std::make_shared(argOut); - callback(*argIn, rb); - }; - } + typedef typename IPCMethodWrapper::type type; }; - - template - class Callback::value, api::Void>::type> { + template + class Signal { public: - typedef api::Void in; - typedef ArgOut out; - typedef std::function type; - - static typename ipc::MethodHandler::type - getCallbackWrapper(const type& callback) { - return [callback](const ipc::PeerID, - const std::shared_ptr& /* argIn */, - ipc::MethodResult::Pointer&& argOut) - { - auto rb = std::make_shared(argOut); - callback(rb); - }; - } + typedef typename IPCSignalWrapper::type type; }; HostIPCConnection(); ~HostIPCConnection(); - void setGetZoneConnectionsCallback(const Callback::type& callback); - void setGetZoneIdsCallback(const Callback::type& callback); - void setGetActiveZoneIdCallback(const Callback::type& callback); - void setGetZoneInfoCallback(const Callback::type& callback); - void setSetNetdevAttrsCallback(const Callback::type& callback); - void setGetNetdevAttrsCallback(const Callback::type& callback); - void setGetNetdevListCallback(const Callback::type& callback); - void setCreateNetdevVethCallback(const Callback::type& callback); - void setCreateNetdevMacvlanCallback(const Callback::type& callback); - void setCreateNetdevPhysCallback(const Callback::type& callback); - void setDestroyNetdevCallback(const Callback::type& callback); - void setDeleteNetdevIpAddressCallback(const Callback::type& callback); - void setDeclareFileCallback(const Callback::type& callback); - void setDeclareMountCallback(const Callback::type& callback); - void setDeclareLinkCallback(const Callback::type& callback); - void setGetDeclarationsCallback(const Callback::type& callback); - void setRemoveDeclarationCallback(const Callback::type& callback); - void setSetActiveZoneCallback(const Callback::type& callback); - void setCreateZoneCallback(const Callback::type& callback); - void setDestroyZoneCallback(const Callback::type& callback); - void setShutdownZoneCallback(const Callback::type& callback); - void setStartZoneCallback(const Callback::type& callback); - void setLockZoneCallback(const Callback::type& callback); - void setUnlockZoneCallback(const Callback::type& callback); - void setGrantDeviceCallback(const Callback::type& callback); - void setRevokeDeviceCallback(const Callback::type& callback); + void setGetZoneConnectionsCallback(const Method::type& callback); + void setGetZoneIdsCallback(const Method::type& callback); + void setGetActiveZoneIdCallback(const Method::type& callback); + void setGetZoneInfoCallback(const Method::type& callback); + void setSetNetdevAttrsCallback(const Method::type& callback); + void setGetNetdevAttrsCallback(const Method::type& callback); + void setGetNetdevListCallback(const Method::type& callback); + void setCreateNetdevVethCallback(const Method::type& callback); + void setCreateNetdevMacvlanCallback(const Method::type& callback); + void setCreateNetdevPhysCallback(const Method::type& callback); + void setDestroyNetdevCallback(const Method::type& callback); + void setDeleteNetdevIpAddressCallback(const Method::type& callback); + void setDeclareFileCallback(const Method::type& callback); + void setDeclareMountCallback(const Method::type& callback); + void setDeclareLinkCallback(const Method::type& callback); + void setGetDeclarationsCallback(const Method::type& callback); + void setRemoveDeclarationCallback(const Method::type& callback); + void setSetActiveZoneCallback(const Method::type& callback); + void setCreateZoneCallback(const Method::type& callback); + void setDestroyZoneCallback(const Method::type& callback); + void setShutdownZoneCallback(const Method::type& callback); + void setStartZoneCallback(const Method::type& callback); + void setLockZoneCallback(const Method::type& callback); + void setUnlockZoneCallback(const Method::type& callback); + void setGrantDeviceCallback(const Method::type& callback); + void setRevokeDeviceCallback(const Method::type& callback); + void setNotifyActiveZoneCallback(const Method::type& callback); + void setSwitchToDefaultCallback(const Signal::type& callback); + void setFileMoveCallback(const Method::type& callback); void signalZoneConnectionState(const api::ConnectionState& connectionState); + void sendNotification(const api::Notification& notification); private: epoll::ThreadDispatcher mDispatcher; diff --git a/server/host-ipc-definitions.hpp b/server/host-ipc-definitions.hpp index b1fca09..8c31339 100644 --- a/server/host-ipc-definitions.hpp +++ b/server/host-ipc-definitions.hpp @@ -29,9 +29,7 @@ namespace vasum { namespace api { -namespace host { -const vasum::ipc::MethodID METHOD_GET_ZONE_CONNECTIONS = 1; const vasum::ipc::MethodID METHOD_GET_ZONE_ID_LIST = 2; const vasum::ipc::MethodID METHOD_GET_ACTIVE_ZONE_ID = 3; const vasum::ipc::MethodID METHOD_GET_ZONE_INFO = 4; @@ -58,9 +56,18 @@ const vasum::ipc::MethodID METHOD_UNLOCK_ZONE = 24; const vasum::ipc::MethodID METHOD_GRANT_DEVICE = 25; const vasum::ipc::MethodID METHOD_REVOKE_DEVICE = 26; -const vasum::ipc::MethodID SIGNAL_ZONE_CONNECTION_STATE = 27; +const vasum::ipc::MethodID METHOD_NOTIFY_ACTIVE_ZONE = 100; +const vasum::ipc::MethodID METHOD_FILE_MOVE_REQUEST = 101; +const vasum::ipc::MethodID SIGNAL_NOTIFICATION = 102; +const vasum::ipc::MethodID SIGNAL_SWITCH_TO_DEFAULT = 103; + +const std::string FILE_MOVE_DESTINATION_NOT_FOUND = "FILE_MOVE_DESTINATION_NOT_FOUND"; +const std::string FILE_MOVE_WRONG_DESTINATION = "FILE_MOVE_WRONG_DESTINATION"; +const std::string FILE_MOVE_NO_PERMISSIONS_SEND = "FILE_MOVE_NO_PERMISSIONS_SEND"; +const std::string FILE_MOVE_NO_PERMISSIONS_RECEIVE = "FILE_MOVE_NO_PERMISSIONS_RECEIVE"; +const std::string FILE_MOVE_FAILED = "FILE_MOVE_FAILED"; +const std::string FILE_MOVE_SUCCEEDED = "FILE_MOVE_SUCCEEDED"; -} // namespace host } // namespace api } // namespace vasum diff --git a/server/ipc-callback-wrapper.hpp b/server/ipc-callback-wrapper.hpp new file mode 100644 index 0000000..04c0544 --- /dev/null +++ b/server/ipc-callback-wrapper.hpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015 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 IPCSignalWrapper and IPCMethodWrapper classes used to hide IPC specifics + */ + + +#ifndef SERVER_IPC_CALLBACK_WRAPPER_HPP +#define SERVER_IPC_CALLBACK_WRAPPER_HPP + +#include "api/messages.hpp" +#include "api/method-result-builder.hpp" +#include "api/ipc-method-result-builder.hpp" + +#include + +namespace vasum { + +template +class IPCSignalWrapper { +public: + typedef typename std::remove_cv::type in; + typedef std::function type; + + static typename ipc::SignalHandler::type + getWrapper(const type& callback) { + return [callback](const ipc::PeerID, const std::shared_ptr& argIn) + { + callback(*argIn); + }; + } +}; + +template<> +class IPCSignalWrapper { +public: + typedef api::Void in; + typedef std::function type; + + static typename ipc::SignalHandler::type + getWrapper(const type& callback) { + return [callback](const ipc::PeerID, const std::shared_ptr& /* argIn */) + { + callback(); + }; + } +}; + +template +class IPCMethodWrapper { +public: + typedef typename std::remove_cv::type in; + typedef ArgOut out; + typedef std::function type; + + static typename ipc::MethodHandler::type + getWrapper(const type& callback) { + return [callback](const ipc::PeerID, + const std::shared_ptr& argIn, + ipc::MethodResult::Pointer&& argOut) + { + auto rb = std::make_shared(argOut); + callback(*argIn, rb); + }; + } +}; + +template +class IPCMethodWrapper::value, api::Void>::type> { +public: + typedef api::Void in; + typedef ArgOut out; + typedef std::function type; + + static typename ipc::MethodHandler::type + getWrapper(const type& callback) { + return [callback](const ipc::PeerID, + const std::shared_ptr& /* argIn */, + ipc::MethodResult::Pointer&& argOut) + { + auto rb = std::make_shared(argOut); + callback(rb); + }; + } +}; + +} // namespace vasum + +#endif // SERVER_IPC_CALLBACK_WRAPPER_HPP diff --git a/server/zone-config.hpp b/server/zone-config.hpp index 67b5f93..b845ef9 100644 --- a/server/zone-config.hpp +++ b/server/zone-config.hpp @@ -60,12 +60,6 @@ struct ZoneConfig { bool switchToDefaultAfterTimeout; /** - * Specify, if D-Bus communication with the zone will be enabled. - * Setting this value to "false" will make the zone API not work inside the zone. - */ - bool enableZoneConnection; - - /** * Zone's CFS quota in us when it's in the foreground */ std::int64_t cpuQuotaForeground; @@ -106,7 +100,6 @@ struct ZoneConfig { initWithArgs, privilege, // TODO not needed? switchToDefaultAfterTimeout, // TODO move to dynamic and add an API to change - enableZoneConnection, cpuQuotaForeground, cpuQuotaBackground, permittedToSend, // TODO move to dynamic and add an API to change diff --git a/server/zone-connection-transport.cpp b/server/zone-connection-transport.cpp deleted file mode 100644 index 0a8f8a0..0000000 --- a/server/zone-connection-transport.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 Implementation of a class for communication transport between zone and server - */ - -#include "config.hpp" - -#include "zone-connection-transport.hpp" -#include "exception.hpp" - -#include "utils/file-wait.hpp" -#include "utils/fs.hpp" -#include "logger/logger.hpp" - -#include -#include - -namespace vasum { - -namespace { - -// Timeout in ms for waiting for dbus transport. -// Should be very long to ensure dbus in zone is ready. -// TODO: this should be in zone's configuration file -const unsigned int TRANSPORT_READY_TIMEOUT = 2 * 60 * 1000; - -} // namespace - - -ZoneConnectionTransport::ZoneConnectionTransport(const std::string& runMountPoint) - : mRunMountPoint(runMountPoint), mDetachOnExit(false) -{ - if (runMountPoint.empty()) { - return; - } - boost::system::error_code errorCode; - boost::filesystem::create_directories(runMountPoint, errorCode); - if (errorCode) { - LOGE("Initialization failed: could not create '" << runMountPoint << "' :" << errorCode); - throw ZoneConnectionException("Could not create: " + runMountPoint + - " :" + errorCode.message()); - } - - bool isMount = false; - if (!utils::isMountPoint(runMountPoint, isMount)) { - LOGE("Failed to check if " << runMountPoint << " is a mount point."); - throw ZoneConnectionException("Could not check if " + runMountPoint + - " is a mount point."); - } - - if (!isMount) { - LOGD(runMountPoint << " not mounted - mounting."); - - if (!utils::mountRun(runMountPoint)) { - LOGE("Initialization failed: could not mount " << runMountPoint); - throw ZoneConnectionException("Could not mount: " + runMountPoint); - } - LOGI("Mounted: " << runMountPoint); - } - - // if there is no systemd in the zone this dir won't be created automatically - // TODO: will require chown with USER namespace enabled - std::string dbusDirectory = runMountPoint + "/dbus"; - boost::filesystem::create_directories(dbusDirectory, errorCode); - if (errorCode) { - LOGE("Initialization failed: could not create '" << dbusDirectory << "' :" << errorCode); - throw ZoneConnectionException("Could not create: " + dbusDirectory + - " :" + errorCode.message()); - } -} - - -ZoneConnectionTransport::~ZoneConnectionTransport() -{ - if (!mDetachOnExit) { - if (!mRunMountPoint.empty()) { - if (!utils::umount(mRunMountPoint)) { - LOGE("Deinitialization failed: could not umount " << mRunMountPoint); - } - LOGI("Unmounted: " << mRunMountPoint); - } - } -} - - -std::string ZoneConnectionTransport::acquireAddress() const -{ - 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; -} - -void ZoneConnectionTransport::setDetachOnExit() -{ - mDetachOnExit = true; -} - -} // namespace vasum diff --git a/server/zone-connection-transport.hpp b/server/zone-connection-transport.hpp deleted file mode 100644 index d651f3c..0000000 --- a/server/zone-connection-transport.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 Declaration of a class for communication transport between zone and server - */ - - -#ifndef SERVER_ZONE_CONNECTION_TRANSPORT_HPP -#define SERVER_ZONE_CONNECTION_TRANSPORT_HPP - -#include "dbus/connection.hpp" - - -namespace vasum { - - -/** - * This class provides a communication transport between zone and server. - * The object lifecycle should cover lifecycle of a zone. - */ -class ZoneConnectionTransport { -public: - ZoneConnectionTransport(const std::string& runMountPoint); - ~ZoneConnectionTransport(); - - /** - * Gets dbus addres. Will block until address is available. - */ - std::string acquireAddress() const; - - /** - * Set whether object should detach from transport filesystem on exit - */ - void setDetachOnExit(); - -private: - std::string mRunMountPoint; - bool mDetachOnExit; -}; - - -} // namespace vasum - - -#endif // SERVER_ZONE_CONNECTION_TRANSPORT_HPP diff --git a/server/zone-connection.cpp b/server/zone-connection.cpp deleted file mode 100644 index 56aa547..0000000 --- a/server/zone-connection.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* - * 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 Implementation of a class for communication between zone and server - */ - -#include "config.hpp" - -#include "zone-connection.hpp" -#include "zone-dbus-definitions.hpp" -#include "exception.hpp" -// TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager -#include "fake-power-manager-dbus-definitions.hpp" - -#include "api/dbus-method-result-builder.hpp" -#include "api/messages.hpp" - -#include "logger/logger.hpp" - - -namespace vasum { - -namespace { - -// Timeout in ms for waiting for dbus name. -// Can happen if glib loop is busy or not present. -// TODO: this should be in zone's configuration file -const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000; - -} // namespace - - -ZoneConnection::ZoneConnection(const std::string& address, const OnNameLostCallback& callback) - : mNameAcquired(false) - , mNameLost(false) -{ - if (address.empty()) { - LOGE("Invalid zone connection address"); - throw ZoneConnectionException("Invalid zone connection address"); - } - - LOGT("Connecting to DBUS on " << address); - mDbusConnection = dbus::DbusConnection::create(address); - - LOGT("Setting DBUS name"); - mDbusConnection->setName(api::zone::BUS_NAME, - std::bind(&ZoneConnection::onNameAcquired, this), - std::bind(&ZoneConnection::onNameLost, this)); - - if (!waitForNameAndSetCallback(NAME_ACQUIRED_TIMEOUT, callback)) { - LOGE("Could not acquire dbus name: " << api::zone::BUS_NAME); - throw ZoneConnectionException("Could not acquire dbus name: " + api::zone::BUS_NAME); - } - - LOGT("Registering DBUS interface"); - using namespace std::placeholders; - mDbusConnection->registerObject(api::zone::OBJECT_PATH, - api::zone::DEFINITION, - std::bind(&ZoneConnection::onMessageCall, - this, - _1, - _2, - _3, - _4, - _5)); - - mDbusConnection->signalSubscribe(std::bind(&ZoneConnection::onSignalReceived, - this, - _1, - _2, - _3, - _4, - _5), - std::string(fake_power_manager_api::BUS_NAME)); - - LOGD("Connected"); -} - -ZoneConnection::~ZoneConnection() -{ -} - -bool ZoneConnection::waitForNameAndSetCallback(const unsigned int timeoutMs, const OnNameLostCallback& callback) -{ - std::unique_lock lock(mNameMutex); - mNameCondition.wait_for(lock, - std::chrono::milliseconds(timeoutMs), - [this] { - return mNameAcquired || mNameLost; - }); - if(mNameAcquired) { - mOnNameLostCallback = callback; - } - - return mNameAcquired; -} - -void ZoneConnection::onNameAcquired() -{ - std::unique_lock lock(mNameMutex); - mNameAcquired = true; - mNameCondition.notify_one(); -} - -void ZoneConnection::onNameLost() -{ - std::unique_lock lock(mNameMutex); - mNameLost = true; - mNameCondition.notify_one(); - - if (mOnNameLostCallback) { - mOnNameLostCallback(); - } -} - -void ZoneConnection::setNotifyActiveZoneCallback( - const NotifyActiveZoneCallback& callback) -{ - mNotifyActiveZoneCallback = callback; -} - -void ZoneConnection::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) -{ - mSwitchToDefaultCallback = callback; -} - -void ZoneConnection::setFileMoveCallback( - const FileMoveCallback& callback) -{ - mFileMoveCallback = callback; -} - -void ZoneConnection::setProxyCallCallback(const ProxyCallCallback& callback) -{ - mProxyCallCallback = callback; -} - -void ZoneConnection::onMessageCall(const std::string& objectPath, - const std::string& interface, - const std::string& methodName, - GVariant* parameters, - dbus::MethodResultBuilder::Pointer result) -{ - if (objectPath != api::zone::OBJECT_PATH || interface != api::zone::INTERFACE) { - return; - } - - if (methodName == api::zone::METHOD_NOTIFY_ACTIVE_ZONE) { - const gchar* application = NULL; - const gchar* message = NULL; - g_variant_get(parameters, "(&s&s)", &application, &message); - if (mNotifyActiveZoneCallback) { - auto rb = std::make_shared>(result); - mNotifyActiveZoneCallback(application, message, rb); - } - } - - if (methodName == api::zone::METHOD_FILE_MOVE_REQUEST) { - const gchar* destination = NULL; - const gchar* path = NULL; - g_variant_get(parameters, "(&s&s)", &destination, &path); - if (mFileMoveCallback) { - auto rb = std::make_shared>(result); - mFileMoveCallback(destination, path, rb); - } - } - - if (methodName == api::METHOD_PROXY_CALL) { - const gchar* target = NULL; - const gchar* targetBusName = NULL; - const gchar* targetObjectPath = NULL; - const gchar* targetInterface = NULL; - const gchar* targetMethod = NULL; - GVariant* rawArgs = NULL; - g_variant_get(parameters, - "(&s&s&s&s&sv)", - &target, - &targetBusName, - &targetObjectPath, - &targetInterface, - &targetMethod, - &rawArgs); - dbus::GVariantPtr args(rawArgs, g_variant_unref); - - if (mProxyCallCallback) { - mProxyCallCallback(target, - targetBusName, - targetObjectPath, - targetInterface, - targetMethod, - args.get(), - result); - } - } -} - -void ZoneConnection::onSignalReceived(const std::string& senderBusName, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* /*parameters*/) -{ - LOGD("Received signal: " << senderBusName << "; " << objectPath << "; " << interface << "; " - << signalName); - if (objectPath == fake_power_manager_api::OBJECT_PATH && - interface == fake_power_manager_api::INTERFACE) { - //power-manager sent us a signal, check it - if (signalName == fake_power_manager_api::SIGNAL_DISPLAY_OFF && mSwitchToDefaultCallback) { - mSwitchToDefaultCallback(); - } - } -} - -void ZoneConnection::sendNotification(const std::string& zone, - const std::string& application, - const std::string& message) -{ - GVariant* parameters = g_variant_new("(sss)", - zone.c_str(), - application.c_str(), - message.c_str()); - mDbusConnection->emitSignal(api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::SIGNAL_NOTIFICATION, - parameters); -} - -void ZoneConnection::proxyCallAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const dbus::DbusConnection::AsyncMethodCallCallback& callback) -{ - mDbusConnection->callMethodAsync(busName, - objectPath, - interface, - method, - parameters, - std::string(), - callback); -} - - -} // namespace vasum diff --git a/server/zone-connection.hpp b/server/zone-connection.hpp deleted file mode 100644 index 441f645..0000000 --- a/server/zone-connection.hpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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 Declaration of a class for communication between zone and server - */ - - -#ifndef SERVER_ZONE_CONNECTION_HPP -#define SERVER_ZONE_CONNECTION_HPP - -#include "dbus/connection.hpp" -#include "api/method-result-builder.hpp" - -#include -#include - -namespace vasum { - - -class ZoneConnection { - -public: - typedef std::function OnNameLostCallback; - typedef std::function SwitchToDefaultCallback; - - ZoneConnection(const std::string& address, const OnNameLostCallback& callback); - ~ZoneConnection(); - - // ------------- API -------------- - - typedef std::function NotifyActiveZoneCallback; - - typedef std::function FileMoveCallback; - - typedef std::function ProxyCallCallback; - - /** - * Register notification request callback - */ - void setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback); - - /** - * Register switch to default request callback - */ - void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); - - /* - * Register file move request callback - */ - void setFileMoveCallback(const FileMoveCallback& callback); - - /** - * Register proxy call callback - */ - void setProxyCallCallback(const ProxyCallCallback& callback); - - /** - * Send notification signal to this zone - */ - void sendNotification(const std::string& zone, - const std::string& application, - const std::string& message); - - /** - * Make a proxy call - */ - void proxyCallAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const dbus::DbusConnection::AsyncMethodCallCallback& callback); - -private: - dbus::DbusConnection::Pointer mDbusConnection; - std::mutex mNameMutex; - std::condition_variable mNameCondition; - bool mNameAcquired; - bool mNameLost; - OnNameLostCallback mOnNameLostCallback; - NotifyActiveZoneCallback mNotifyActiveZoneCallback; - SwitchToDefaultCallback mSwitchToDefaultCallback; - FileMoveCallback mFileMoveCallback; - ProxyCallCallback mProxyCallCallback; - - void onNameAcquired(); - void onNameLost(); - bool waitForNameAndSetCallback(const unsigned int timeoutMs, const OnNameLostCallback& callback); - - void onMessageCall(const std::string& objectPath, - const std::string& interface, - const std::string& methodName, - GVariant* parameters, - dbus::MethodResultBuilder::Pointer result); - void onSignalReceived(const std::string& senderBusName, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters); -}; - - -} // namespace vasum - - -#endif // SERVER_ZONE_CONNECTION_HPP diff --git a/server/zone-dbus-definitions.hpp b/server/zone-dbus-definitions.hpp deleted file mode 100644 index c46e99a..0000000 --- a/server/zone-dbus-definitions.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 Zone dbus api definitions - */ - -#ifndef SERVER_ZONE_DBUS_DEFINITIONS_HPP -#define SERVER_ZONE_DBUS_DEFINITIONS_HPP - -#include "common-dbus-definitions.hpp" - - -namespace vasum { -namespace api { -namespace zone { - -const std::string BUS_NAME = "org.tizen.vasum.zone"; -const std::string OBJECT_PATH = "/org/tizen/vasum/zone"; -const std::string INTERFACE = "org.tizen.vasum.zone.manager"; - -const std::string METHOD_NOTIFY_ACTIVE_ZONE = "NotifyActiveZone"; -const std::string METHOD_FILE_MOVE_REQUEST = "FileMoveRequest"; -const std::string SIGNAL_NOTIFICATION = "Notification"; - -const std::string FILE_MOVE_DESTINATION_NOT_FOUND = "FILE_MOVE_DESTINATION_NOT_FOUND"; -const std::string FILE_MOVE_WRONG_DESTINATION = "FILE_MOVE_WRONG_DESTINATION"; -const std::string FILE_MOVE_NO_PERMISSIONS_SEND = "FILE_MOVE_NO_PERMISSIONS_SEND"; -const std::string FILE_MOVE_NO_PERMISSIONS_RECEIVE = "FILE_MOVE_NO_PERMISSIONS_RECEIVE"; -const std::string FILE_MOVE_FAILED = "FILE_MOVE_FAILED"; -const std::string FILE_MOVE_SUCCEEDED = "FILE_MOVE_SUCCEEDED"; - - -const std::string DEFINITION = - "" - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - ""; - -} // namespace zone -} // namespace api -} // namespace vasum - - -#endif // SERVER_ZONE_DBUS_DEFINITIONS_HPP diff --git a/server/zone.cpp b/server/zone.cpp index 2e47f25..8a1aa0b 100644 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -46,25 +46,19 @@ namespace { typedef std::lock_guard Lock; -// TODO: move constants to the config file when default values are implemented there -const int RECONNECT_RETRIES = 15; -const int RECONNECT_DELAY = 1 * 1000; - const std::string STATE_STOPPED = "stopped"; const std::string STATE_RUNNING = "running"; const std::string STATE_PAUSED = "paused"; } // namespace -Zone::Zone(const utils::Worker::Pointer& worker, - const std::string& zoneId, +Zone::Zone(const std::string& zoneId, const std::string& zonesPath, const std::string& zoneTemplatePath, const std::string& dbPath, const std::string& lxcTemplatePrefix, const std::string& baseRunMountPointPath) - : mWorker(worker) - , mDbPath(dbPath) + : mDbPath(dbPath) { const std::string dbPrefix = getZoneDbPrefix(zoneId); config::loadFromKVStoreWithJsonFile(dbPath, zoneTemplatePath, mConfig, dbPrefix); @@ -89,19 +83,6 @@ Zone::Zone(const utils::Worker::Pointer& worker, mProvision.reset(new ZoneProvision(mRootPath, zoneTemplatePath, dbPath, dbPrefix, mConfig.validLinkPrefixes)); } -Zone::~Zone() -{ - // Make sure all OnNameLostCallbacks get finished and no new will - // get called before proceeding further. This guarantees no race - // condition on the reconnect thread. - { - Lock lock(mReconnectMutex); - disconnect(); - } - // wait for all tasks to complete - mWorker.reset(); -} - const std::vector& Zone::getPermittedToSend() const { return mPermittedToSend; @@ -164,16 +145,9 @@ void Zone::start() Lock lock(mReconnectMutex); updateRequestedState(STATE_RUNNING); mProvision->start(); - if (mConfig.enableZoneConnection) { - mConnectionTransport.reset(new ZoneConnectionTransport(mRunMountPoint)); - } - mAdmin->start(); - if (mConfig.enableZoneConnection) { - // Increase cpu quota before connect, otherwise it'd take ages. - goForeground(); - connect(); - } + // Increase cpu quota before connect, otherwise it'd take ages. + goForeground(); // refocus in ZonesManager will adjust cpu quota after all } @@ -187,54 +161,10 @@ void Zone::stop(bool saveState) // boost stopping goForeground(); } - disconnect(); mAdmin->stop(); - mConnectionTransport.reset(); mProvision->stop(); } -void Zone::connect() -{ - // assume called under reconnect lock - mConnectionAddress = mConnectionTransport->acquireAddress(); - mConnection.reset(new ZoneConnection(mConnectionAddress, - std::bind(&Zone::onNameLostCallback, this))); - if (mNotifyCallback) { - mConnection->setNotifyActiveZoneCallback(mNotifyCallback); - } - if (mSwitchToDefaultCallback) { - mConnection->setSwitchToDefaultCallback(mSwitchToDefaultCallback); - } - if (mFileMoveCallback) { - mConnection->setFileMoveCallback(mFileMoveCallback); - } - if (mProxyCallCallback) { - mConnection->setProxyCallCallback(mProxyCallCallback); - } - if (mConnectionStateChangedCallback) { - mConnectionStateChangedCallback(mConnectionAddress); - } -} - -void Zone::disconnect() -{ - // assume called under reconnect lock - if (mConnection) { - mConnection.reset(); - mConnectionAddress.clear(); - if (mConnectionStateChangedCallback) { - // notify about invalid address for this zone - mConnectionStateChangedCallback(std::string()); - } - } -} - -std::string Zone::getConnectionAddress() const -{ - Lock lock(mReconnectMutex); - return mConnectionAddress; -} - int Zone::getVT() const { Lock lock(mReconnectMutex); @@ -300,9 +230,6 @@ void Zone::setDetachOnExit() { Lock lock(mReconnectMutex); mAdmin->setDetachOnExit(); - if (mConnectionTransport) { - mConnectionTransport->setDetachOnExit(); - } } void Zone::setDestroyOnExit() @@ -348,120 +275,6 @@ bool Zone::isSwitchToDefaultAfterTimeoutAllowed() const return mConfig.switchToDefaultAfterTimeout; } -void Zone::onNameLostCallback() -{ - LOGI(getId() << ": A connection to the DBUS server has been lost, reconnecting..."); - - mWorker->addTask(std::bind(&Zone::reconnectHandler, this)); -} - -void Zone::reconnectHandler() -{ - { - Lock lock(mReconnectMutex); - disconnect(); - } - - for (int i = 0; i < RECONNECT_RETRIES; ++i) { - // This sleeps even before the first try to give DBUS some time to come back up - std::this_thread::sleep_for(std::chrono::milliseconds(RECONNECT_DELAY)); - - Lock lock(mReconnectMutex); - if (isStopped()) { - LOGI(getId() << ": Has stopped, nothing to reconnect to, bailing out"); - return; - } - - try { - LOGT(getId() << ": Reconnect try " << i + 1); - connect(); - LOGI(getId() << ": Reconnected"); - return; - } catch (VasumException&) { - LOGT(getId() << ": Reconnect try " << i + 1 << " has been unsuccessful"); - } - } - - LOGE(getId() << ": Reconnecting to the DBUS has failed, stopping the zone"); - stop(false); -} - -void Zone::setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback) -{ - Lock lock(mReconnectMutex); - mNotifyCallback = callback; - if (mConnection) { - mConnection->setNotifyActiveZoneCallback(mNotifyCallback); - } -} - -void Zone::sendNotification(const std::string& zone, - const std::string& application, - const std::string& message) -{ - Lock lock(mReconnectMutex); - if (mConnection) { - mConnection->sendNotification(zone, application, message); - } else { - LOGE(getId() << ": Can't send notification, no connection to DBUS"); - } -} - -void Zone::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) -{ - Lock lock(mReconnectMutex); - - mSwitchToDefaultCallback = callback; - if (mConnection) { - mConnection->setSwitchToDefaultCallback(callback); - } -} - -void Zone::setFileMoveCallback(const FileMoveCallback& callback) -{ - Lock lock(mReconnectMutex); - - mFileMoveCallback = callback; - if (mConnection) { - mConnection->setFileMoveCallback(callback); - } -} - -void Zone::setProxyCallCallback(const ProxyCallCallback& callback) -{ - Lock lock(mReconnectMutex); - - mProxyCallCallback = callback; - if (mConnection) { - mConnection->setProxyCallCallback(callback); - } -} - -void Zone::setConnectionStateChangedCallback(const ConnectionStateChangedCallback& callback) -{ - mConnectionStateChangedCallback = callback; -} - -void Zone::proxyCallAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const dbus::DbusConnection::AsyncMethodCallCallback& callback) -{ - Lock lock(mReconnectMutex); - if (mConnection) { - mConnection->proxyCallAsync(busName, - objectPath, - interface, - method, - parameters, - callback); - } else { - LOGE(getId() << ": Can't do a proxy call, no connection to DBUS"); - } -} - std::string Zone::declareFile(const int32_t& type, const std::string& path, const int32_t& flags, diff --git a/server/zone.hpp b/server/zone.hpp index f24a6e6..6d13d85 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -28,11 +28,9 @@ #include "zone-config.hpp" #include "zone-admin.hpp" -#include "zone-connection.hpp" -#include "zone-connection-transport.hpp" #include "zone-provision.hpp" -#include "utils/worker.hpp" +#include #include #include #include @@ -54,8 +52,7 @@ public: * @param lxcTemplatePrefix directory where templates are stored * @param baseRunMountPointPath base directory for run mount point */ - Zone(const utils::Worker::Pointer& worker, - const std::string& zoneId, + Zone(const std::string& zoneId, const std::string& zonesPath, const std::string& zoneTemplatePath, const std::string& dbPath, @@ -63,14 +60,7 @@ public: const std::string& baseRunMountPointPath); Zone(const Zone&) = delete; Zone& operator=(const Zone&) = delete; - ~Zone(); - typedef ZoneConnection::NotifyActiveZoneCallback NotifyActiveZoneCallback; - typedef ZoneConnection::SwitchToDefaultCallback SwitchToDefaultCallback; - typedef ZoneConnection::FileMoveCallback FileMoveCallback; - typedef ZoneConnection::ProxyCallCallback ProxyCallCallback; - - typedef std::function ConnectionStateChangedCallback; typedef std::function StartAsyncResultCallback; /** @@ -135,8 +125,7 @@ public: /** * Set if zone should be detached on exit. * - * This sends detach flag to ZoneAdmin object and disables unmounting tmpfs - * in ZoneConnectionTransport. + * This sends detach flag to ZoneAdmin object. */ void setDetachOnExit(); @@ -174,65 +163,12 @@ public: */ bool isPaused(); - // ZoneConnection API - /** * @return Is switching to default zone after timeout allowed? */ bool isSwitchToDefaultAfterTimeoutAllowed() const; /** - * Register notification request callback - */ - void setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback); - - /** - * Register callback used when switching to default zone. - */ - void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); - - /** - * Register proxy call callback - */ - void setProxyCallCallback(const ProxyCallCallback& callback); - - /** - * Send notification signal to this zone - * - * @param zone name of zone in which the notification occurred - * @param application name of application that cause notification - * @param message message to be send to zone - */ - void sendNotification(const std::string& zone, - const std::string& application, - const std::string& message); - - /** - * Register file move request callback - */ - void setFileMoveCallback(const FileMoveCallback& callback); - - /** - * Register dbus state changed callback - */ - void setConnectionStateChangedCallback(const ConnectionStateChangedCallback& callback); - - /** - * Make a proxy call - */ - void proxyCallAsync(const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters, - const dbus::DbusConnection::AsyncMethodCallCallback& callback); - - /** - * Get a dbus address - */ - std::string getConnectionAddress() const; - - /** * Get id of VT */ int getVT() const; @@ -317,30 +253,18 @@ public: void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip); private: - utils::Worker::Pointer mWorker; ZoneConfig mConfig; ZoneDynamicConfig mDynamicConfig; std::vector mPermittedToSend; std::vector mPermittedToRecv; - std::unique_ptr mConnectionTransport; std::unique_ptr mAdmin; - std::unique_ptr mConnection; std::unique_ptr mProvision; mutable std::recursive_mutex mReconnectMutex; - NotifyActiveZoneCallback mNotifyCallback; - SwitchToDefaultCallback mSwitchToDefaultCallback; - FileMoveCallback mFileMoveCallback; - ProxyCallCallback mProxyCallCallback; - ConnectionStateChangedCallback mConnectionStateChangedCallback; - std::string mConnectionAddress; std::string mRunMountPoint; std::string mRootPath; std::string mDbPath; void onNameLostCallback(); - void reconnectHandler(); - void connect(); - void disconnect(); void saveDynamicConfig(); void updateRequestedState(const std::string& state); }; diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 1b6edf3..e6621d8 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -24,9 +24,12 @@ #include "config.hpp" +#ifdef DBUS_CONNECTION #include "host-dbus-definitions.hpp" -#include "common-dbus-definitions.hpp" -#include "zone-dbus-definitions.hpp" +#else +#include "host-ipc-definitions.hpp" +#endif +#include "common-definitions.hpp" #include "dynamic-config-scheme.hpp" #include "zones-manager.hpp" #include "zone-admin.hpp" @@ -55,6 +58,7 @@ namespace vasum { namespace { +#ifdef ZONE_CONNECTION bool regexMatchVector(const std::string& str, const std::vector& v) { for (const boost::regex& toMatch : v) { @@ -65,6 +69,7 @@ bool regexMatchVector(const std::string& str, const std::vector& v return false; } +#endif const std::string HOST_ID = "host"; const std::string ENABLED_FILE_NAME = "enabled"; @@ -124,17 +129,14 @@ ZonesManager::ZonesManager(const std::string& configPath) mDynamicConfig, getVasumDbPrefix()); - mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); using namespace std::placeholders; #ifdef DBUS_CONNECTION + mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); mHostConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall, this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); #endif - mHostConnection.setGetZoneConnectionsCallback(bind(&ZonesManager::handleGetZoneConnectionsCall, - this, _1)); - mHostConnection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall, this, _1)); @@ -210,6 +212,15 @@ ZonesManager::ZonesManager(const std::string& configPath) mHostConnection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall, this, _1, _2)); + mHostConnection.setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, + this, "", _1, _2)); + + mHostConnection.setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, + this, "")); + + mHostConnection.setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, + this, "", _1, _2)); + for (const auto& zoneId : mDynamicConfig.zoneIds) { insertZone(zoneId, getTemplatePathForExistingZone(zoneId)); } @@ -307,30 +318,13 @@ void ZonesManager::insertZone(const std::string& zoneId, const std::string& zone } LOGT("Creating Zone " << zoneId); - std::unique_ptr zone(new Zone(mWorker->createSubWorker(), - zoneId, + std::unique_ptr zone(new Zone(zoneId, mConfig.zonesPath, zoneTemplatePath, mConfig.dbPath, mConfig.lxcTemplatePrefix, mConfig.runMountPointPrefix)); - using namespace std::placeholders; - zone->setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, - this, zoneId, _1, _2, _3)); - - zone->setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, - this, zoneId)); - - zone->setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, - this, zoneId, _1, _2, _3)); - - zone->setProxyCallCallback(bind(&ZonesManager::handleProxyCall, - this, zoneId, _1, _2, _3, _4, _5, _6, _7)); - - zone->setConnectionStateChangedCallback(bind(&ZonesManager::handleConnectionStateChanged, - this, zoneId, _1)); - mZones.push_back(std::move(zone)); // after zone is created successfully, put a file informing that zones are enabled @@ -556,28 +550,6 @@ void ZonesManager::setZonesDetachOnExit() } } -void ZonesManager::handleNotifyActiveZoneCall(const std::string& caller, - const std::string& application, - const std::string& message, - api::MethodResultBuilder::Pointer result) -{ - LOGI("handleNotifyActiveZoneCall(" << caller << ", " << application << ", " << message - << ") called"); - - Lock lock(mMutex); - - try { - auto iter = getRunningForegroundZoneIterator(); - if (iter != mZones.end() && caller != get(iter).getId()) { - get(iter).sendNotification(caller, application, message); - } - result->setVoid(); - } catch (const VasumException&) { - LOGE("Notification from " << caller << " hasn't been sent"); - result->setError(api::ERROR_INTERNAL, "Notification hasn't been sent"); - } -} - void ZonesManager::handleSwitchToDefaultCall(const std::string& /*caller*/) { // get config of currently set zone and switch if switchToDefaultAfterTimeout is true @@ -596,10 +568,33 @@ void ZonesManager::handleSwitchToDefaultCall(const std::string& /*caller*/) } } +#ifdef ZONE_CONNECTION +void ZonesManager::handleNotifyActiveZoneCall(const std::string& caller, + const api::NotifActiveZoneIn& notif, + api::MethodResultBuilder::Pointer result) +{ + const std::string& application = notif.first; + const std::string& message = notif.second; + LOGI("handleNotifyActiveZoneCall(" << caller << ", " << application << ", " << message + << ") called"); + + Lock lock(mMutex); + + try { + auto iter = getRunningForegroundZoneIterator(); + if (iter != mZones.end() && caller != get(iter).getId()) { + //XXX:get(iter).sendNotification(caller, application, message); + } + result->setVoid(); + } catch (const VasumException&) { + LOGE("Notification from " << caller << " hasn't been sent"); + result->setError(api::ERROR_INTERNAL, "Notification hasn't been sent"); + } +} + void ZonesManager::handleFileMoveCall(const std::string& srcZoneId, - const std::string& dstZoneId, - const std::string& path, - api::MethodResultBuilder::Pointer result) + const api::FileMoveRequestIn& request, + api::MethodResultBuilder::Pointer result) { // TODO: this implementation is only a placeholder. // There are too many unanswered questions and security concerns: @@ -620,6 +615,8 @@ void ZonesManager::handleFileMoveCall(const std::string& srcZoneId, // Now when the main process has obtained FDs (by either of those methods) // it can do the copying by itself. + const std::string& dstZoneId = request.first; + const std::string& path = request.second; LOGI("File move requested\n" << "src: " << srcZoneId << "\n" << "dst: " << dstZoneId << "\n" @@ -639,7 +636,7 @@ void ZonesManager::handleFileMoveCall(const std::string& srcZoneId, auto dstIter = findZone(dstZoneId); if (dstIter == mZones.end()) { LOGE("Destination zone '" << dstZoneId << "' not found"); - status->value = api::zone::FILE_MOVE_DESTINATION_NOT_FOUND; + status->value = api::FILE_MOVE_DESTINATION_NOT_FOUND; result->set(status); return; } @@ -647,21 +644,21 @@ void ZonesManager::handleFileMoveCall(const std::string& srcZoneId, if (srcZoneId == dstZoneId) { LOGE("Cannot send a file to yourself"); - status->value = api::zone::FILE_MOVE_WRONG_DESTINATION; + status->value = api::FILE_MOVE_WRONG_DESTINATION; result->set(status); return; } if (!regexMatchVector(path, srcZone.getPermittedToSend())) { LOGE("Source zone has no permissions to send the file: " << path); - status->value = api::zone::FILE_MOVE_NO_PERMISSIONS_SEND; + status->value = api::FILE_MOVE_NO_PERMISSIONS_SEND; result->set(status); return; } if (!regexMatchVector(path, dstContanier.getPermittedToRecv())) { LOGE("Destination zone has no permissions to receive the file: " << path); - status->value = api::zone::FILE_MOVE_NO_PERMISSIONS_RECEIVE; + status->value = api::FILE_MOVE_NO_PERMISSIONS_RECEIVE; result->set(status); return; } @@ -672,19 +669,36 @@ void ZonesManager::handleFileMoveCall(const std::string& srcZoneId, if (!utils::moveFile(srcPath, dstPath)) { LOGE("Failed to move the file: " << path); - status->value = api::zone::FILE_MOVE_FAILED; + status->value = api::FILE_MOVE_FAILED; result->set(status); } else { - status->value = api::zone::FILE_MOVE_SUCCEEDED; + status->value = api::FILE_MOVE_SUCCEEDED; result->set(status); try { - dstContanier.sendNotification(srcZoneId, path, api::zone::FILE_MOVE_SUCCEEDED); + //XXX: dstContanier.sendNotification(srcZoneId, path, api::FILE_MOVE_SUCCEEDED); } catch (ServerException&) { LOGE("Notification to '" << dstZoneId << "' has not been sent"); } } } +#else +void ZonesManager::handleNotifyActiveZoneCall(const std::string& /* caller */, + const api::NotifActiveZoneIn& /*notif*/, + api::MethodResultBuilder::Pointer result) +{ + result->setError(api::ERROR_INTERNAL, "Not implemented"); +} + +void ZonesManager::handleFileMoveCall(const std::string& /*srcZoneId*/, + const api::FileMoveRequestIn& /*request*/, + api::MethodResultBuilder::Pointer result) +{ + result->setError(api::ERROR_INTERNAL, "Not implemented"); +} +#endif /* ZONE_CONNECTION */ + +#ifdef DBUS_CONNECTION void ZonesManager::handleProxyCall(const std::string& caller, const std::string& target, const std::string& targetBusName, @@ -718,54 +732,19 @@ void ZonesManager::handleProxyCall(const std::string& caller, } }; - if (target == HOST_ID) { -#ifdef DBUS_CONNECTION - mHostConnection.proxyCallAsync(targetBusName, - targetObjectPath, - targetInterface, - targetMethod, - parameters, - asyncResultCallback); -#else - result->setError(api::ERROR_INVALID_ID, "Unsupported proxy call target"); -#endif - return; - } - - Lock lock(mMutex); - - auto targetIter = findZone(target); - if (targetIter == mZones.end()) { - LOGE("Target zone '" << target << "' not found"); + if (target != HOST_ID) { result->setError(api::ERROR_INVALID_ID, "Unknown proxy call target"); return; } - Zone& targetZone = get(targetIter); - targetZone.proxyCallAsync(targetBusName, - targetObjectPath, - targetInterface, - targetMethod, - parameters, - asyncResultCallback); -} - -void ZonesManager::handleGetZoneConnectionsCall(api::MethodResultBuilder::Pointer result) -{ - Lock lock(mMutex); - - auto connections = std::make_shared(); - for (auto& zone : mZones) { - connections->values.push_back({zone->getId(), zone->getConnectionAddress()}); - } - result->set(connections); -} - -void ZonesManager::handleConnectionStateChanged(const std::string& zoneId , - const std::string& address) -{ - mHostConnection.signalZoneConnectionState({zoneId, address}); + mHostConnection.proxyCallAsync(targetBusName, + targetObjectPath, + targetInterface, + targetMethod, + parameters, + asyncResultCallback); } +#endif void ZonesManager::handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result) { @@ -1081,7 +1060,7 @@ void ZonesManager::handleSetActiveZoneCall(const api::ZoneId& zoneId, if (!get(iter).isRunning()) { LOGE("Could not activate stopped or paused zone"); - result->setError(api::host::ERROR_ZONE_NOT_RUNNING, + result->setError(api::ERROR_ZONE_NOT_RUNNING, "Could not activate stopped or paused zone"); return; } diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 31c90cd..42477ae 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -30,11 +30,11 @@ #include "zones-manager-config.hpp" #ifdef DBUS_CONNECTION #include "host-dbus-connection.hpp" +#include "proxy-call-policy.hpp" #else #include "host-ipc-connection.hpp" #endif #include "input-monitor.hpp" -#include "proxy-call-policy.hpp" #include "utils/worker.hpp" #include "api/method-result-builder.hpp" @@ -131,7 +131,6 @@ private: HostConnection mHostConnection; // to hold InputMonitor pointer to monitor if zone switching sequence is recognized std::unique_ptr mSwitchingSequenceMonitor; - std::unique_ptr mProxyCallPolicy; // like set but keep insertion order // smart pointer is needed because Zone is not moveable (because of mutex) typedef std::vector> Zones; @@ -157,14 +156,14 @@ private: // Zone's handlers--------------------------------------------------------- void handleNotifyActiveZoneCall(const std::string& caller, - const std::string& appliaction, - const std::string& message, + const api::NotifActiveZoneIn& notif, api::MethodResultBuilder::Pointer result); void handleSwitchToDefaultCall(const std::string& caller); void handleFileMoveCall(const std::string& srcZoneId, - const std::string& dstZoneId, - const std::string& path, + const api::FileMoveRequestIn& request, api::MethodResultBuilder::Pointer result); +#ifdef DBUS_CONNECTION + std::unique_ptr mProxyCallPolicy; void handleProxyCall(const std::string& caller, const std::string& target, const std::string& targetBusName, @@ -173,10 +172,8 @@ private: const std::string& targetMethod, GVariant* parameters, dbus::MethodResultBuilder::Pointer result); - void handleGetZoneConnectionsCall(api::MethodResultBuilder::Pointer result); - void handleConnectionStateChanged(const std::string& zoneId, - const std::string& address); - // Host's handlers -------------------------------------------------------- +#endif + // Handlers -------------------------------------------------------- void handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result); void handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer result); void handleGetZoneInfoCall(const api::ZoneId& data, diff --git a/tests/unit_tests/client/configs/CMakeLists.txt b/tests/unit_tests/client/configs/CMakeLists.txt index 5587d11..64618ed 100644 --- a/tests/unit_tests/client/configs/CMakeLists.txt +++ b/tests/unit_tests/client/configs/CMakeLists.txt @@ -26,6 +26,8 @@ FILE(GLOB client_manager_CONF_GEN ${CMAKE_BINARY_DIR}/ut-client/*.conf) CONFIGURE_FILE(ut-client/templates/console-dbus.conf.in ${CMAKE_BINARY_DIR}/ut-client/templates/console-dbus.conf @ONLY) +CONFIGURE_FILE(ut-client/templates/console-ipc.conf.in + ${CMAKE_BINARY_DIR}/ut-client/templates/console-ipc.conf @ONLY) FILE(GLOB client_templates_CONF_GEN ${CMAKE_BINARY_DIR}/ut-client/templates/*.conf) ## Install ##################################################################### diff --git a/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in b/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in index 3481c09..2ff5998 100644 --- a/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in +++ b/tests/unit_tests/client/configs/ut-client/templates/console-dbus.conf.in @@ -7,7 +7,6 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/client/configs/ut-client/templates/console-ipc.conf.in b/tests/unit_tests/client/configs/ut-client/templates/console-ipc.conf.in new file mode 100644 index 0000000..b7b103a --- /dev/null +++ b/tests/unit_tests/client/configs/ut-client/templates/console-ipc.conf.in @@ -0,0 +1,18 @@ +{ + "lxcTemplate" : "minimal-dbus.sh", + "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "requestedState" : "running", + "ipv4Gateway" : "", + "ipv4" : "", + "privilege" : 20, + "vt" : -1, + "switchToDefaultAfterTimeout" : true, + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, + "runMountPoint" : "/tmp/ut-run/~NAME~", + "provisions" : [], + "permittedToSend" : [ "/tmp/.*" ], + "permittedToRecv" : [ "/tmp/.*" ], + "validLinkPrefixes" : [] +} diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index d53238f..f0e6b2e 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -23,6 +23,8 @@ * @brief Unit tests of the client C API */ +#ifndef DBUS_CONNECTION + #include #include "ut.hpp" #include @@ -30,7 +32,7 @@ #include "utils/latch.hpp" #include "utils/scoped-dir.hpp" #include "zones-manager.hpp" -#include "zone-dbus-definitions.hpp" +#include "host-ipc-definitions.hpp" #include "logger/logger.hpp" #include @@ -49,35 +51,23 @@ namespace { const std::string TEST_CONFIG_PATH = VSM_TEST_CONFIG_INSTALL_DIR "/client/ut-client/test-daemon.conf"; const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf -const std::string TEMPLATE_NAME = "console-dbus"; - -struct Loop { - Loop() - { - vsm_start_glib_loop(); - } - ~Loop() - { - vsm_stop_glib_loop(); - } -}; +const std::string TEMPLATE_NAME = "console-ipc"; struct Fixture { - Loop loop; utils::ScopedDir mZonesPathGuard; utils::ScopedDir mRunGuard; - ZonesManager cm; + std::unique_ptr cm; Fixture() : mZonesPathGuard(ZONES_PATH) , mRunGuard("/tmp/ut-run") - , cm(TEST_CONFIG_PATH) + , cm(new ZonesManager(TEST_CONFIG_PATH)) { - cm.createZone("zone1", TEMPLATE_NAME); - cm.createZone("zone2", TEMPLATE_NAME); - cm.createZone("zone3", TEMPLATE_NAME); - cm.restoreAll(); + cm->createZone("zone1", TEMPLATE_NAME); + cm->createZone("zone2", TEMPLATE_NAME); + cm->createZone("zone3", TEMPLATE_NAME); + cm->restoreAll(); LOGI("------- setup complete --------"); } @@ -87,32 +77,7 @@ struct Fixture { } }; -const int EVENT_TIMEOUT = 5000; ///< ms -const std::map EXPECTED_CONNECTIONS = { - { - "zone1", - "unix:path=/tmp/ut-run/zone1/dbus/system_bus_socket" - }, - { - "zone2", - "unix:path=/tmp/ut-run/zone2/dbus/system_bus_socket" - }, - { - "zone3", - "unix:path=/tmp/ut-run/zone3/dbus/system_bus_socket" - } -}; - -void convertDictToMap(VsmArrayString keys, - VsmArrayString values, - std::map& ret) -{ - VsmArrayString iKeys; - VsmArrayString iValues; - for (iKeys = keys, iValues = values; *iKeys && *iValues; iKeys++, iValues++) { - ret.insert(std::make_pair(*iKeys, *iValues)); - } -} +const std::set EXPECTED_ZONES = { "zone1", "zone2", "zone3" }; void convertArrayToSet(VsmArrayString values, std::set& ret) { @@ -153,35 +118,11 @@ BOOST_FIXTURE_TEST_SUITE(ClientSuite, Fixture) BOOST_AUTO_TEST_CASE(NotRunningServer) { - cm.shutdownAll(); - - VsmClient client = vsm_client_create(); - VsmStatus status = vsm_connect_custom(client, - EXPECTED_CONNECTIONS.begin()->second.c_str()); - BOOST_CHECK_EQUAL(VSMCLIENT_IO_ERROR, status); - vsm_client_free(client); -} + cm.reset(); -BOOST_AUTO_TEST_CASE(GetZoneConnections) -{ VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); - BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - VsmArrayString keys, values; - status = vsm_get_zone_dbuses(client, &keys, &values); - //TODO: Clean up if BOOST_REQUIRE_EQUAL fail (remove client). Same in other client tests. - BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - - BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_CONNECTIONS.size() + 1u), - EXPECTED_CONNECTIONS.size()); - BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_CONNECTIONS.size() + 1u), - EXPECTED_CONNECTIONS.size()); - - std::map zones; - convertDictToMap(keys, values, zones); - BOOST_CHECK(zones == EXPECTED_CONNECTIONS); - vsm_array_string_free(keys); - vsm_array_string_free(values); + BOOST_CHECK_EQUAL(VSMCLIENT_IO_ERROR, status); vsm_client_free(client); } @@ -193,14 +134,14 @@ BOOST_AUTO_TEST_CASE(GetZoneIds) VsmArrayString values; status = vsm_get_zone_ids(client, &values); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_CONNECTIONS.size() + 1u), - EXPECTED_CONNECTIONS.size()); + BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_ZONES.size() + 1u), + EXPECTED_ZONES.size()); std::set zones; convertArrayToSet(values, zones); for (const auto& zone : zones) { - BOOST_CHECK(EXPECTED_CONNECTIONS.find(zone) != EXPECTED_CONNECTIONS.cend()); + BOOST_CHECK(EXPECTED_ZONES.find(zone) != EXPECTED_ZONES.cend()); } vsm_array_string_free(values); vsm_client_free(client); @@ -215,7 +156,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) status = vsm_get_active_zone_id(client, &zone); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(zone, cm.getRunningForegroundZoneId()); + BOOST_CHECK_EQUAL(zone, cm->getRunningForegroundZoneId()); vsm_string_free(zone); vsm_client_free(client); @@ -245,14 +186,14 @@ BOOST_AUTO_TEST_CASE(SetActiveZone) { const std::string newActiveZoneId = "zone2"; - BOOST_REQUIRE_NE(newActiveZoneId, cm.getRunningForegroundZoneId()); + BOOST_REQUIRE_NE(newActiveZoneId, cm->getRunningForegroundZoneId()); VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); status = vsm_set_active_zone(client, newActiveZoneId.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); - BOOST_CHECK_EQUAL(newActiveZoneId, cm.getRunningForegroundZoneId()); + BOOST_CHECK_EQUAL(newActiveZoneId, cm->getRunningForegroundZoneId()); vsm_client_free(client); } @@ -296,17 +237,18 @@ BOOST_AUTO_TEST_CASE(LockUnlockZone) vsm_client_free(client); } +#ifdef ZONE_CONNECTION BOOST_AUTO_TEST_CASE(FileMoveRequest) { const std::string path = "/tmp/fake_path"; const std::string secondZone = "fake_zone"; VsmClient client = vsm_client_create(); - VsmStatus status = vsm_connect_custom(client, EXPECTED_CONNECTIONS.begin()->second.c_str()); + VsmStatus status = vsm_connect(client); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); status = vsm_file_move_request(client, secondZone.c_str(), path.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_CUSTOM_ERROR, status); - BOOST_REQUIRE_EQUAL(api::zone::FILE_MOVE_DESTINATION_NOT_FOUND, + BOOST_REQUIRE_EQUAL(api::FILE_MOVE_DESTINATION_NOT_FOUND, vsm_get_status_message(client)); vsm_client_free(client); } @@ -332,9 +274,9 @@ BOOST_AUTO_TEST_CASE(Notification) CallbackData callbackData; std::map clients; - for (const auto& it : EXPECTED_CONNECTIONS) { + for (const auto& it : EXPECTED_ZONES) { VsmClient client = vsm_client_create(); - VsmStatus status = vsm_connect_custom(client, it.second.c_str()); + VsmStatus status = vsm_connect_custom(client, it.c_str()); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); clients[it.first] = client; } @@ -365,6 +307,7 @@ BOOST_AUTO_TEST_CASE(Notification) vsm_client_free(client.second); } } +#endif BOOST_AUTO_TEST_CASE(GetZoneIdByPidTestSingle) { @@ -398,8 +341,8 @@ BOOST_AUTO_TEST_CASE(GetZoneIdByPidTestMultiple) BOOST_CHECK(ids.count("host") == 1); - for (const auto& dbus : EXPECTED_CONNECTIONS) { - BOOST_CHECK(ids.count(dbus.first) == 1); + for (const auto& dbus : EXPECTED_ZONES) { + BOOST_CHECK(ids.count(dbus) == 1); } } @@ -429,7 +372,7 @@ BOOST_AUTO_TEST_CASE(Provision) { VsmClient client = vsm_client_create(); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, vsm_connect(client)); - const std::string zone = cm.getRunningForegroundZoneId(); + const std::string zone = cm->getRunningForegroundZoneId(); VsmArrayString declarations; BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, vsm_list_declarations(client, zone.c_str(), &declarations)); BOOST_REQUIRE(declarations != NULL && declarations[0] == NULL); @@ -469,3 +412,5 @@ BOOST_AUTO_TEST_CASE(ZoneGetNetdevs) BOOST_AUTO_TEST_SUITE_END() + +#endif /* !DBUS_CONNECTION */ diff --git a/tests/unit_tests/lxc/templates/minimal-dbus.sh b/tests/unit_tests/lxc/templates/minimal-dbus.sh index a8ff5b9..a33ccac 100755 --- a/tests/unit_tests/lxc/templates/minimal-dbus.sh +++ b/tests/unit_tests/lxc/templates/minimal-dbus.sh @@ -68,7 +68,6 @@ 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-run/${name} var/run none rw,bind 0 0 EOF if [ "$(uname -m)" = "x86_64" ]; then diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt index 6c8a1af..c5880b1 100644 --- a/tests/unit_tests/server/configs/CMakeLists.txt +++ b/tests/unit_tests/server/configs/CMakeLists.txt @@ -32,8 +32,6 @@ FILE(GLOB zone_provision_CONF ut-zone-provision/*.conf) FILE(GLOB admin_templates_CONF ut-zone-admin/templates/*.conf) -FILE(GLOB connection_CONF ut-zone-connection/*.conf) - ## Generate #################################################################### CONFIGURE_FILE(ut-server/test-daemon.conf.in @@ -50,6 +48,8 @@ FILE(GLOB manager_manager_CONF_GEN ${CMAKE_BINARY_DIR}/ut-zones-manager/*.conf) CONFIGURE_FILE(ut-zones-manager/templates/console-dbus.conf.in ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/console-dbus.conf @ONLY) +CONFIGURE_FILE(ut-zones-manager/templates/console-ipc.conf.in + ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/console-ipc.conf @ONLY) FILE(GLOB manager_templates_CONF_GEN ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/*.conf) @@ -83,8 +83,5 @@ INSTALL(FILES ${zone_provision_CONF} INSTALL(FILES ${admin_templates_CONF} DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/server/ut-zone-admin/templates) -INSTALL(FILES ${connection_CONF} - DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/server/ut-zone-connection) - INSTALL(FILES dbus-1/system.d/org.tizen.vasum.tests.conf DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/) diff --git a/tests/unit_tests/server/configs/ut-server/templates/default.conf b/tests/unit_tests/server/configs/ut-server/templates/default.conf index d07ecc6..5261493 100644 --- a/tests/unit_tests/server/configs/ut-server/templates/default.conf +++ b/tests/unit_tests/server/configs/ut-server/templates/default.conf @@ -7,7 +7,6 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf index c3b07fe..99bc05e 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/buggy.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf index 7e20d62..6c7ce34 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/missing.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf index 4aa7bd2..e4f2bf9 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/test-no-shutdown.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf b/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf index 5083c0e..8af8d42 100644 --- a/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf +++ b/tests/unit_tests/server/configs/ut-zone-admin/templates/test.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone-connection/ut-dbus.conf b/tests/unit_tests/server/configs/ut-zone-connection/ut-dbus.conf deleted file mode 100644 index 66ee3f9..0000000 --- a/tests/unit_tests/server/configs/ut-zone-connection/ut-dbus.conf +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - custom - unix:path=/tmp/ut-zones/mount-point/dbus/system_bus_socket - - - - - - - - - - diff --git a/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf b/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf index 1e71ece..5c98cfd 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in b/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in index da02e3b..d2fea11 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-zone/templates/test-dbus.conf.in @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zone/templates/test.conf b/tests/unit_tests/server/configs/ut-zone/templates/test.conf index 7827fe3..38907a0 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/test.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/test.conf @@ -7,7 +7,6 @@ "privilege" : 10, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in index 3481c09..2ff5998 100644 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in +++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in @@ -7,7 +7,6 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in new file mode 100644 index 0000000..fab7e58 --- /dev/null +++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in @@ -0,0 +1,18 @@ +{ + "lxcTemplate" : "minimal.sh", + "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], + "requestedState" : "running", + "ipv4Gateway" : "", + "ipv4" : "", + "privilege" : 20, + "vt" : -1, + "switchToDefaultAfterTimeout" : true, + "cpuQuotaForeground" : -1, + "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, + "runMountPoint" : "/tmp/ut-run/~NAME~", + "provisions" : [], + "permittedToSend" : [ "/tmp/.*" ], + "permittedToRecv" : [ "/tmp/.*" ], + "validLinkPrefixes" : [] +} diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf b/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf index d9f69ec..02a7dc6 100644 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf +++ b/tests/unit_tests/server/configs/ut-zones-manager/templates/console.conf @@ -7,7 +7,6 @@ "privilege" : 20, "vt" : -1, "switchToDefaultAfterTimeout" : true, - "enableZoneConnection" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "shutdownTimeout" : 10, diff --git a/tests/unit_tests/server/ut-zone-connection.cpp b/tests/unit_tests/server/ut-zone-connection.cpp deleted file mode 100644 index c374c81..0000000 --- a/tests/unit_tests/server/ut-zone-connection.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* - * 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 ZoneConnection class - */ - -#include "config.hpp" -#include "ut.hpp" - -#include "zone-connection.hpp" -#include "zone-connection-transport.hpp" -#include "host-dbus-definitions.hpp" -#include "zone-dbus-definitions.hpp" -// TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager -#include "fake-power-manager-dbus-definitions.hpp" - -#include "dbus/connection.hpp" -#include "dbus/exception.hpp" -#include "utils/scoped-daemon.hpp" -#include "utils/glib-loop.hpp" -#include "utils/latch.hpp" -#include "utils/fs.hpp" -#include "utils/scoped-dir.hpp" - -#include "api/method-result-builder.hpp" - - -using namespace vasum; -using namespace vasum::utils; -using namespace dbus; - -namespace { - -const char* DBUS_DAEMON_PROC = "/usr/bin/dbus-daemon"; -const char* const DBUS_DAEMON_ARGS[] = { - DBUS_DAEMON_PROC, - "--config-file=" VSM_TEST_CONFIG_INSTALL_DIR "/server/ut-zone-connection/ut-dbus.conf", - "--nofork", - NULL -}; - -const std::string ZONES_PATH = "/tmp/ut-zones"; -const std::string TRANSPORT_MOUNT_POINT = ZONES_PATH + "/mount-point"; -const int EVENT_TIMEOUT = 1000; - -class Fixture { -public: - Fixture() - : mZonesPathGuard(ZONES_PATH) - , mTransport(TRANSPORT_MOUNT_POINT) - { - mDaemon.start(DBUS_DAEMON_PROC, DBUS_DAEMON_ARGS); - } - - std::string acquireAddress() - { - return mTransport.acquireAddress(); - } -private: - ScopedGlibLoop mLoop; - ScopedDir mZonesPathGuard; - ZoneConnectionTransport mTransport; - ScopedDaemon mDaemon; -}; - -class DbusNameSetter { -public: - DbusNameSetter() - : mNameAcquired(false), - mPendingDisconnect(false) - { - } - - void setName(const std::unique_ptr& conn, const std::string& name) - { - conn->setName(name, - std::bind(&DbusNameSetter::onNameAcquired, this), - std::bind(&DbusNameSetter::onDisconnect, this)); - - if(!waitForName()) { - throw dbus::DbusOperationException("Could not acquire name."); - } - } - - bool waitForName() - { - std::unique_lock lock(mMutex); - mNameCondition.wait(lock, [this] {return mNameAcquired || mPendingDisconnect;}); - return mNameAcquired; - } - - void onNameAcquired() - { - std::unique_lock lock(mMutex); - mNameAcquired = true; - mNameCondition.notify_one(); - } - - void onDisconnect() - { - std::unique_lock lock(mMutex); - mPendingDisconnect = true; - mNameCondition.notify_one(); - } - -private: - bool mNameAcquired; - bool mPendingDisconnect; - std::mutex mMutex; - std::condition_variable mNameCondition; -}; - -} // namespace - -BOOST_FIXTURE_TEST_SUITE(ZoneConnectionSuite, Fixture) - -BOOST_AUTO_TEST_CASE(ConstructorDestructorConnect) -{ - ZoneConnection(acquireAddress(), nullptr); -} - -BOOST_AUTO_TEST_CASE(NotifyActiveZoneApi) -{ - Latch notifyCalled; - ZoneConnection connection(acquireAddress(), nullptr); - - auto callback = [&](const std::string& application, const std::string& message, api::MethodResultBuilder::Pointer result) { - if (application == "testapp" && message == "testmessage") { - notifyCalled.set(); - } - result->setVoid(); - }; - connection.setNotifyActiveZoneCallback(callback); - - DbusConnection::Pointer client = DbusConnection::create(acquireAddress()); - client->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::METHOD_NOTIFY_ACTIVE_ZONE, - g_variant_new("(ss)", "testapp", "testmessage"), - "()"); - BOOST_CHECK(notifyCalled.wait(EVENT_TIMEOUT)); -} - -BOOST_AUTO_TEST_CASE(SignalNotificationApi) -{ - Latch signalEmitted; - ZoneConnection connection(acquireAddress(), nullptr); - - DbusConnection::Pointer client = DbusConnection::create(acquireAddress()); - - auto handler = [&](const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters) { - if (objectPath == api::zone::OBJECT_PATH && - interface == api::zone::INTERFACE && - signalName == api::zone::SIGNAL_NOTIFICATION && - g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { - - const gchar* zone = NULL; - const gchar* application = NULL; - const gchar* message = NULL; - g_variant_get(parameters, "(&s&s&s)", &zone, &application, &message); - if (zone == std::string("testzone") && - application == std::string("testapp") && - message == std::string("testmessage")) { - signalEmitted.set(); - } - } - }; - client->signalSubscribe(handler, api::zone::BUS_NAME); - - connection.sendNotification("testzone", "testapp", "testmessage"); - - BOOST_CHECK(signalEmitted.wait(EVENT_TIMEOUT)); -} - -BOOST_AUTO_TEST_CASE(SignalSwitchToDefaultApi) -{ - Latch switchToDefaultCalled; - ZoneConnection connection(acquireAddress(), nullptr); - - DbusConnection::Pointer client = DbusConnection::create(acquireAddress()); - - auto callback = [&]() { - switchToDefaultCalled.set(); - }; - - connection.setSwitchToDefaultCallback(callback); - - client->emitSignal(fake_power_manager_api::OBJECT_PATH, - fake_power_manager_api::INTERFACE, - fake_power_manager_api::SIGNAL_DISPLAY_OFF, - nullptr); - - // timeout should occur, since no name is set to client - BOOST_CHECK(!switchToDefaultCalled.wait(EVENT_TIMEOUT)); - - DbusNameSetter setter; - - setter.setName(client, fake_power_manager_api::BUS_NAME); - - client->emitSignal(fake_power_manager_api::OBJECT_PATH, - fake_power_manager_api::INTERFACE, - fake_power_manager_api::SIGNAL_DISPLAY_OFF, - nullptr); - - // now signal should be delivered correctly - BOOST_CHECK(switchToDefaultCalled.wait(EVENT_TIMEOUT)); -} - - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index dc66753..b4938b4 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -84,8 +84,7 @@ struct Fixture { std::unique_ptr create(const std::string& configPath) { - return std::unique_ptr(new Zone(utils::Worker::create(), - "zoneId", + return std::unique_ptr(new Zone("zoneId", ZONES_PATH, configPath, DB_PATH, diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp index 5a9693f..a2811a9 100644 --- a/tests/unit_tests/server/ut-zones-manager.cpp +++ b/tests/unit_tests/server/ut-zones-manager.cpp @@ -27,22 +27,21 @@ #include "ut.hpp" #include "zones-manager.hpp" -#include "zone-dbus-definitions.hpp" #ifdef DBUS_CONNECTION +// TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager +#include "fake-power-manager-dbus-definitions.hpp" #include "host-dbus-definitions.hpp" +#include "test-dbus-definitions.hpp" +#include "dbus/connection.hpp" +#include "dbus/exception.hpp" #else #include "host-ipc-definitions.hpp" #include #include #include #endif -#include "test-dbus-definitions.hpp" -// TODO: Switch to real power-manager dbus defs when they will be implemented in power-manager -#include "fake-power-manager-dbus-definitions.hpp" #include "exception.hpp" -#include "dbus/connection.hpp" -#include "dbus/exception.hpp" #include "utils/glib-loop.hpp" #include "config/exception.hpp" #include "utils/latch.hpp" @@ -64,7 +63,9 @@ using namespace vasum; using namespace config; using namespace vasum::utils; +#ifdef DBUS_CONNECTION using namespace dbus; +#endif namespace { @@ -73,7 +74,6 @@ const std::string TEST_CONFIG_PATH = CONFIG_DIR + "/test-daemon.conf"; const std::string MISSING_CONFIG_PATH = CONFIG_DIR + "/missing-daemon.conf"; const int EVENT_TIMEOUT = 5000; //const int UNEXPECTED_EVENT_TIMEOUT = EVENT_TIMEOUT / 5; -const int TEST_DBUS_CONNECTION_ZONES_COUNT = 3; const std::string TEST_APP_NAME = "testapp"; const std::string TEST_MESSAGE = "testmessage"; const std::string FILE_CONTENT = "File content\n" @@ -82,7 +82,11 @@ const std::string FILE_CONTENT = "File content\n" const std::string NON_EXISTANT_ZONE_ID = "NON_EXISTANT_ZONE_ID"; const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf const std::string SIMPLE_TEMPLATE = "console"; +#ifdef DBUS_CONNECTION const std::string ZONE_ACCESS_TEMPLATE = "console-dbus"; +#else +const std::string ZONE_ACCESS_TEMPLATE = "console-ipc"; +#endif #ifdef DBUS_CONNECTION /** @@ -109,8 +113,7 @@ public: MethodResultBuilder::Pointer result )> TestApiMethodCallback; typedef std::function VoidResultCallback; - typedef std::function SignalCallback; + typedef std::function NotificationCallback; typedef std::map Connections; @@ -165,44 +168,48 @@ public: void signalSubscribe(const DbusConnection::SignalCallback& callback) { - mClient->signalSubscribe(callback, isHost() ? api::host::BUS_NAME : api::zone::BUS_NAME); + mClient->signalSubscribe(callback, isHost() ? api::BUS_NAME : api::BUS_NAME); } - void subscribeZoneConnectionState(const SignalCallback& callback) { - assert(isHost()); - auto onSignal = [callback] (const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters) { - if (objectPath == api::host::OBJECT_PATH && - interface == api::host::INTERFACE && - signalName == api::host::SIGNAL_ZONE_CONNECTION_STATE) { - - const gchar* zoneId = NULL; - const gchar* address = NULL; - g_variant_get(parameters, "(&s&s)", &zoneId, &address); - callback(zoneId, address); + void subscribeNotification(const NotificationCallback& callback) + { + auto handler = [callback](const std::string& /*senderBusName*/, + const std::string& objectPath, + const std::string& interface, + const std::string& signalName, + GVariant* parameters) + { + if (objectPath == api::OBJECT_PATH && + interface == api::INTERFACE && + signalName == api::SIGNAL_NOTIFICATION && + g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { + + const gchar* zone = NULL; + const gchar* application = NULL; + const gchar* message = NULL; + g_variant_get(parameters, "(&s&s&s)", &zone, &application, &message); + callback({zone, application, message}); } }; - mClient->signalSubscribe(onSignal, api::host::BUS_NAME); + mClient->signalSubscribe(handler, api::BUS_NAME); } - void emitSignal(const std::string& objectPath, - const std::string& interface, - const std::string& name, - GVariant* parameters) + void signalSwitchToDefault() { - mClient->emitSignal(objectPath, interface, name, parameters); + // emit signal from dbus connection + mClient->emitSignal(api::OBJECT_PATH, + api::INTERFACE, + api::SIGNAL_SWITCH_TO_DEFAULT, + nullptr); } void callMethodNotify() { GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str()); - mClient->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::METHOD_NOTIFY_ACTIVE_ZONE, + mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_NOTIFY_ACTIVE_ZONE, parameters, "()"); } @@ -210,10 +217,10 @@ public: std::string callMethodMove(const std::string& dest, const std::string& path) { GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str()); - GVariantPtr result = mClient->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::METHOD_FILE_MOVE_REQUEST, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_FILE_MOVE_REQUEST, parameters, "(s)"); @@ -271,12 +278,12 @@ public: interface.c_str(), method.c_str(), parameters); - GVariantPtr result = mClient->callMethod(isHost() ? api::host::BUS_NAME : - api::zone::BUS_NAME, - isHost() ? api::host::OBJECT_PATH : - api::zone::OBJECT_PATH, - isHost() ? api::host::INTERFACE : - api::zone::INTERFACE, + GVariantPtr result = mClient->callMethod(isHost() ? api::BUS_NAME : + api::BUS_NAME, + isHost() ? api::OBJECT_PATH : + api::OBJECT_PATH, + isHost() ? api::INTERFACE : + api::INTERFACE, api::METHOD_PROXY_CALL, packedParameters, "(v)"); @@ -285,36 +292,13 @@ public: return GVariantPtr(unpackedResult, g_variant_unref); } - Connections callMethodGetZoneConnections() - { - assert(isHost()); - Connections connections; - GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE, - api::host::METHOD_GET_ZONE_CONNECTIONS, - NULL, - "(a(ss))"); - GVariant* array = NULL; - g_variant_get(result.get(), "(*)", &array); - dbus::GVariantPtr autounref(array, g_variant_unref); - size_t count = g_variant_n_children(array); - for (size_t n = 0; n < count; ++n) { - const char* zoneId = NULL; - const char* address = NULL; - g_variant_get_child(array, n, "(&s&s)", &zoneId, &address); - connections.insert(Connections::value_type(zoneId, address)); - } - return connections; - } - std::vector callMethodGetZoneIds() { assert(isHost()); - GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE, - api::host::METHOD_GET_ZONE_ID_LIST, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_GET_ZONE_ID_LIST, NULL, "(as)"); @@ -336,10 +320,10 @@ public: std::string callMethodGetActiveZoneId() { assert(isHost()); - GVariantPtr result = mClient->callMethod(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE, - api::host::METHOD_GET_ACTIVE_ZONE_ID, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_GET_ACTIVE_ZONE_ID, NULL, "(s)"); @@ -352,10 +336,10 @@ public: { 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_SET_ACTIVE_ZONE, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_SET_ACTIVE_ZONE, parameters, "()"); @@ -373,10 +357,10 @@ public: assert(isHost()); GVariant* parameters = g_variant_new("(ss)", id.c_str(), templateName.c_str()); - mClient->callMethodAsync(api::host::BUS_NAME, - api::host::OBJECT_PATH, - api::host::INTERFACE, - api::host::METHOD_CREATE_ZONE, + mClient->callMethodAsync(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_CREATE_ZONE, parameters, "()", dropException(asyncResult)); @@ -393,10 +377,10 @@ public: 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_ZONE, + mClient->callMethodAsync(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_DESTROY_ZONE, parameters, "()", dropException(asyncResult)); @@ -413,10 +397,10 @@ public: 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_SHUTDOWN_ZONE, + mClient->callMethodAsync(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_SHUTDOWN_ZONE, parameters, "()", dropException(asyncResult)); @@ -433,10 +417,10 @@ public: 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_START_ZONE, + mClient->callMethodAsync(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_START_ZONE, parameters, "()", dropException(asyncResult)); @@ -446,10 +430,10 @@ public: { 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_ZONE, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_LOCK_ZONE, parameters, "()"); } @@ -458,10 +442,10 @@ public: { 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_ZONE, + GVariantPtr result = mClient->callMethod(api::BUS_NAME, + api::OBJECT_PATH, + api::INTERFACE, + api::METHOD_UNLOCK_ZONE, parameters, "()"); } @@ -490,21 +474,14 @@ private: }; typedef DbusAccessory HostAccessory; -typedef DbusAccessory ZoneAccessory; #else //#ifdef DBUS_CONNECTION class HostIPCAccessory { public: - typedef std::function TestApiMethodCallback; typedef std::function VoidResultCallback; - typedef std::function SignalCallback; - - typedef std::map Connections; + typedef std::function NotificationCallback; HostIPCAccessory() : mClient(mDispatcher.getPoll(), HOST_IPC_SOCKET) @@ -512,43 +489,23 @@ public: mClient.start(); } - void subscribeZoneConnectionState(const SignalCallback& callback) - { - auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { - callback(data->first, data->second); - }; - mClient.setSignalHandler(api::host::SIGNAL_ZONE_CONNECTION_STATE, - callbackWrapper); - } - - Connections callMethodGetZoneConnections() - { - const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_CONNECTIONS, - std::make_shared()); - Connections connections; - for (const auto& dbus : out->values) { - connections.insert(Connections::value_type(dbus.first, dbus.second)); - } - return connections; - } - std::vector callMethodGetZoneIds() { - const auto out = mClient.callSync(api::host::METHOD_GET_ZONE_ID_LIST, + const auto out = mClient.callSync(api::METHOD_GET_ZONE_ID_LIST, std::make_shared()); return out->values; } std::string callMethodGetActiveZoneId() { - const auto out = mClient.callSync(api::host::METHOD_GET_ACTIVE_ZONE_ID, + const auto out = mClient.callSync(api::METHOD_GET_ACTIVE_ZONE_ID, std::make_shared()); return out->value; } void callMethodSetActiveZone(const std::string& id) { - mClient.callSync(api::host::METHOD_SET_ACTIVE_ZONE, + mClient.callSync(api::METHOD_SET_ACTIVE_ZONE, std::make_shared(api::ZoneId{id})); } @@ -561,7 +518,7 @@ public: result(); } }; - mClient.callAsync(api::host::METHOD_CREATE_ZONE, + mClient.callAsync(api::METHOD_CREATE_ZONE, std::make_shared(api::CreateZoneIn{id, templateName}), asyncResult); } @@ -574,7 +531,7 @@ public: result(); } }; - mClient.callAsync(api::host::METHOD_DESTROY_ZONE, + mClient.callAsync(api::METHOD_DESTROY_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } @@ -587,7 +544,7 @@ public: result(); } }; - mClient.callAsync(api::host::METHOD_SHUTDOWN_ZONE, + mClient.callAsync(api::METHOD_SHUTDOWN_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } @@ -600,195 +557,62 @@ public: result(); } }; - mClient.callAsync(api::host::METHOD_START_ZONE, + mClient.callAsync(api::METHOD_START_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } void callMethodLockZone(const std::string& id) { - mClient.callSync(api::host::METHOD_LOCK_ZONE, + mClient.callSync(api::METHOD_LOCK_ZONE, std::make_shared(api::ZoneId{id}), EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } void callMethodUnlockZone(const std::string& id) { - mClient.callSync(api::host::METHOD_UNLOCK_ZONE, + mClient.callSync(api::METHOD_UNLOCK_ZONE, std::make_shared(api::ZoneId{id}), EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } -private: - epoll::ThreadDispatcher mDispatcher; - ipc::Client mClient; -}; - -class ZoneDbusAccessory { -public: - typedef std::function TestApiMethodCallback; - - typedef std::map Connections; - - ZoneDbusAccessory(int id) - : mId(id), - mClient(DbusConnection::create(acquireAddress())), - mNameAcquired(false), - mPendingDisconnect(false) - { - } - - void setName(const std::string& name) - { - mClient->setName(name, - std::bind(&ZoneDbusAccessory::onNameAcquired, this), - std::bind(&ZoneDbusAccessory::onDisconnect, this)); - - if(!waitForName()) { - mClient.reset(); - throw dbus::DbusOperationException("Could not acquire name."); - } - } - - bool waitForName() - { - std::unique_lock lock(mMutex); - mNameCondition.wait(lock, [this] {return mNameAcquired || mPendingDisconnect;}); - return mNameAcquired; - } - - void onNameAcquired() - { - std::unique_lock lock(mMutex); - mNameAcquired = true; - mNameCondition.notify_one(); - } - - void onDisconnect() - { - std::unique_lock lock(mMutex); - mPendingDisconnect = true; - mNameCondition.notify_one(); - } - - void signalSubscribe(const DbusConnection::SignalCallback& callback) + void subscribeNotification(const NotificationCallback& callback) { - mClient->signalSubscribe(callback, api::zone::BUS_NAME); + auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { + callback(*data); + }; + mClient.setSignalHandler(api::SIGNAL_NOTIFICATION, + callbackWrapper); } - void emitSignal(const std::string& objectPath, - const std::string& interface, - const std::string& name, - GVariant* parameters) + void signalSwitchToDefault() { - mClient->emitSignal(objectPath, interface, name, parameters); + mClient.signal(api::SIGNAL_SWITCH_TO_DEFAULT, std::make_shared()); } void callMethodNotify() { - GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str()); - mClient->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::METHOD_NOTIFY_ACTIVE_ZONE, - parameters, - "()"); + mClient.callSync( + api::METHOD_NOTIFY_ACTIVE_ZONE, + std::make_shared(api::NotifActiveZoneIn{TEST_APP_NAME, TEST_MESSAGE}), + EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } std::string callMethodMove(const std::string& dest, const std::string& path) { - GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str()); - GVariantPtr result = mClient->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::zone::METHOD_FILE_MOVE_REQUEST, - parameters, - "(s)"); - - const gchar* retcode = NULL; - g_variant_get(result.get(), "(&s)", &retcode); - return std::string(retcode); - } - - void registerTestApiObject(const TestApiMethodCallback& callback) - { - auto handler = [callback](const std::string& objectPath, - const std::string& interface, - const std::string& methodName, - GVariant* parameters, - MethodResultBuilder::Pointer result) { - if (objectPath == testapi::OBJECT_PATH && - interface == testapi::INTERFACE && - methodName == testapi::METHOD) { - const gchar* argument = NULL; - g_variant_get(parameters, "(&s)", &argument); - if (callback) { - callback(argument, result); - } - } - }; - mClient->registerObject(testapi::OBJECT_PATH, testapi::DEFINITION, handler); - } - - std::string testApiProxyCall(const std::string& target, const std::string& argument) - { - GVariant* parameters = g_variant_new("(s)", argument.c_str()); - GVariantPtr result = proxyCall(target, - testapi::BUS_NAME, - testapi::OBJECT_PATH, - testapi::INTERFACE, - testapi::METHOD, - parameters); - const gchar* ret = NULL; - g_variant_get(result.get(), "(&s)", &ret); - return ret; - } - - - GVariantPtr proxyCall(const std::string& target, - const std::string& busName, - const std::string& objectPath, - const std::string& interface, - const std::string& method, - GVariant* parameters) - { - GVariant* packedParameters = g_variant_new("(sssssv)", - target.c_str(), - busName.c_str(), - objectPath.c_str(), - interface.c_str(), - method.c_str(), - parameters); - GVariantPtr result = mClient->callMethod(api::zone::BUS_NAME, - api::zone::OBJECT_PATH, - api::zone::INTERFACE, - api::METHOD_PROXY_CALL, - packedParameters, - "(v)"); - GVariant* unpackedResult = NULL; - g_variant_get(result.get(), "(v)", &unpackedResult); - return GVariantPtr(unpackedResult, g_variant_unref); + auto result = mClient.callSync( + api::METHOD_FILE_MOVE_REQUEST, + std::make_shared(api::FileMoveRequestIn{dest, path}), + EVENT_TIMEOUT*10); + return result->value; } private: - const int mId; - DbusConnection::Pointer mClient; - bool mNameAcquired; - bool mPendingDisconnect; - std::mutex mMutex; - std::condition_variable mNameCondition; - - std::string acquireAddress() const - { - std::string zoneId = "zone" + std::to_string(mId); - return "unix:path=/tmp/ut-run/" + zoneId + "/dbus/system_bus_socket"; - } + epoll::ThreadDispatcher mDispatcher; + ipc::Client mClient; }; typedef HostIPCAccessory HostAccessory; -typedef ZoneDbusAccessory ZoneAccessory; #endif //DBUS_CONNECTION @@ -889,6 +713,16 @@ BOOST_AUTO_TEST_CASE(Focus) BOOST_CHECK(cm.getRunningForegroundZoneId() == "zone3"); } +BOOST_AUTO_TEST_CASE(StartStopWithZoneAccess) +{ + ZonesManager cm(TEST_CONFIG_PATH); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.restoreAll(); +} + +#ifdef ZONE_CONNECTION BOOST_AUTO_TEST_CASE(NotifyActiveZone) { ZonesManager cm(TEST_CONFIG_PATH); @@ -907,37 +741,23 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) auto handler = [](Latch& latch, std::vector& receivedSignalSources, - const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters) + const api::Notification& notify) { - if (objectPath == api::zone::OBJECT_PATH && - interface == api::zone::INTERFACE && - signalName == api::zone::SIGNAL_NOTIFICATION && - g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { - - const gchar* zone = NULL; - const gchar* application = NULL; - const gchar* message = NULL; - g_variant_get(parameters, "(&s&s&s)", &zone, &application, &message); - receivedSignalSources.push_back(zone); - if (application == TEST_APP_NAME && message == TEST_MESSAGE) { - latch.set(); - } + receivedSignalSources.push_back(notify.zone); + if (notify.application == TEST_APP_NAME && notify.message == TEST_MESSAGE) { + latch.set(); } }; using namespace std::placeholders; for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - connections[i]->signalSubscribe(std::bind(handler, - std::ref(signalReceivedLatch), - std::ref(signalReceivedSourcesMap[i]), - _1, _2, _3, _4, _5)); + connections[i]->subscribeNotification(std::bind(handler, + std::ref(signalReceivedLatch), + std::ref(signalReceivedSourcesMap[i]), + _1)); } - for (auto& dbus : connections) { - dbus.second->callMethodNotify(); + for (auto& connection : connections) { + connection.second->callMethodNotify(); } BOOST_REQUIRE(signalReceivedLatch.waitForN(connections.size() - 1u, EVENT_TIMEOUT)); @@ -959,43 +779,6 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) connections.clear(); } -BOOST_AUTO_TEST_CASE(SwitchToDefault) -{ - ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); - cm.restoreAll(); - - std::vector> clients; - for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - clients.push_back(std::unique_ptr(new ZoneAccessory(i))); - } - - for (auto& client : clients) { - client->setName(fake_power_manager_api::BUS_NAME); - } - - auto isDefaultFocused = [&cm]() -> bool { - return cm.getRunningForegroundZoneId() == "zone1"; - }; - - for (auto& client : clients) { - // TEST SWITCHING TO DEFAULT ZONE - // focus non-default zone - cm.focus("zone3"); - - // emit signal from dbus connection - client->emitSignal(fake_power_manager_api::OBJECT_PATH, - fake_power_manager_api::INTERFACE, - fake_power_manager_api::SIGNAL_DISPLAY_OFF, - nullptr); - - // check if default zone has focus - BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, isDefaultFocused)); - } -} - BOOST_AUTO_TEST_CASE(MoveFile) { ZonesManager cm(TEST_CONFIG_PATH); @@ -1014,31 +797,16 @@ BOOST_AUTO_TEST_CASE(MoveFile) connections[i] = std::unique_ptr(new ZoneAccessory(i)); } - auto handler = [&](const std::string& /*senderBusName*/, - const std::string& objectPath, - const std::string& interface, - const std::string& signalName, - GVariant* parameters) + auto handler = [&](const api::Notification& notify) { - if (objectPath == api::zone::OBJECT_PATH && - interface == api::zone::INTERFACE && - signalName == api::zone::SIGNAL_NOTIFICATION && - g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { - - const gchar* source = NULL; - const gchar* path = NULL; - const gchar* retcode = NULL; - g_variant_get(parameters, "(&s&s&s)", &source, &path, &retcode); - - notificationSource = source; - notificationPath = path; - notificationRetcode = retcode; + notificationSource = notify.zone; + notificationPath = notify.application; + notificationRetcode = notify.message; notificationLatch.set(); - } }; // subscribe the second (destination) zone for notifications - connections.at(2)->signalSubscribe(handler); + connections.at(2)->subscribeNotification(handler); const std::string TMP = "/tmp/ut-zones"; const std::string NO_PATH = "path_doesnt_matter_here"; @@ -1051,28 +819,28 @@ BOOST_AUTO_TEST_CASE(MoveFile) // sending to a non existing zone BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(BUGGY_ZONE, NO_PATH), - api::zone::FILE_MOVE_DESTINATION_NOT_FOUND); + api::FILE_MOVE_DESTINATION_NOT_FOUND); BOOST_CHECK(notificationLatch.empty()); // sending to self BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE1, NO_PATH), - api::zone::FILE_MOVE_WRONG_DESTINATION); + api::FILE_MOVE_WRONG_DESTINATION); BOOST_CHECK(notificationLatch.empty()); // no permission to send BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, "/etc/secret1"), - api::zone::FILE_MOVE_NO_PERMISSIONS_SEND); + api::FILE_MOVE_NO_PERMISSIONS_SEND); BOOST_CHECK(notificationLatch.empty()); // no permission to receive // TODO uncomment this after adding an api to change 'permittedTo*' config //BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, "/etc/secret2"), - // api::zone::FILE_MOVE_NO_PERMISSIONS_RECEIVE); + // api::FILE_MOVE_NO_PERMISSIONS_RECEIVE); //BOOST_CHECK(notificationLatch.empty()); // non existing file BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, BUGGY_PATH), - api::zone::FILE_MOVE_FAILED); + api::FILE_MOVE_FAILED); BOOST_CHECK(notificationLatch.empty()); // a working scenario @@ -1085,20 +853,21 @@ BOOST_AUTO_TEST_CASE(MoveFile) BOOST_REQUIRE(utils::saveFileContent(ZONE1PATH + "/file", FILE_CONTENT)); BOOST_CHECK_EQUAL(connections.at(1)->callMethodMove(ZONE2, TMP + "/file"), - api::zone::FILE_MOVE_SUCCEEDED); + api::FILE_MOVE_SUCCEEDED); BOOST_REQUIRE(notificationLatch.wait(EVENT_TIMEOUT)); BOOST_REQUIRE(notificationLatch.empty()); BOOST_CHECK_EQUAL(notificationSource, ZONE1); BOOST_CHECK_EQUAL(notificationPath, TMP + "/file"); - BOOST_CHECK_EQUAL(notificationRetcode, api::zone::FILE_MOVE_SUCCEEDED); + BOOST_CHECK_EQUAL(notificationRetcode, api::FILE_MOVE_SUCCEEDED); BOOST_CHECK(!fs::exists(ZONE1PATH + "/file")); BOOST_CHECK_EQUAL(utils::readFileContent(ZONE2PATH + "/file"), FILE_CONTENT); fs::remove_all(ZONE1PATH, ec); fs::remove_all(ZONE2PATH, ec); } +#endif -BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) +BOOST_AUTO_TEST_CASE(SwitchToDefault) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); @@ -1106,49 +875,21 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); - std::vector> clients; - for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - clients.push_back(std::unique_ptr(new ZoneAccessory(i))); - } - - for (auto& client : clients) { - client->setName(fake_power_manager_api::BUS_NAME); - } + HostAccessory host; auto isDefaultFocused = [&cm]() -> bool { return cm.getRunningForegroundZoneId() == "zone1"; }; - for (auto& client : clients) { - // focus non-default zone with allowed switching - cm.focus("zone3"); - - // emit signal from dbus connection - client->emitSignal(fake_power_manager_api::OBJECT_PATH, - fake_power_manager_api::INTERFACE, - fake_power_manager_api::SIGNAL_DISPLAY_OFF, - nullptr); - - // check if default zone has focus - BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, isDefaultFocused)); + cm.focus("zone3"); - // focus non-default zone with disabled switching - cm.focus("zone2"); + host.signalSwitchToDefault(); - // emit signal from dbus connection - client->emitSignal(fake_power_manager_api::OBJECT_PATH, - fake_power_manager_api::INTERFACE, - fake_power_manager_api::SIGNAL_DISPLAY_OFF, - nullptr); - - // now default zone should not be focused - // TODO uncomment this after adding an api to change 'switchToDefaultAfterTimeout' - //BOOST_CHECK(!spinWaitFor(UNEXPECTED_EVENT_TIMEOUT, isDefaultFocused)); - } + // check if default zone has focus + BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, isDefaultFocused)); } -#ifdef DBUS_CONNECTION -BOOST_AUTO_TEST_CASE(ProxyCall) +BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); @@ -1156,152 +897,83 @@ BOOST_AUTO_TEST_CASE(ProxyCall) cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); cm.restoreAll(); - std::map> connections; - connections[0] = std::unique_ptr(new HostAccessory()); - for (int i = 1; i <= TEST_DBUS_CONNECTION_ZONES_COUNT; ++i) { - connections[i] = std::unique_ptr(new ZoneAccessory(i)); - } + HostAccessory host; - for (auto& dbus : connections) { - dbus.second->setName(testapi::BUS_NAME); + auto isDefaultFocused = [&cm]() -> bool { + return cm.getRunningForegroundZoneId() == "zone1"; + }; - const int id = dbus.first; - auto handler = [id](const std::string& argument, MethodResultBuilder::Pointer result) { - if (argument.empty()) { - result->setError("org.tizen.vasum.Error.Test", "Test error"); - } else { - std::string ret = "reply from " + std::to_string(id) + ": " + argument; - result->set(g_variant_new("(s)", ret.c_str())); - } - }; - dbus.second->registerTestApiObject(handler); - } + // focus non-default zone with allowed switching + cm.focus("zone3"); - // host -> zone2 - BOOST_CHECK_EQUAL("reply from 2: param1", - connections.at(0)->testApiProxyCall("zone2", - "param1")); + host.signalSwitchToDefault(); - // host -> host - BOOST_CHECK_EQUAL("reply from 0: param2", - connections.at(0)->testApiProxyCall("host", - "param2")); + // check if default zone has focus + BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, isDefaultFocused)); + + // focus non-default zone with disabled switching + cm.focus("zone2"); + + host.signalSwitchToDefault(); - // zone1 -> host - BOOST_CHECK_EQUAL("reply from 0: param3", - connections.at(1)->testApiProxyCall("host", - "param3")); + // now default zone should not be focused + // TODO uncomment this after adding an api to change 'switchToDefaultAfterTimeout' + //BOOST_CHECK(!spinWaitFor(UNEXPECTED_EVENT_TIMEOUT, isDefaultFocused)); +} - // zone1 -> zone2 - BOOST_CHECK_EQUAL("reply from 2: param4", - connections.at(1)->testApiProxyCall("zone2", - "param4")); +#ifdef DBUS_CONNECTION +BOOST_AUTO_TEST_CASE(ProxyCall) +{ + ZonesManager cm(TEST_CONFIG_PATH); + cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.restoreAll(); + + HostAccessory host; + host.setName(testapi::BUS_NAME); + + auto handler = [](const std::string& argument, MethodResultBuilder::Pointer result) { + if (argument.empty()) { + result->setError("org.tizen.vasum.Error.Test", "Test error"); + } else { + std::string ret = "reply from host: " + argument; + result->set(g_variant_new("(s)", ret.c_str())); + } + }; + host.registerTestApiObject(handler); - // zone2 -> zone2 - BOOST_CHECK_EQUAL("reply from 2: param5", - connections.at(2)->testApiProxyCall("zone2", - "param5")); + // host -> host + BOOST_CHECK_EQUAL("reply from host: param2", + host.testApiProxyCall("host", "param2")); // host -> unknown - BOOST_CHECK_EXCEPTION(connections.at(0)->testApiProxyCall("unknown", "param"), + BOOST_CHECK_EXCEPTION(host.testApiProxyCall("unknown", "param"), DbusCustomException, WhatEquals("Unknown proxy call target")); // forwarding error - BOOST_CHECK_EXCEPTION(connections.at(0)->testApiProxyCall("host", ""), + BOOST_CHECK_EXCEPTION(host.testApiProxyCall("host", ""), DbusCustomException, WhatEquals("Test error")); // forbidden call - BOOST_CHECK_EXCEPTION(connections.at(0)->proxyCall("host", - "org.fake", - "/a/b", - "c.d", - "foo", - g_variant_new("(s)", "arg")), + BOOST_CHECK_EXCEPTION(host.proxyCall("host", + "org.fake", + "/a/b", + "c.d", + "foo", + g_variant_new("(s)", "arg")), DbusCustomException, WhatEquals("Proxy call forbidden")); } #endif // DBUS_CONNECTION namespace { - const HostAccessory::Connections EXPECTED_CONNECTIONS_NONE = { - {"zone1", ""}, - {"zone2", ""}, - {"zone3", ""}}; - - const HostAccessory::Connections EXPECTED_CONNECTIONS_ALL = { - {"zone1", - "unix:path=/tmp/ut-run/zone1/dbus/system_bus_socket"}, - {"zone2", - "unix:path=/tmp/ut-run/zone2/dbus/system_bus_socket"}, - {"zone3", - "unix:path=/tmp/ut-run/zone3/dbus/system_bus_socket"}}; -} // namespace - -BOOST_AUTO_TEST_CASE(GetZoneConnections) -{ - ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); - - BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); - cm.restoreAll(); - BOOST_CHECK(EXPECTED_CONNECTIONS_ALL == host.callMethodGetZoneConnections()); - cm.shutdownAll(); - BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); -} - -BOOST_AUTO_TEST_CASE(GetZoneConnectionsNoDbus) -{ - ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; - cm.createZone("zone1", SIMPLE_TEMPLATE); - cm.createZone("zone2", SIMPLE_TEMPLATE); - cm.createZone("zone3", SIMPLE_TEMPLATE); - - BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); - cm.restoreAll(); - BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); - cm.shutdownAll(); - BOOST_CHECK(EXPECTED_CONNECTIONS_NONE == host.callMethodGetZoneConnections()); -} -BOOST_AUTO_TEST_CASE(ZoneConnectionsSignals) -{ - Latch signalLatch; - HostAccessory::Connections collectedConnections; - std::mutex collectedConnectionsMutex; - - auto onSignal = [&] (const std::string& zoneId, const std::string& address) { - std::unique_lock lock(collectedConnectionsMutex); - collectedConnections.insert(HostAccessory::Connections::value_type(zoneId, address)); - signalLatch.set(); - }; - - { - ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; - host.subscribeZoneConnectionState(onSignal); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); - - BOOST_CHECK(signalLatch.empty()); - BOOST_CHECK(collectedConnections.empty()); - - cm.restoreAll(); - - BOOST_REQUIRE(signalLatch.waitForN(TEST_DBUS_CONNECTION_ZONES_COUNT, EVENT_TIMEOUT)); - BOOST_CHECK(signalLatch.empty()); - std::unique_lock lock(collectedConnectionsMutex); - BOOST_CHECK(EXPECTED_CONNECTIONS_ALL == collectedConnections); - collectedConnections.clear(); - } -} +const std::set EXPECTED_CONNECTIONS_NONE = { "zone1", "zone2", "zone3" }; +} // namespace BOOST_AUTO_TEST_CASE(GetZoneIds) { -- 2.7.4 From 762ce7ad4b9d8f640d360f1e3502da590166af22 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Mon, 20 Apr 2015 15:21:39 +0200 Subject: [PATCH 14/16] Create libLogger, libSimpleDbus, libConfig packages. [Bug/Feature] Create libLogger, libSimpleDbus, libConfig packages. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests, run server. Change-Id: Iab8c507315f6534ffd11e9f664e017ab45d7e94e Signed-off-by: Dariusz Michaluk --- CMakeLists.txt | 7 ++ client/CMakeLists.txt | 13 +-- libs/config/CMakeLists.txt | 60 ++++++++++++ libs/config/config.hpp | 78 ++++++++++++++++ {common => libs}/config/exception.hpp | 0 {common => libs}/config/fdstore.cpp | 2 +- {common => libs}/config/fdstore.hpp | 0 {common => libs}/config/fields-union.hpp | 0 {common => libs}/config/fields.hpp | 0 {common => libs}/config/from-fdstore-visitor.hpp | 0 {common => libs}/config/from-gvariant-visitor.hpp | 0 {common => libs}/config/from-json-visitor.hpp | 0 {common => libs}/config/from-kvjson-visitor.hpp | 0 {common => libs}/config/from-kvstore-visitor.hpp | 0 {common => libs}/config/fs-utils.cpp | 0 {common => libs}/config/fs-utils.hpp | 0 {common => libs}/config/is-union.hpp | 0 {common => libs}/config/is-visitable.hpp | 0 {common => libs}/config/kvstore.cpp | 2 +- {common => libs}/config/kvstore.hpp | 0 libs/config/libConfig.pc.in | 12 +++ {common => libs}/config/manager.hpp | 0 {common => libs}/config/sqlite3/connection.cpp | 0 {common => libs}/config/sqlite3/connection.hpp | 0 {common => libs}/config/sqlite3/statement.cpp | 0 {common => libs}/config/sqlite3/statement.hpp | 0 {common => libs}/config/to-fdstore-visitor.hpp | 0 {common => libs}/config/to-gvariant-visitor.hpp | 0 {common => libs}/config/to-json-visitor.hpp | 0 {common => libs}/config/to-kvstore-visitor.hpp | 0 libs/dbus/CMakeLists.txt | 68 ++++++++++++++ libs/dbus/config.hpp | 78 ++++++++++++++++ {common => libs}/dbus/connection.cpp | 2 +- {common => libs}/dbus/connection.hpp | 0 {common => libs}/dbus/exception.hpp | 0 libs/dbus/libSimpleDbus.pc.in | 12 +++ libs/logger/CMakeLists.txt | 56 +++++++++++ {common => libs}/logger/backend-journal.cpp | 2 +- {common => libs}/logger/backend-journal.hpp | 0 {common => libs}/logger/backend-null.hpp | 0 {common => libs}/logger/backend-stderr.cpp | 2 +- {common => libs}/logger/backend-stderr.hpp | 0 {common => libs}/logger/backend.hpp | 0 {common => libs}/logger/ccolor.cpp | 2 +- {common => libs}/logger/ccolor.hpp | 0 libs/logger/config.hpp | 78 ++++++++++++++++ {common => libs}/logger/formatter.cpp | 2 +- {common => libs}/logger/formatter.hpp | 0 {common => libs}/logger/level.cpp | 2 +- {common => libs}/logger/level.hpp | 0 libs/logger/libLogger.pc.in | 12 +++ {common => libs}/logger/logger-scope.cpp | 0 {common => libs}/logger/logger-scope.hpp | 0 {common => libs}/logger/logger.cpp | 2 +- {common => libs}/logger/logger.hpp | 0 packaging/vasum.spec | 109 +++++++++++++++++++++- server/CMakeLists.txt | 7 +- tests/unit_tests/CMakeLists.txt | 10 +- zone-daemon/CMakeLists.txt | 8 +- 59 files changed, 595 insertions(+), 31 deletions(-) create mode 100644 libs/config/CMakeLists.txt create mode 100644 libs/config/config.hpp rename {common => libs}/config/exception.hpp (100%) rename {common => libs}/config/fdstore.cpp (99%) rename {common => libs}/config/fdstore.hpp (100%) rename {common => libs}/config/fields-union.hpp (100%) rename {common => libs}/config/fields.hpp (100%) rename {common => libs}/config/from-fdstore-visitor.hpp (100%) rename {common => libs}/config/from-gvariant-visitor.hpp (100%) rename {common => libs}/config/from-json-visitor.hpp (100%) rename {common => libs}/config/from-kvjson-visitor.hpp (100%) rename {common => libs}/config/from-kvstore-visitor.hpp (100%) rename {common => libs}/config/fs-utils.cpp (100%) rename {common => libs}/config/fs-utils.hpp (100%) rename {common => libs}/config/is-union.hpp (100%) rename {common => libs}/config/is-visitable.hpp (100%) rename {common => libs}/config/kvstore.cpp (99%) rename {common => libs}/config/kvstore.hpp (100%) create mode 100644 libs/config/libConfig.pc.in rename {common => libs}/config/manager.hpp (100%) rename {common => libs}/config/sqlite3/connection.cpp (100%) rename {common => libs}/config/sqlite3/connection.hpp (100%) rename {common => libs}/config/sqlite3/statement.cpp (100%) rename {common => libs}/config/sqlite3/statement.hpp (100%) rename {common => libs}/config/to-fdstore-visitor.hpp (100%) rename {common => libs}/config/to-gvariant-visitor.hpp (100%) rename {common => libs}/config/to-json-visitor.hpp (100%) rename {common => libs}/config/to-kvstore-visitor.hpp (100%) create mode 100644 libs/dbus/CMakeLists.txt create mode 100644 libs/dbus/config.hpp rename {common => libs}/dbus/connection.cpp (99%) rename {common => libs}/dbus/connection.hpp (100%) rename {common => libs}/dbus/exception.hpp (100%) create mode 100644 libs/dbus/libSimpleDbus.pc.in create mode 100644 libs/logger/CMakeLists.txt rename {common => libs}/logger/backend-journal.cpp (98%) rename {common => libs}/logger/backend-journal.hpp (100%) rename {common => libs}/logger/backend-null.hpp (100%) rename {common => libs}/logger/backend-stderr.cpp (98%) rename {common => libs}/logger/backend-stderr.hpp (100%) rename {common => libs}/logger/backend.hpp (100%) rename {common => libs}/logger/ccolor.cpp (97%) rename {common => libs}/logger/ccolor.hpp (100%) create mode 100644 libs/logger/config.hpp rename {common => libs}/logger/formatter.cpp (99%) rename {common => libs}/logger/formatter.hpp (100%) rename {common => libs}/logger/level.cpp (98%) rename {common => libs}/logger/level.hpp (100%) create mode 100644 libs/logger/libLogger.pc.in rename {common => libs}/logger/logger-scope.cpp (100%) rename {common => libs}/logger/logger-scope.hpp (100%) rename {common => libs}/logger/logger.cpp (98%) rename {common => libs}/logger/logger.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 308fb45..9b61793 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,6 +133,10 @@ ENDIF(NOT DEFINED PYTHON_SITELIB) ## Subdirectories ############################################################## SET(COMMON_FOLDER ${PROJECT_SOURCE_DIR}/common) +SET(LIBS_FOLDER ${PROJECT_SOURCE_DIR}/libs) +SET(LOGGER_FOLDER ${PROJECT_SOURCE_DIR}/libs/logger) +SET(DBUS_FOLDER ${PROJECT_SOURCE_DIR}/libs/dbus) +SET(CONFIG_FOLDER ${PROJECT_SOURCE_DIR}/libs/config) SET(CLIENT_FOLDER ${PROJECT_SOURCE_DIR}/client) SET(SERVER_FOLDER ${PROJECT_SOURCE_DIR}/server) SET(ZONE_SUPPORT_FOLDER ${PROJECT_SOURCE_DIR}/zone-support) @@ -172,6 +176,9 @@ SET(VSM_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/vasum) SET(VSM_SERVER_IPC_SOCKET_PATH /var/run/vasum-ipc.socket) SET(VSM_UNIT_TESTS_IPC_SOCKET_PATH /var/run/vasum-ipc-unit-tests.socket) +ADD_SUBDIRECTORY(${LOGGER_FOLDER}) +ADD_SUBDIRECTORY(${DBUS_FOLDER}) +ADD_SUBDIRECTORY(${CONFIG_FOLDER}) ADD_SUBDIRECTORY(${CLIENT_FOLDER}) ADD_SUBDIRECTORY(${SERVER_FOLDER}) ADD_SUBDIRECTORY(${ZONE_SUPPORT_FOLDER}) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index afe609f..753b7c4 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -20,13 +20,9 @@ MESSAGE(STATUS "") MESSAGE(STATUS "Generating makefile for the Client...") FILE(GLOB project_SRCS *.cpp *.hpp *.h) -FILE(GLOB common_SRCS ${COMMON_FOLDER}/config/*.hpp ${COMMON_FOLDER}/config/*.cpp - ${COMMON_FOLDER}/config/sqlite3/*.hpp ${COMMON_FOLDER}/config/sqlite3/*.cpp - ${COMMON_FOLDER}/dbus/*.hpp ${COMMON_FOLDER}/dbus/*.cpp - ${COMMON_FOLDER}/epoll/*.hpp ${COMMON_FOLDER}/epoll/*.cpp +FILE(GLOB common_SRCS ${COMMON_FOLDER}/epoll/*.hpp ${COMMON_FOLDER}/epoll/*.cpp ${COMMON_FOLDER}/ipc/*.hpp ${COMMON_FOLDER}/ipc/*.cpp ${COMMON_FOLDER}/ipc/internals/*.hpp ${COMMON_FOLDER}/ipc/internals/*.cpp - ${COMMON_FOLDER}/logger/*.hpp ${COMMON_FOLDER}/logger/*.cpp ${COMMON_FOLDER}/utils/*.hpp ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/*.hpp ${COMMON_FOLDER}/*.cpp) @@ -47,14 +43,15 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${_LIB_VERSION_} COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_SERVER_IPC_SOCKET_PATH}") - ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS system filesystem) -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libsystemd-daemon libsystemd-journal libcap-ng sqlite3) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libsystemd-daemon libcap-ng) INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) INCLUDE_DIRECTORIES(${SERVER_FOLDER}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES} + Config SimpleDbus) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/libs/config/CMakeLists.txt b/libs/config/CMakeLists.txt new file mode 100644 index 0000000..377b734 --- /dev/null +++ b/libs/config/CMakeLists.txt @@ -0,0 +1,60 @@ +# 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 Dariusz Michaluk (d.michaluk@samsung.com) +# + +PROJECT(Config) + +MESSAGE(STATUS "") +MESSAGE(STATUS "Generating makefile for the libConfig...") +FILE(GLOB HEADERS *.hpp) +FILE(GLOB HEADERS_SQLITE3 ${CMAKE_CURRENT_BINARY_DIR}/sqlite3/*.hpp) +FILE(GLOB_RECURSE SRCS *.cpp *.hpp) + +SET(_LIB_VERSION_ "0.0.1") +SET(_LIB_SOVERSION_ "0") +SET(PC_FILE "lib${PROJECT_NAME}.pc") + +## Setup target ################################################################ +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES + SOVERSION ${_LIB_SOVERSION_} + VERSION ${_LIB_VERSION_} +) + +## Link libraries ############################################################## +PKG_CHECK_MODULES(CONFIG_DEPS REQUIRED sqlite3 glib-2.0) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) +INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${CONFIG_DEPS_LIBRARIES}) + +## Generate the pc file ######################################################## +CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY) + +## Install ##################################################################### +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(TARGETS ${PROJECT_NAME} + DESTINATION ${LIB_INSTALL_DIR} + COMPONENT RuntimeLibraries) + +INSTALL(FILES ${HEADERS} + DESTINATION ${INCLUDE_INSTALL_DIR}/vasum-tools/config) + +INSTALL(FILES ${HEADERS_SQLITE3} + DESTINATION ${INCLUDE_INSTALL_DIR}/vasum-tools/config/sqlite3) diff --git a/libs/config/config.hpp b/libs/config/config.hpp new file mode 100644 index 0000000..753430e --- /dev/null +++ b/libs/config/config.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk (l.pawelczyk@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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Configuration file for the code + */ + + +#ifndef COMMON_CONFIG_HPP +#define COMMON_CONFIG_HPP + + +#ifdef __clang__ +#define CLANG_VERSION (__clang__major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif // __clang__ + +#if defined __GNUC__ && !defined __clang__ // clang also defines GCC versions +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + + +#ifdef GCC_VERSION + +#if GCC_VERSION < 40800 +// GCC 4.8 is the first where those defines are not required for +// std::this_thread::sleep_for() and ::yield(). They might exist though +// in previous versions depending on the build configuration of the GCC. +#ifndef _GLIBCXX_USE_NANOSLEEP +#define _GLIBCXX_USE_NANOSLEEP +#endif // _GLIBCXX_USE_NANOSLEEP +#ifndef _GLIBCXX_USE_SCHED_YIELD +#define _GLIBCXX_USE_SCHED_YIELD +#endif // _GLIBCXX_USE_SCHED_YIELD +#endif // GCC_VERSION < 40800 + +#if GCC_VERSION < 40700 +// Those appeared in 4.7 with full c++11 support +#define final +#define override +#define thread_local __thread // use GCC extension instead of C++11 +#define steady_clock monotonic_clock +#endif // GCC_VERSION < 40700 + +#endif // GCC_VERSION + +// Variadic macros support for boost preprocessor should be enabled +// manually for clang since they are marked as untested feature +// (boost trunk if fixed but the latest 1.55 version is not, +// see boost/preprocessor/config/config.hpp) +#ifdef __clang__ +#define BOOST_PP_VARIADICS 1 +#endif + +// This has to be defined always when the boost has not been compiled +// using C++11. Headers detect that you are compiling using C++11 and +// blindly and wrongly assume that boost has been as well. +#ifndef BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_SCOPED_ENUMS 1 +#endif + +#endif // COMMON_CONFIG_HPP diff --git a/common/config/exception.hpp b/libs/config/exception.hpp similarity index 100% rename from common/config/exception.hpp rename to libs/config/exception.hpp diff --git a/common/config/fdstore.cpp b/libs/config/fdstore.cpp similarity index 99% rename from common/config/fdstore.cpp rename to libs/config/fdstore.cpp index c1cedfe..2b761eb 100644 --- a/common/config/fdstore.cpp +++ b/libs/config/fdstore.cpp @@ -22,7 +22,7 @@ * @brief Definition of a class for writing and reading data from a file descriptor */ -#include "config.hpp" +#include "config/config.hpp" #include "config/fdstore.hpp" #include "config/exception.hpp" diff --git a/common/config/fdstore.hpp b/libs/config/fdstore.hpp similarity index 100% rename from common/config/fdstore.hpp rename to libs/config/fdstore.hpp diff --git a/common/config/fields-union.hpp b/libs/config/fields-union.hpp similarity index 100% rename from common/config/fields-union.hpp rename to libs/config/fields-union.hpp diff --git a/common/config/fields.hpp b/libs/config/fields.hpp similarity index 100% rename from common/config/fields.hpp rename to libs/config/fields.hpp diff --git a/common/config/from-fdstore-visitor.hpp b/libs/config/from-fdstore-visitor.hpp similarity index 100% rename from common/config/from-fdstore-visitor.hpp rename to libs/config/from-fdstore-visitor.hpp diff --git a/common/config/from-gvariant-visitor.hpp b/libs/config/from-gvariant-visitor.hpp similarity index 100% rename from common/config/from-gvariant-visitor.hpp rename to libs/config/from-gvariant-visitor.hpp diff --git a/common/config/from-json-visitor.hpp b/libs/config/from-json-visitor.hpp similarity index 100% rename from common/config/from-json-visitor.hpp rename to libs/config/from-json-visitor.hpp diff --git a/common/config/from-kvjson-visitor.hpp b/libs/config/from-kvjson-visitor.hpp similarity index 100% rename from common/config/from-kvjson-visitor.hpp rename to libs/config/from-kvjson-visitor.hpp diff --git a/common/config/from-kvstore-visitor.hpp b/libs/config/from-kvstore-visitor.hpp similarity index 100% rename from common/config/from-kvstore-visitor.hpp rename to libs/config/from-kvstore-visitor.hpp diff --git a/common/config/fs-utils.cpp b/libs/config/fs-utils.cpp similarity index 100% rename from common/config/fs-utils.cpp rename to libs/config/fs-utils.cpp diff --git a/common/config/fs-utils.hpp b/libs/config/fs-utils.hpp similarity index 100% rename from common/config/fs-utils.hpp rename to libs/config/fs-utils.hpp diff --git a/common/config/is-union.hpp b/libs/config/is-union.hpp similarity index 100% rename from common/config/is-union.hpp rename to libs/config/is-union.hpp diff --git a/common/config/is-visitable.hpp b/libs/config/is-visitable.hpp similarity index 100% rename from common/config/is-visitable.hpp rename to libs/config/is-visitable.hpp diff --git a/common/config/kvstore.cpp b/libs/config/kvstore.cpp similarity index 99% rename from common/config/kvstore.cpp rename to libs/config/kvstore.cpp index 49656ae..b6d922e 100644 --- a/common/config/kvstore.cpp +++ b/libs/config/kvstore.cpp @@ -22,7 +22,7 @@ * @brief Definition of a class for key-value storage in a sqlite3 database */ -#include "config.hpp" +#include "config/config.hpp" #include "config/kvstore.hpp" #include "config/exception.hpp" diff --git a/common/config/kvstore.hpp b/libs/config/kvstore.hpp similarity index 100% rename from common/config/kvstore.hpp rename to libs/config/kvstore.hpp diff --git a/libs/config/libConfig.pc.in b/libs/config/libConfig.pc.in new file mode 100644 index 0000000..82f4559 --- /dev/null +++ b/libs/config/libConfig.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: libConfig +Description: Config library +Version: @_LIB_VERSION_@ +Libs: -L${libdir} -lConfig +Cflags: -I${includedir}/vasum-tools diff --git a/common/config/manager.hpp b/libs/config/manager.hpp similarity index 100% rename from common/config/manager.hpp rename to libs/config/manager.hpp diff --git a/common/config/sqlite3/connection.cpp b/libs/config/sqlite3/connection.cpp similarity index 100% rename from common/config/sqlite3/connection.cpp rename to libs/config/sqlite3/connection.cpp diff --git a/common/config/sqlite3/connection.hpp b/libs/config/sqlite3/connection.hpp similarity index 100% rename from common/config/sqlite3/connection.hpp rename to libs/config/sqlite3/connection.hpp diff --git a/common/config/sqlite3/statement.cpp b/libs/config/sqlite3/statement.cpp similarity index 100% rename from common/config/sqlite3/statement.cpp rename to libs/config/sqlite3/statement.cpp diff --git a/common/config/sqlite3/statement.hpp b/libs/config/sqlite3/statement.hpp similarity index 100% rename from common/config/sqlite3/statement.hpp rename to libs/config/sqlite3/statement.hpp diff --git a/common/config/to-fdstore-visitor.hpp b/libs/config/to-fdstore-visitor.hpp similarity index 100% rename from common/config/to-fdstore-visitor.hpp rename to libs/config/to-fdstore-visitor.hpp diff --git a/common/config/to-gvariant-visitor.hpp b/libs/config/to-gvariant-visitor.hpp similarity index 100% rename from common/config/to-gvariant-visitor.hpp rename to libs/config/to-gvariant-visitor.hpp diff --git a/common/config/to-json-visitor.hpp b/libs/config/to-json-visitor.hpp similarity index 100% rename from common/config/to-json-visitor.hpp rename to libs/config/to-json-visitor.hpp diff --git a/common/config/to-kvstore-visitor.hpp b/libs/config/to-kvstore-visitor.hpp similarity index 100% rename from common/config/to-kvstore-visitor.hpp rename to libs/config/to-kvstore-visitor.hpp diff --git a/libs/dbus/CMakeLists.txt b/libs/dbus/CMakeLists.txt new file mode 100644 index 0000000..cd2c06c --- /dev/null +++ b/libs/dbus/CMakeLists.txt @@ -0,0 +1,68 @@ +# 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 Dariusz Michaluk (d.michaluk@samsung.com) +# + +PROJECT(SimpleDbus) + +MESSAGE(STATUS "") +MESSAGE(STATUS "Generating makefile for the libSimpleDbus...") +FILE(GLOB HEADERS *.hpp) +FILE(GLOB HEADERS_UTILS ${COMMON_FOLDER}/utils/callback-guard.hpp + ${COMMON_FOLDER}/utils/scoped-gerror.hpp + ${COMMON_FOLDER}/utils/glib-utils.hpp + ${COMMON_FOLDER}/utils/callback-wrapper.hpp) +FILE(GLOB SRCS_UTILS ${COMMON_FOLDER}/utils/callback-guard.cpp + ${COMMON_FOLDER}/utils/scoped-gerror.cpp + ${COMMON_FOLDER}/utils/glib-utils.cpp + ${COMMON_FOLDER}/utils/callback-wrapper.cpp) +FILE(GLOB SRCS *.cpp *.hpp) + +SET(_LIB_VERSION_ "0.0.1") +SET(_LIB_SOVERSION_ "0") +SET(PC_FILE "lib${PROJECT_NAME}.pc") + +## Setup target ################################################################ +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${SRCS_UTILS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES + SOVERSION ${_LIB_SOVERSION_} + VERSION ${_LIB_VERSION_} +) + +## Link libraries ############################################################## +PKG_CHECK_MODULES(DBUS_DEPS REQUIRED glib-2.0 gio-2.0) +INCLUDE_DIRECTORIES(${COMMON_FOLDER}) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) +INCLUDE_DIRECTORIES(SYSTEM ${DBUS_DEPS_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${DBUS_DEPS_LIBRARIES} Logger) + +## Generate the pc file ######################################################## +CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY) + +## Install ##################################################################### +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(TARGETS ${PROJECT_NAME} + DESTINATION ${LIB_INSTALL_DIR} + COMPONENT RuntimeLibraries) + +INSTALL(FILES ${HEADERS} + DESTINATION ${INCLUDE_INSTALL_DIR}/vasum-tools/dbus) + +INSTALL(FILES ${HEADERS_UTILS} + DESTINATION ${INCLUDE_INSTALL_DIR}/vasum-tools/dbus/utils) diff --git a/libs/dbus/config.hpp b/libs/dbus/config.hpp new file mode 100644 index 0000000..753430e --- /dev/null +++ b/libs/dbus/config.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk (l.pawelczyk@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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Configuration file for the code + */ + + +#ifndef COMMON_CONFIG_HPP +#define COMMON_CONFIG_HPP + + +#ifdef __clang__ +#define CLANG_VERSION (__clang__major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif // __clang__ + +#if defined __GNUC__ && !defined __clang__ // clang also defines GCC versions +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + + +#ifdef GCC_VERSION + +#if GCC_VERSION < 40800 +// GCC 4.8 is the first where those defines are not required for +// std::this_thread::sleep_for() and ::yield(). They might exist though +// in previous versions depending on the build configuration of the GCC. +#ifndef _GLIBCXX_USE_NANOSLEEP +#define _GLIBCXX_USE_NANOSLEEP +#endif // _GLIBCXX_USE_NANOSLEEP +#ifndef _GLIBCXX_USE_SCHED_YIELD +#define _GLIBCXX_USE_SCHED_YIELD +#endif // _GLIBCXX_USE_SCHED_YIELD +#endif // GCC_VERSION < 40800 + +#if GCC_VERSION < 40700 +// Those appeared in 4.7 with full c++11 support +#define final +#define override +#define thread_local __thread // use GCC extension instead of C++11 +#define steady_clock monotonic_clock +#endif // GCC_VERSION < 40700 + +#endif // GCC_VERSION + +// Variadic macros support for boost preprocessor should be enabled +// manually for clang since they are marked as untested feature +// (boost trunk if fixed but the latest 1.55 version is not, +// see boost/preprocessor/config/config.hpp) +#ifdef __clang__ +#define BOOST_PP_VARIADICS 1 +#endif + +// This has to be defined always when the boost has not been compiled +// using C++11. Headers detect that you are compiling using C++11 and +// blindly and wrongly assume that boost has been as well. +#ifndef BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_SCOPED_ENUMS 1 +#endif + +#endif // COMMON_CONFIG_HPP diff --git a/common/dbus/connection.cpp b/libs/dbus/connection.cpp similarity index 99% rename from common/dbus/connection.cpp rename to libs/dbus/connection.cpp index 12544be..441174b 100644 --- a/common/dbus/connection.cpp +++ b/libs/dbus/connection.cpp @@ -22,7 +22,7 @@ * @brief Dbus connection class */ -#include "config.hpp" +#include "dbus/config.hpp" #include "dbus/connection.hpp" #include "dbus/exception.hpp" #include "utils/callback-wrapper.hpp" diff --git a/common/dbus/connection.hpp b/libs/dbus/connection.hpp similarity index 100% rename from common/dbus/connection.hpp rename to libs/dbus/connection.hpp diff --git a/common/dbus/exception.hpp b/libs/dbus/exception.hpp similarity index 100% rename from common/dbus/exception.hpp rename to libs/dbus/exception.hpp diff --git a/libs/dbus/libSimpleDbus.pc.in b/libs/dbus/libSimpleDbus.pc.in new file mode 100644 index 0000000..b3adec3 --- /dev/null +++ b/libs/dbus/libSimpleDbus.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: libSimpleDbus +Description: Simple Dbus library +Version: @_LIB_VERSION_@ +Libs: -L${libdir} -lSimpleDbus +Cflags: -I${includedir}/vasum-tools diff --git a/libs/logger/CMakeLists.txt b/libs/logger/CMakeLists.txt new file mode 100644 index 0000000..786f8bc --- /dev/null +++ b/libs/logger/CMakeLists.txt @@ -0,0 +1,56 @@ +# 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 Dariusz Michaluk (d.michaluk@samsung.com) +# + +PROJECT(Logger) + +MESSAGE(STATUS "") +MESSAGE(STATUS "Generating makefile for the libLogger...") +FILE(GLOB HEADERS *.hpp) +FILE(GLOB SRCS *.cpp *.hpp) + +SET(_LIB_VERSION_ "0.0.1") +SET(_LIB_SOVERSION_ "0") +SET(PC_FILE "lib${PROJECT_NAME}.pc") + +## Setup target ################################################################ +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES + SOVERSION ${_LIB_SOVERSION_} + VERSION ${_LIB_VERSION_} +) + +## Link libraries ############################################################## +PKG_CHECK_MODULES(LOGGER_DEPS REQUIRED libsystemd-journal) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) +INCLUDE_DIRECTORIES(SYSTEM ${LOGGER_DEPS_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${LOGGER_DEPS_LIBRARIES}) + +## Generate the pc file ######################################################## +CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY) + +## Install ##################################################################### +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} + DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +INSTALL(TARGETS ${PROJECT_NAME} + DESTINATION ${LIB_INSTALL_DIR} + COMPONENT RuntimeLibraries) + +INSTALL(FILES ${HEADERS} + DESTINATION ${INCLUDE_INSTALL_DIR}/vasum-tools/logger) diff --git a/common/logger/backend-journal.cpp b/libs/logger/backend-journal.cpp similarity index 98% rename from common/logger/backend-journal.cpp rename to libs/logger/backend-journal.cpp index 12c4eff..74fc581 100644 --- a/common/logger/backend-journal.cpp +++ b/libs/logger/backend-journal.cpp @@ -22,7 +22,7 @@ * @brief Systemd journal backend for logger */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/backend-journal.hpp" #define SD_JOURNAL_SUPPRESS_LOCATION diff --git a/common/logger/backend-journal.hpp b/libs/logger/backend-journal.hpp similarity index 100% rename from common/logger/backend-journal.hpp rename to libs/logger/backend-journal.hpp diff --git a/common/logger/backend-null.hpp b/libs/logger/backend-null.hpp similarity index 100% rename from common/logger/backend-null.hpp rename to libs/logger/backend-null.hpp diff --git a/common/logger/backend-stderr.cpp b/libs/logger/backend-stderr.cpp similarity index 98% rename from common/logger/backend-stderr.cpp rename to libs/logger/backend-stderr.cpp index d4e36b1..c0d3a3c 100644 --- a/common/logger/backend-stderr.cpp +++ b/libs/logger/backend-stderr.cpp @@ -22,7 +22,7 @@ * @brief Stderr backend for logger */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/backend-stderr.hpp" #include "logger/formatter.hpp" diff --git a/common/logger/backend-stderr.hpp b/libs/logger/backend-stderr.hpp similarity index 100% rename from common/logger/backend-stderr.hpp rename to libs/logger/backend-stderr.hpp diff --git a/common/logger/backend.hpp b/libs/logger/backend.hpp similarity index 100% rename from common/logger/backend.hpp rename to libs/logger/backend.hpp diff --git a/common/logger/ccolor.cpp b/libs/logger/ccolor.cpp similarity index 97% rename from common/logger/ccolor.cpp rename to libs/logger/ccolor.cpp index e5e71b0..7424044 100644 --- a/common/logger/ccolor.cpp +++ b/libs/logger/ccolor.cpp @@ -22,7 +22,7 @@ * @brief Console color for StderrBackend logger */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/ccolor.hpp" #include diff --git a/common/logger/ccolor.hpp b/libs/logger/ccolor.hpp similarity index 100% rename from common/logger/ccolor.hpp rename to libs/logger/ccolor.hpp diff --git a/libs/logger/config.hpp b/libs/logger/config.hpp new file mode 100644 index 0000000..753430e --- /dev/null +++ b/libs/logger/config.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Pawelczyk (l.pawelczyk@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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com) + * @brief Configuration file for the code + */ + + +#ifndef COMMON_CONFIG_HPP +#define COMMON_CONFIG_HPP + + +#ifdef __clang__ +#define CLANG_VERSION (__clang__major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif // __clang__ + +#if defined __GNUC__ && !defined __clang__ // clang also defines GCC versions +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + + +#ifdef GCC_VERSION + +#if GCC_VERSION < 40800 +// GCC 4.8 is the first where those defines are not required for +// std::this_thread::sleep_for() and ::yield(). They might exist though +// in previous versions depending on the build configuration of the GCC. +#ifndef _GLIBCXX_USE_NANOSLEEP +#define _GLIBCXX_USE_NANOSLEEP +#endif // _GLIBCXX_USE_NANOSLEEP +#ifndef _GLIBCXX_USE_SCHED_YIELD +#define _GLIBCXX_USE_SCHED_YIELD +#endif // _GLIBCXX_USE_SCHED_YIELD +#endif // GCC_VERSION < 40800 + +#if GCC_VERSION < 40700 +// Those appeared in 4.7 with full c++11 support +#define final +#define override +#define thread_local __thread // use GCC extension instead of C++11 +#define steady_clock monotonic_clock +#endif // GCC_VERSION < 40700 + +#endif // GCC_VERSION + +// Variadic macros support for boost preprocessor should be enabled +// manually for clang since they are marked as untested feature +// (boost trunk if fixed but the latest 1.55 version is not, +// see boost/preprocessor/config/config.hpp) +#ifdef __clang__ +#define BOOST_PP_VARIADICS 1 +#endif + +// This has to be defined always when the boost has not been compiled +// using C++11. Headers detect that you are compiling using C++11 and +// blindly and wrongly assume that boost has been as well. +#ifndef BOOST_NO_CXX11_SCOPED_ENUMS +#define BOOST_NO_CXX11_SCOPED_ENUMS 1 +#endif + +#endif // COMMON_CONFIG_HPP diff --git a/common/logger/formatter.cpp b/libs/logger/formatter.cpp similarity index 99% rename from common/logger/formatter.cpp rename to libs/logger/formatter.cpp index 529cd14..815a111 100644 --- a/common/logger/formatter.cpp +++ b/libs/logger/formatter.cpp @@ -22,7 +22,7 @@ * @brief Helper formatter for logger */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/formatter.hpp" #include "logger/ccolor.hpp" diff --git a/common/logger/formatter.hpp b/libs/logger/formatter.hpp similarity index 100% rename from common/logger/formatter.hpp rename to libs/logger/formatter.hpp diff --git a/common/logger/level.cpp b/libs/logger/level.cpp similarity index 98% rename from common/logger/level.cpp rename to libs/logger/level.cpp index bf46561..3b74205 100644 --- a/common/logger/level.cpp +++ b/libs/logger/level.cpp @@ -22,7 +22,7 @@ * @brief Functions to handle LogLevel */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/level.hpp" #include diff --git a/common/logger/level.hpp b/libs/logger/level.hpp similarity index 100% rename from common/logger/level.hpp rename to libs/logger/level.hpp diff --git a/libs/logger/libLogger.pc.in b/libs/logger/libLogger.pc.in new file mode 100644 index 0000000..f4acc69 --- /dev/null +++ b/libs/logger/libLogger.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: libLogger +Description: Logger library +Version: @_LIB_VERSION_@ +Libs: -L${libdir} -lLogger +Cflags: -I${includedir}/vasum-tools diff --git a/common/logger/logger-scope.cpp b/libs/logger/logger-scope.cpp similarity index 100% rename from common/logger/logger-scope.cpp rename to libs/logger/logger-scope.cpp diff --git a/common/logger/logger-scope.hpp b/libs/logger/logger-scope.hpp similarity index 100% rename from common/logger/logger-scope.hpp rename to libs/logger/logger-scope.hpp diff --git a/common/logger/logger.cpp b/libs/logger/logger.cpp similarity index 98% rename from common/logger/logger.cpp rename to libs/logger/logger.cpp index aa2dccd..ec0855b 100644 --- a/common/logger/logger.cpp +++ b/libs/logger/logger.cpp @@ -22,7 +22,7 @@ * @brief Logger */ -#include "config.hpp" +#include "logger/config.hpp" #include "logger/logger.hpp" #include "logger/formatter.hpp" #include "logger/backend-null.hpp" diff --git a/common/logger/logger.hpp b/libs/logger/logger.hpp similarity index 100% rename from common/logger/logger.hpp rename to libs/logger/logger.hpp diff --git a/packaging/vasum.spec b/packaging/vasum.spec index bd31d68..55567c7 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -147,11 +147,10 @@ Development package including the header files for the client library %defattr(644,root,root,755) %{_libdir}/libvasum.so %{_includedir}/vasum -%{_libdir}/pkgconfig/*.pc +%{_libdir}/pkgconfig/vasum.pc ## Zone Support Package ################################################### -# TODO move to a separate repository %package zone-support Summary: Vasum Support Group: Security/Other @@ -166,7 +165,6 @@ Zones support installed inside every zone. ## Zone Daemon Package #################################################### -# TODO move to a separate repository %package zone-daemon Summary: Vasum Zones Daemon Group: Security/Other @@ -247,3 +245,108 @@ systemctl daemon-reload %config /etc/dbus-1/system.d/org.tizen.vasum.tests.conf %{_unitdir}/vasum-socket-test.socket %{_unitdir}/vasum-socket-test.service + +## libLogger Package ########################################################### +%package -n libLogger +Summary: Logger library +Group: Security/Other +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libLogger +The package provides libLogger library. + +%post -n libLogger -p /sbin/ldconfig + +%postun -n libLogger -p /sbin/ldconfig + +%files -n libLogger +%defattr(644,root,root,755) +%{_libdir}/libLogger.so.0 +%attr(755,root,root) %{_libdir}/libLogger.so.0.0.1 + +%package -n libLogger-devel +Summary: Development logger library +Group: Development/Libraries +Requires: libLogger = %{version}-%{release} + +%description -n libLogger-devel +The package provides libLogger development tools and libs. + +%files -n libLogger-devel +%defattr(644,root,root,755) +%{_libdir}/libLogger.so +%{_includedir}/vasum-tools/logger +%{_libdir}/pkgconfig/libLogger.pc + +## libSimpleDbus Package ####################################################### +%package -n libSimpleDbus +Summary: Simple dbus library +Group: Security/Other +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libSimpleDbus +The package provides libSimpleDbus library. + +%post -n libSimpleDbus -p /sbin/ldconfig + +%postun -n libSimpleDbus -p /sbin/ldconfig + +%files -n libSimpleDbus +%defattr(644,root,root,755) +%{_libdir}/libSimpleDbus.so.0 +%attr(755,root,root) %{_libdir}/libSimpleDbus.so.0.0.1 + +%package -n libSimpleDbus-devel +Summary: Development Simple dbus library +Group: Development/Libraries +Requires: libSimpleDbus = %{version}-%{release} +Requires: pkgconfig(libLogger) + +%description -n libSimpleDbus-devel +The package provides libSimpleDbus development tools and libs. + +%files -n libSimpleDbus-devel +%defattr(644,root,root,755) +%{_libdir}/libSimpleDbus.so +%{_includedir}/vasum-tools/dbus +%{_libdir}/pkgconfig/libSimpleDbus.pc + +## libConfig Package ########################################################## +%package -n libConfig +Summary: Config library +Group: Security/Other +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libConfig +The package provides libConfig library. + +%post -n libConfig -p /sbin/ldconfig + +%postun -n libConfig -p /sbin/ldconfig + +%files -n libConfig +%defattr(644,root,root,755) +%{_libdir}/libConfig.so.0 +%attr(755,root,root) %{_libdir}/libConfig.so.0.0.1 + +%package -n libConfig-devel +Summary: Development Config library +Group: Development/Libraries +Requires: libConfig = %{version}-%{release} +Requires: boost-devel +Requires: pkgconfig(libLogger) +Requires: libjson-devel + +%description -n libConfig-devel +The package provides libConfig development tools and libs. + +%files -n libConfig-devel +%defattr(644,root,root,755) +%{_libdir}/libConfig.so +%{_includedir}/vasum-tools/config +%{_libdir}/pkgconfig/libConfig.pc + + diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 2dbc322..c4e0d8f 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -30,10 +30,10 @@ ADD_EXECUTABLE(${SERVER_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS program_options system filesystem regex) -PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-journal libsystemd-daemon - libcap-ng sqlite3) +PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-journal libsystemd-daemon libcap-ng) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) INCLUDE_DIRECTORIES(${CLIENT_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) @@ -43,7 +43,8 @@ SET_TARGET_PROPERTIES(${SERVER_CODENAME} PROPERTIES LINK_FLAGS "-pthread" ) -TARGET_LINK_LIBRARIES(${SERVER_CODENAME} ${SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(${SERVER_CODENAME} ${SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES} + Logger Config SimpleDbus) ## Subdirectories ############################################################## ADD_SUBDIRECTORY(configs) diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index bed7d37..20ae2f9 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -48,9 +48,9 @@ ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS}) FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc json gio-2.0 libsystemd-daemon - libsystemd-journal libcap-ng sqlite3) + libsystemd-journal libcap-ng) INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER} ${CLIENT_FOLDER} - ${SOCKET_TEST_FOLDER}) + ${LIBS_FOLDER} ${SOCKET_TEST_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) SET_TARGET_PROPERTIES(${UT_SERVER_CODENAME} PROPERTIES @@ -65,8 +65,10 @@ SET_TARGET_PROPERTIES(${SOCKET_TEST_CODENAME} PROPERTIES LINK_FLAGS "-pthread" ) -TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES}) -TARGET_LINK_LIBRARIES(${SOCKET_TEST_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES} + Logger Config SimpleDbus) +TARGET_LINK_LIBRARIES(${SOCKET_TEST_CODENAME} ${UT_SERVER_DEPS_LIBRARIES} ${Boost_LIBRARIES} + Logger Config SimpleDbus) ## Subdirectories ############################################################## SET(VSM_TEST_CONFIG_INSTALL_DIR ${VSM_CONFIG_INSTALL_DIR}/tests) diff --git a/zone-daemon/CMakeLists.txt b/zone-daemon/CMakeLists.txt index 7e7bfba..e721dbf 100644 --- a/zone-daemon/CMakeLists.txt +++ b/zone-daemon/CMakeLists.txt @@ -20,9 +20,7 @@ MESSAGE(STATUS "") MESSAGE(STATUS "Generating makefile for the Zone Daemon...") FILE(GLOB project_SRCS *.cpp *.hpp) -FILE(GLOB common_SRCS ${COMMON_FOLDER}/dbus/*.cpp ${COMMON_FOLDER}/dbus/*.hpp - ${COMMON_FOLDER}/logger/*.cpp ${COMMON_FOLDER}/logger/*.hpp - ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp +FILE(GLOB common_SRCS ${COMMON_FOLDER}/utils/*.cpp ${COMMON_FOLDER}/utils/*.hpp ${COMMON_FOLDER}/*.cpp) ## Setup target ################################################################ @@ -36,6 +34,7 @@ FIND_PACKAGE (Boost COMPONENTS program_options system filesystem) PKG_CHECK_MODULES(ZONE_DAEMON_DEPS REQUIRED gio-2.0 libsystemd-journal libcap-ng) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) +INCLUDE_DIRECTORIES(${LIBS_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${ZONE_DAEMON_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) SET_TARGET_PROPERTIES(${ZONE_DAEMON_CODENAME} PROPERTIES @@ -43,7 +42,8 @@ SET_TARGET_PROPERTIES(${ZONE_DAEMON_CODENAME} PROPERTIES LINK_FLAGS "-pthread" ) -TARGET_LINK_LIBRARIES(${ZONE_DAEMON_CODENAME} ${ZONE_DAEMON_DEPS_LIBRARIES} ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(${ZONE_DAEMON_CODENAME} ${ZONE_DAEMON_DEPS_LIBRARIES} + ${Boost_LIBRARIES} Logger SimpleDbus) ## Install ##################################################################### -- 2.7.4 From aed669399e583ce0f978cfaf542236520d50461d Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 5 May 2015 17:44:08 +0200 Subject: [PATCH 15/16] Listen on dbus and ipc socket at the same time [Feature] Possibility to handle ipc and dbus requests without recompiling the code. To build without dbus add --define 'without_dbus ON' to gbs arguments [Cause] N/A [Solution] N/A [Verification] Build with --define 'without_dbus ON' and without it, run tests for each build, check if server starts Change-Id: Ibd00485c4b3a6451a1cb7046f3488ff77150b3ea --- CMakeLists.txt | 4 +- client/host-ipc-connection.cpp | 62 ++--- common/api/dbus-method-result-builder.hpp | 6 +- packaging/vasum.spec | 3 +- server/host-dbus-connection.cpp | 78 +++--- server/host-dbus-definitions.hpp | 2 + server/host-ipc-connection.cpp | 58 ++-- server/host-ipc-definitions.hpp | 2 + server/zones-manager.cpp | 161 +++++------ server/zones-manager.hpp | 25 +- tests/unit_tests/client/ut-client.cpp | 11 +- tests/unit_tests/server/configs/CMakeLists.txt | 4 - .../templates/console-dbus.conf.in | 18 -- .../ut-zones-manager/templates/console-ipc.conf.in | 18 -- tests/unit_tests/server/ut-zones-manager.cpp | 294 ++++++++++----------- 15 files changed, 356 insertions(+), 390 deletions(-) delete mode 100644 tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in delete mode 100644 tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b61793..2e960c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,9 @@ ADD_DEFINITIONS(-DVASUM_USER="${VASUM_USER}") ADD_DEFINITIONS(-DINPUT_EVENT_GROUP="${INPUT_EVENT_GROUP}") ADD_DEFINITIONS(-DDISK_GROUP="${DISK_GROUP}") ADD_DEFINITIONS(-DTTY_GROUP="${TTY_GROUP}") -#ADD_DEFINITIONS(-DDBUS_CONNECTION) +IF(NOT WITHOUT_DBUS) + ADD_DEFINITIONS(-DDBUS_CONNECTION) +ENDIF(NOT WITHOUT_DBUS) ## Python packages directory ################################################### IF(NOT DEFINED PYTHON_SITELIB) diff --git a/client/host-ipc-connection.cpp b/client/host-ipc-connection.cpp index 121f7ad..6541881 100644 --- a/client/host-ipc-connection.cpp +++ b/client/host-ipc-connection.cpp @@ -46,183 +46,183 @@ void HostIPCConnection::create(const std::string& address) void HostIPCConnection::callGetZoneIds(api::ZoneIds& argOut) { api::Void argVoid; - call(api::METHOD_GET_ZONE_ID_LIST, argVoid, argOut); + call(api::ipc::METHOD_GET_ZONE_ID_LIST, argVoid, argOut); } void HostIPCConnection::callGetActiveZoneId(api::ZoneId& argOut) { api::Void argVoid; - call(api::METHOD_GET_ACTIVE_ZONE_ID, argVoid, argOut); + call(api::ipc::METHOD_GET_ACTIVE_ZONE_ID, argVoid, argOut); } void HostIPCConnection::callSetActiveZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_SET_ACTIVE_ZONE, + api::ipc::METHOD_SET_ACTIVE_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callGetZoneInfo(const api::ZoneId& argIn, api::ZoneInfoOut& argOut) { argOut = *mClient->callSync( - api::METHOD_GET_ZONE_INFO, + api::ipc::METHOD_GET_ZONE_INFO, std::make_shared(argIn)); } void HostIPCConnection::callSetNetdevAttrs(const api::SetNetDevAttrsIn& argIn) { mClient->callSync( - api::METHOD_SET_NETDEV_ATTRS, + api::ipc::METHOD_SET_NETDEV_ATTRS, std::make_shared(argIn)); api::Void argVoid; - call(api::METHOD_SET_NETDEV_ATTRS, argIn, argVoid); + call(api::ipc::METHOD_SET_NETDEV_ATTRS, argIn, argVoid); } void HostIPCConnection::callGetNetdevAttrs(const api::GetNetDevAttrsIn& argIn, api::GetNetDevAttrs& argOut) { argOut = *mClient->callSync( - api::METHOD_GET_NETDEV_ATTRS, + api::ipc::METHOD_GET_NETDEV_ATTRS, std::make_shared(argIn)); } void HostIPCConnection::callGetNetdevList(const api::ZoneId& argIn, api::NetDevList& argOut) { argOut = *mClient->callSync( - api::METHOD_GET_NETDEV_LIST, + api::ipc::METHOD_GET_NETDEV_LIST, std::make_shared(argIn)); } void HostIPCConnection::callCreateNetdevVeth(const api::CreateNetDevVethIn& argIn) { mClient->callSync( - api::METHOD_CREATE_NETDEV_VETH, + api::ipc::METHOD_CREATE_NETDEV_VETH, std::make_shared(argIn)); } void HostIPCConnection::callCreateNetdevMacvlan(const api::CreateNetDevMacvlanIn& argIn) { mClient->callSync( - api::METHOD_CREATE_NETDEV_MACVLAN, + api::ipc::METHOD_CREATE_NETDEV_MACVLAN, std::make_shared(argIn)); } void HostIPCConnection::callCreateNetdevPhys(const api::CreateNetDevPhysIn& argIn) { mClient->callSync( - api::METHOD_CREATE_NETDEV_PHYS, + api::ipc::METHOD_CREATE_NETDEV_PHYS, std::make_shared(argIn)); } void HostIPCConnection::callDestroyNetdev(const api::DestroyNetDevIn& argIn) { mClient->callSync( - api::METHOD_DESTROY_NETDEV, + api::ipc::METHOD_DESTROY_NETDEV, std::make_shared(argIn)); } void HostIPCConnection::callDeleteNetdevIpAddress(const api::DeleteNetdevIpAddressIn& argIn) { mClient->callSync( - api::METHOD_DELETE_NETDEV_IP_ADDRESS, + api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS, std::make_shared(argIn)); } void HostIPCConnection::callDeclareFile(const api::DeclareFileIn& argIn, api::Declaration& argOut) { argOut = *mClient->callSync( - api::METHOD_DECLARE_FILE, + api::ipc::METHOD_DECLARE_FILE, std::make_shared(argIn)); } void HostIPCConnection::callDeclareMount(const api::DeclareMountIn& argIn, api::Declaration& argOut) { argOut = *mClient->callSync( - api::METHOD_DECLARE_MOUNT, + api::ipc::METHOD_DECLARE_MOUNT, std::make_shared(argIn)); } void HostIPCConnection::callDeclareLink(const api::DeclareLinkIn& argIn, api::Declaration& argOut) { argOut = *mClient->callSync( - api::METHOD_DECLARE_LINK, + api::ipc::METHOD_DECLARE_LINK, std::make_shared(argIn)); } void HostIPCConnection::callGetDeclarations(const api::ZoneId& argIn, api::Declarations& argOut) { argOut = *mClient->callSync( - api::METHOD_GET_DECLARATIONS, + api::ipc::METHOD_GET_DECLARATIONS, std::make_shared(argIn)); } void HostIPCConnection::callRemoveDeclaration(const api::RemoveDeclarationIn& argIn) { mClient->callSync( - api::METHOD_REMOVE_DECLARATION, + api::ipc::METHOD_REMOVE_DECLARATION, std::make_shared(argIn)); } void HostIPCConnection::callCreateZone(const api::CreateZoneIn& argIn) { mClient->callSync( - api::METHOD_CREATE_ZONE, + api::ipc::METHOD_CREATE_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callDestroyZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_DESTROY_ZONE, + api::ipc::METHOD_DESTROY_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callShutdownZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_SHUTDOWN_ZONE, + api::ipc::METHOD_SHUTDOWN_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callStartZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_START_ZONE, + api::ipc::METHOD_START_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callLockZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_LOCK_ZONE, + api::ipc::METHOD_LOCK_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callUnlockZone(const api::ZoneId& argIn) { mClient->callSync( - api::METHOD_UNLOCK_ZONE, + api::ipc::METHOD_UNLOCK_ZONE, std::make_shared(argIn)); } void HostIPCConnection::callGrantDevice(const api::GrantDeviceIn& argIn) { mClient->callSync( - api::METHOD_GRANT_DEVICE, + api::ipc::METHOD_GRANT_DEVICE, std::make_shared(argIn)); } void HostIPCConnection::callRevokeDevice(const api::RevokeDeviceIn& argIn) { mClient->callSync( - api::METHOD_REVOKE_DEVICE, + api::ipc::METHOD_REVOKE_DEVICE, std::make_shared(argIn)); } void HostIPCConnection::callNotifyActiveZone(const api::NotifActiveZoneIn& argIn) { mClient->callSync( - api::METHOD_NOTIFY_ACTIVE_ZONE, + api::ipc::METHOD_NOTIFY_ACTIVE_ZONE, std::make_shared(argIn)); } @@ -230,14 +230,14 @@ void HostIPCConnection::callFileMoveRequest(const api::FileMoveRequestIn& argIn, api::FileMoveRequestStatus& argOut) { argOut = *mClient->callSync( - api::METHOD_FILE_MOVE_REQUEST, + api::ipc::METHOD_FILE_MOVE_REQUEST, std::make_shared(argIn)); } void HostIPCConnection::signalSwitchToDefault() { - mClient->signal(api::SIGNAL_SWITCH_TO_DEFAULT, + mClient->signal(api::ipc::SIGNAL_SWITCH_TO_DEFAULT, std::make_shared()); } @@ -248,8 +248,8 @@ HostIPCConnection::subscribeNotification(const NotificationCallback& callback) std::shared_ptr& data) { callback(*data); }; - mClient->setSignalHandler(api::SIGNAL_NOTIFICATION, callbackWrapper); - return api::SIGNAL_NOTIFICATION; + mClient->setSignalHandler(api::ipc::SIGNAL_NOTIFICATION, callbackWrapper); + return api::ipc::SIGNAL_NOTIFICATION; } void HostIPCConnection::unsubscribe(const SubscriptionId& id) diff --git a/common/api/dbus-method-result-builder.hpp b/common/api/dbus-method-result-builder.hpp index 99f3bc0..c6422dc 100644 --- a/common/api/dbus-method-result-builder.hpp +++ b/common/api/dbus-method-result-builder.hpp @@ -42,7 +42,7 @@ namespace api { template class DbusMethodResultBuilder: public MethodResultBuilder { public: - DbusMethodResultBuilder(const dbus::MethodResultBuilder::Pointer& methodResultBuilderPtr); + DbusMethodResultBuilder(const ::dbus::MethodResultBuilder::Pointer& methodResultBuilderPtr); ~DbusMethodResultBuilder() {} private: @@ -50,12 +50,12 @@ private: void setVoid() override; void setError(const std::string& name, const std::string& message) override; - dbus::MethodResultBuilder::Pointer mMethodResultBuilderPtr; + ::dbus::MethodResultBuilder::Pointer mMethodResultBuilderPtr; std::function)> mSerialize; }; template -DbusMethodResultBuilder::DbusMethodResultBuilder(const dbus::MethodResultBuilder::Pointer& methodResultBuilderPtr) +DbusMethodResultBuilder::DbusMethodResultBuilder(const ::dbus::MethodResultBuilder::Pointer& methodResultBuilderPtr) : mMethodResultBuilderPtr(methodResultBuilderPtr) { mSerialize = [](const std::shared_ptr data)->GVariant* { diff --git a/packaging/vasum.spec b/packaging/vasum.spec index 55567c7..64c3662 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -70,7 +70,8 @@ between them. A process from inside a zone can request a switch of context -DVASUM_USER=%{vsm_user} \ -DINPUT_EVENT_GROUP=%{input_event_group} \ -DDISK_GROUP=%{disk_group} \ - -DTTY_GROUP=%{tty_group} + -DTTY_GROUP=%{tty_group} \ + -DWITHOUT_DBUS=%{?without_dbus} make -k %{?jobs:-j%jobs} %install diff --git a/server/host-dbus-connection.cpp b/server/host-dbus-connection.cpp index b93ad21..98325ac 100644 --- a/server/host-dbus-connection.cpp +++ b/server/host-dbus-connection.cpp @@ -53,19 +53,19 @@ HostDbusConnection::HostDbusConnection() mDbusConnection = dbus::DbusConnection::createSystem(); LOGT("Setting DBUS name"); - mDbusConnection->setName(api::BUS_NAME, + mDbusConnection->setName(api::dbus::BUS_NAME, std::bind(&HostDbusConnection::onNameAcquired, this), std::bind(&HostDbusConnection::onNameLost, this)); if (!waitForName(NAME_ACQUIRED_TIMEOUT)) { - LOGE("Could not acquire dbus name: " << api::BUS_NAME); - throw HostConnectionException("Could not acquire dbus name: " + api::BUS_NAME); + LOGE("Could not acquire dbus name: " << api::dbus::BUS_NAME); + throw HostConnectionException("Could not acquire dbus name: " + api::dbus::BUS_NAME); } LOGT("Registering DBUS interface"); using namespace std::placeholders; - mDbusConnection->registerObject(api::OBJECT_PATH, - api::DEFINITION, + mDbusConnection->registerObject(api::dbus::OBJECT_PATH, + api::dbus::DEFINITION, std::bind(&HostDbusConnection::onMessageCall, this, _1, _2, _3, _4, _5)); @@ -267,11 +267,11 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, GVariant* parameters, dbus::MethodResultBuilder::Pointer result) { - if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) { + if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) { return; } - if (methodName == api::METHOD_SET_ACTIVE_ZONE) { + if (methodName == api::dbus::METHOD_SET_ACTIVE_ZONE) { api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); @@ -282,7 +282,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_PROXY_CALL) { + if (methodName == api::dbus::METHOD_PROXY_CALL) { const gchar* target = NULL; const gchar* targetBusName = NULL; const gchar* targetObjectPath = NULL; @@ -311,7 +311,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_ZONE_ID_LIST) { + if (methodName == api::dbus::METHOD_GET_ZONE_ID_LIST) { if (mGetZoneIdsCallback) { auto rb = std::make_shared>(result); mGetZoneIdsCallback(rb); @@ -319,7 +319,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_ACTIVE_ZONE_ID) { + if (methodName == api::dbus::METHOD_GET_ACTIVE_ZONE_ID) { if (mGetActiveZoneIdCallback) { auto rb = std::make_shared>(result); mGetActiveZoneIdCallback(rb); @@ -327,7 +327,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_ZONE_INFO) { + if (methodName == api::dbus::METHOD_GET_ZONE_INFO) { api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); @@ -338,7 +338,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_SET_NETDEV_ATTRS) { + if (methodName == api::dbus::METHOD_SET_NETDEV_ATTRS) { api::SetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); @@ -349,7 +349,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_NETDEV_ATTRS) { + if (methodName == api::dbus::METHOD_GET_NETDEV_ATTRS) { api::GetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); @@ -360,7 +360,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_NETDEV_LIST) { + if (methodName == api::dbus::METHOD_GET_NETDEV_LIST) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -371,7 +371,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_CREATE_NETDEV_VETH) { + if (methodName == api::dbus::METHOD_CREATE_NETDEV_VETH) { api::CreateNetDevVethIn data; config::loadFromGVariant(parameters, data); @@ -382,7 +382,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_CREATE_NETDEV_MACVLAN) { + if (methodName == api::dbus::METHOD_CREATE_NETDEV_MACVLAN) { api::CreateNetDevMacvlanIn data; config::loadFromGVariant(parameters, data); @@ -392,7 +392,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_CREATE_NETDEV_PHYS) { + if (methodName == api::dbus::METHOD_CREATE_NETDEV_PHYS) { api::CreateNetDevPhysIn data; config::loadFromGVariant(parameters, data); @@ -402,7 +402,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_DESTROY_NETDEV) { + if (methodName == api::dbus::METHOD_DESTROY_NETDEV) { api::DestroyNetDevIn data; config::loadFromGVariant(parameters, data); @@ -412,7 +412,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_DELETE_NETDEV_IP_ADDRESS) { + if (methodName == api::dbus::METHOD_DELETE_NETDEV_IP_ADDRESS) { api::DeleteNetdevIpAddressIn data; config::loadFromGVariant(parameters, data); if (mDeleteNetdevIpAddressCallback) { @@ -421,7 +421,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_DECLARE_FILE) { + if (methodName == api::dbus::METHOD_DECLARE_FILE) { api::DeclareFileIn data; config::loadFromGVariant(parameters, data); @@ -432,7 +432,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_DECLARE_MOUNT) { + if (methodName == api::dbus::METHOD_DECLARE_MOUNT) { api::DeclareMountIn data; config::loadFromGVariant(parameters, data); @@ -443,7 +443,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_DECLARE_LINK) { + if (methodName == api::dbus::METHOD_DECLARE_LINK) { api::DeclareLinkIn data; config::loadFromGVariant(parameters, data); @@ -454,7 +454,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GET_DECLARATIONS) { + if (methodName == api::dbus::METHOD_GET_DECLARATIONS) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -465,7 +465,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_REMOVE_DECLARATION) { + if (methodName == api::dbus::METHOD_REMOVE_DECLARATION) { api::RemoveDeclarationIn data; config::loadFromGVariant(parameters, data); @@ -476,7 +476,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_CREATE_ZONE) { + if (methodName == api::dbus::METHOD_CREATE_ZONE) { api::CreateZoneIn data; config::loadFromGVariant(parameters, data); @@ -487,7 +487,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_DESTROY_ZONE) { + if (methodName == api::dbus::METHOD_DESTROY_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -498,7 +498,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_SHUTDOWN_ZONE) { + if (methodName == api::dbus::METHOD_SHUTDOWN_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -508,7 +508,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_START_ZONE) { + if (methodName == api::dbus::METHOD_START_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -518,7 +518,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_LOCK_ZONE) { + if (methodName == api::dbus::METHOD_LOCK_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -529,7 +529,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_UNLOCK_ZONE) { + if (methodName == api::dbus::METHOD_UNLOCK_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); @@ -540,7 +540,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_GRANT_DEVICE) { + if (methodName == api::dbus::METHOD_GRANT_DEVICE) { api::GrantDeviceIn data; config::loadFromGVariant(parameters, data); @@ -551,7 +551,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_REVOKE_DEVICE) { + if (methodName == api::dbus::METHOD_REVOKE_DEVICE) { api::RevokeDeviceIn data; config::loadFromGVariant(parameters, data); @@ -562,7 +562,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, return; } - if (methodName == api::METHOD_NOTIFY_ACTIVE_ZONE) { + if (methodName == api::dbus::METHOD_NOTIFY_ACTIVE_ZONE) { api::NotifActiveZoneIn data; config::loadFromGVariant(parameters, data); @@ -572,7 +572,7 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } } - if (methodName == api::METHOD_FILE_MOVE_REQUEST) { + if (methodName == api::dbus::METHOD_FILE_MOVE_REQUEST) { api::FileMoveRequestIn data; config::loadFromGVariant(parameters, data); @@ -589,11 +589,11 @@ void HostDbusConnection::onSignalCall(const std::string& /* senderBusName */, const std::string& signalName, GVariant* /* parameters */) { - if (objectPath != api::OBJECT_PATH || interface != api::INTERFACE) { + if (objectPath != api::dbus::OBJECT_PATH || interface != api::dbus::INTERFACE) { return; } - if (signalName == api::SIGNAL_SWITCH_TO_DEFAULT) { + if (signalName == api::dbus::SIGNAL_SWITCH_TO_DEFAULT) { if (mSwitchToDefaultCallback) { mSwitchToDefaultCallback(); } @@ -622,9 +622,9 @@ void HostDbusConnection::sendNotification(const api::Notification& notify) notify.zone.c_str(), notify.application.c_str(), notify.message.c_str()); - mDbusConnection->emitSignal(api::OBJECT_PATH, - api::INTERFACE, - api::SIGNAL_NOTIFICATION, + mDbusConnection->emitSignal(api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::SIGNAL_NOTIFICATION, parameters); } diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index 208276e..2d013c9 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -29,6 +29,7 @@ namespace vasum { namespace api { +namespace dbus { const std::string BUS_NAME = "org.tizen.vasum.host"; const std::string OBJECT_PATH = "/org/tizen/vasum/host"; @@ -228,6 +229,7 @@ const std::string DEFINITION = " " ""; +} // namespace dbus } // namespace api } // namespace vasum diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp index 1bf2e78c..d6519e9 100644 --- a/server/host-ipc-connection.cpp +++ b/server/host-ipc-connection.cpp @@ -49,7 +49,7 @@ void HostIPCConnection::setGetZoneIdsCallback(const Method::type& { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_GET_ZONE_ID_LIST, + api::ipc::METHOD_GET_ZONE_ID_LIST, Callback::getWrapper(callback)); } @@ -58,7 +58,7 @@ void HostIPCConnection::setGetActiveZoneIdCallback(const Method::ty { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_GET_ACTIVE_ZONE_ID, + api::ipc::METHOD_GET_ACTIVE_ZONE_ID, Callback::getWrapper(callback)); } @@ -67,7 +67,7 @@ void HostIPCConnection::setGetZoneInfoCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_GET_ZONE_INFO, + api::ipc::METHOD_GET_ZONE_INFO, Callback::getWrapper(callback)); } @@ -75,7 +75,7 @@ void HostIPCConnection::setSetNetdevAttrsCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_SET_NETDEV_ATTRS, + api::ipc::METHOD_SET_NETDEV_ATTRS, Callback::getWrapper(callback)); } @@ -83,7 +83,7 @@ void HostIPCConnection::setGetNetdevAttrsCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_GET_NETDEV_ATTRS, + api::ipc::METHOD_GET_NETDEV_ATTRS, Callback::getWrapper(callback)); } @@ -91,7 +91,7 @@ void HostIPCConnection::setGetNetdevListCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_GET_NETDEV_LIST, + api::ipc::METHOD_GET_NETDEV_LIST, Callback::getWrapper(callback)); } @@ -99,7 +99,7 @@ void HostIPCConnection::setCreateNetdevVethCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_CREATE_NETDEV_VETH, + api::ipc::METHOD_CREATE_NETDEV_VETH, Callback::getWrapper(callback)); } @@ -107,7 +107,7 @@ void HostIPCConnection::setCreateNetdevMacvlanCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_CREATE_NETDEV_MACVLAN, + api::ipc::METHOD_CREATE_NETDEV_MACVLAN, Callback::getWrapper(callback)); } @@ -115,7 +115,7 @@ void HostIPCConnection::setCreateNetdevPhysCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_CREATE_NETDEV_PHYS, + api::ipc::METHOD_CREATE_NETDEV_PHYS, Callback::getWrapper(callback)); } @@ -123,7 +123,7 @@ void HostIPCConnection::setDestroyNetdevCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_DESTROY_NETDEV, + api::ipc::METHOD_DESTROY_NETDEV, Callback::getWrapper(callback)); } @@ -131,7 +131,7 @@ void HostIPCConnection::setDeleteNetdevIpAddressCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_DELETE_NETDEV_IP_ADDRESS, + api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS, Callback::getWrapper(callback)); } @@ -139,7 +139,7 @@ void HostIPCConnection::setDeclareFileCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_DECLARE_FILE, + api::ipc::METHOD_DECLARE_FILE, Callback::getWrapper(callback)); } @@ -147,7 +147,7 @@ void HostIPCConnection::setDeclareMountCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_DECLARE_MOUNT, + api::ipc::METHOD_DECLARE_MOUNT, Callback::getWrapper(callback)); } @@ -155,7 +155,7 @@ void HostIPCConnection::setDeclareLinkCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_DECLARE_LINK, + api::ipc::METHOD_DECLARE_LINK, Callback::getWrapper(callback)); } @@ -163,7 +163,7 @@ void HostIPCConnection::setGetDeclarationsCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_GET_DECLARATIONS, + api::ipc::METHOD_GET_DECLARATIONS, Callback::getWrapper(callback)); } @@ -171,7 +171,7 @@ void HostIPCConnection::setRemoveDeclarationCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_REMOVE_DECLARATION, + api::ipc::METHOD_REMOVE_DECLARATION, Callback::getWrapper(callback)); } @@ -179,7 +179,7 @@ void HostIPCConnection::setSetActiveZoneCallback(const Method { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_SET_ACTIVE_ZONE, + api::ipc::METHOD_SET_ACTIVE_ZONE, Callback::getWrapper(callback)); } @@ -187,7 +187,7 @@ void HostIPCConnection::setCreateZoneCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_CREATE_ZONE, + api::ipc::METHOD_CREATE_ZONE, Callback::getWrapper(callback)); } @@ -195,7 +195,7 @@ void HostIPCConnection::setDestroyZoneCallback(const Method:: { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_DESTROY_ZONE, + api::ipc::METHOD_DESTROY_ZONE, Callback::getWrapper(callback)); } @@ -203,7 +203,7 @@ void HostIPCConnection::setShutdownZoneCallback(const Method: { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_SHUTDOWN_ZONE, + api::ipc::METHOD_SHUTDOWN_ZONE, Callback::getWrapper(callback)); } @@ -211,7 +211,7 @@ void HostIPCConnection::setStartZoneCallback(const Method::ty { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_START_ZONE, + api::ipc::METHOD_START_ZONE, Callback::getWrapper(callback)); } @@ -219,7 +219,7 @@ void HostIPCConnection::setLockZoneCallback(const Method::typ { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_LOCK_ZONE, + api::ipc::METHOD_LOCK_ZONE, Callback::getWrapper(callback)); } @@ -227,7 +227,7 @@ void HostIPCConnection::setUnlockZoneCallback(const Method::t { typedef IPCMethodWrapper Callback; mService->setMethodHandler( - api::METHOD_UNLOCK_ZONE, + api::ipc::METHOD_UNLOCK_ZONE, Callback::getWrapper(callback)); } @@ -235,7 +235,7 @@ void HostIPCConnection::setGrantDeviceCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_GRANT_DEVICE, + api::ipc::METHOD_GRANT_DEVICE, Callback::getWrapper(callback)); } @@ -243,7 +243,7 @@ void HostIPCConnection::setRevokeDeviceCallback(const Method Callback; mService->setMethodHandler( - api::METHOD_REVOKE_DEVICE, + api::ipc::METHOD_REVOKE_DEVICE, Callback::getWrapper(callback)); } @@ -252,7 +252,7 @@ void HostIPCConnection::setNotifyActiveZoneCallback( { typedef IPCMethodWrapper Method; mService->setMethodHandler( - api::METHOD_NOTIFY_ACTIVE_ZONE, + api::ipc::METHOD_NOTIFY_ACTIVE_ZONE, Method::getWrapper(callback)); } @@ -260,7 +260,7 @@ void HostIPCConnection::setSwitchToDefaultCallback(const Signal { typedef IPCSignalWrapper Signal; mService->setSignalHandler( - api::SIGNAL_SWITCH_TO_DEFAULT, + api::ipc::SIGNAL_SWITCH_TO_DEFAULT, Signal::getWrapper(callback)); } @@ -269,13 +269,13 @@ void HostIPCConnection::setFileMoveCallback(const Method Method; mService->setMethodHandler( - api::METHOD_FILE_MOVE_REQUEST, + api::ipc::METHOD_FILE_MOVE_REQUEST, Method::getWrapper(callback)); } void HostIPCConnection::sendNotification(const api::Notification& notification) { - mService->signal(api::SIGNAL_NOTIFICATION, + mService->signal(api::ipc::SIGNAL_NOTIFICATION, std::make_shared(notification)); } diff --git a/server/host-ipc-definitions.hpp b/server/host-ipc-definitions.hpp index 8c31339..a54b679 100644 --- a/server/host-ipc-definitions.hpp +++ b/server/host-ipc-definitions.hpp @@ -29,6 +29,7 @@ namespace vasum { namespace api { +namespace ipc { const vasum::ipc::MethodID METHOD_GET_ZONE_ID_LIST = 2; const vasum::ipc::MethodID METHOD_GET_ACTIVE_ZONE_ID = 3; @@ -68,6 +69,7 @@ const std::string FILE_MOVE_NO_PERMISSIONS_RECEIVE = "FILE_MOVE_NO_PERMISSIONS_ const std::string FILE_MOVE_FAILED = "FILE_MOVE_FAILED"; const std::string FILE_MOVE_SUCCEEDED = "FILE_MOVE_SUCCEEDED"; +} // namespace ipc } // namespace api } // namespace vasum diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index e6621d8..953fad0 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -24,11 +24,6 @@ #include "config.hpp" -#ifdef DBUS_CONNECTION -#include "host-dbus-definitions.hpp" -#else -#include "host-ipc-definitions.hpp" -#endif #include "common-definitions.hpp" #include "dynamic-config-scheme.hpp" #include "zones-manager.hpp" @@ -117,109 +112,115 @@ bool zoneIsRunning(const std::unique_ptr& zone) { } // namespace -ZonesManager::ZonesManager(const std::string& configPath) - : mWorker(utils::Worker::create()) - , mDetachOnExit(false) +template +void ZonesManager::setHandlers(Connection& connection) { - LOGD("Instantiating ZonesManager object..."); + using namespace std::placeholders; + connection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall, + this, _1)); - config::loadFromJsonFile(configPath, mConfig); - config::loadFromKVStoreWithJsonFile(mConfig.dbPath, - configPath, - mDynamicConfig, - getVasumDbPrefix()); + connection.setGetActiveZoneIdCallback(bind(&ZonesManager::handleGetActiveZoneIdCall, + this, _1)); + connection.setGetZoneInfoCallback(bind(&ZonesManager::handleGetZoneInfoCall, + this, _1, _2)); - using namespace std::placeholders; -#ifdef DBUS_CONNECTION - mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); - mHostConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall, - this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); -#endif + connection.setSetNetdevAttrsCallback(bind(&ZonesManager::handleSetNetdevAttrsCall, + this, _1, _2)); - mHostConnection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall, - this, _1)); + connection.setGetNetdevAttrsCallback(bind(&ZonesManager::handleGetNetdevAttrsCall, + this, _1, _2)); - mHostConnection.setGetActiveZoneIdCallback(bind(&ZonesManager::handleGetActiveZoneIdCall, - this, _1)); + connection.setGetNetdevListCallback(bind(&ZonesManager::handleGetNetdevListCall, + this, _1, _2)); - mHostConnection.setGetZoneInfoCallback(bind(&ZonesManager::handleGetZoneInfoCall, + connection.setCreateNetdevVethCallback(bind(&ZonesManager::handleCreateNetdevVethCall, this, _1, _2)); - mHostConnection.setSetNetdevAttrsCallback(bind(&ZonesManager::handleSetNetdevAttrsCall, + connection.setCreateNetdevMacvlanCallback(bind(&ZonesManager::handleCreateNetdevMacvlanCall, this, _1, _2)); - mHostConnection.setGetNetdevAttrsCallback(bind(&ZonesManager::handleGetNetdevAttrsCall, - this, _1, _2)); + connection.setCreateNetdevPhysCallback(bind(&ZonesManager::handleCreateNetdevPhysCall, + this, _1, _2)); - mHostConnection.setGetNetdevListCallback(bind(&ZonesManager::handleGetNetdevListCall, - this, _1, _2)); + connection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, + this, _1, _2)); - mHostConnection.setCreateNetdevVethCallback(bind(&ZonesManager::handleCreateNetdevVethCall, + connection.setDeleteNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, this, _1, _2)); - mHostConnection.setCreateNetdevMacvlanCallback(bind(&ZonesManager::handleCreateNetdevMacvlanCall, - this, _1, _2)); + connection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, + this, _1, _2)); - mHostConnection.setCreateNetdevPhysCallback(bind(&ZonesManager::handleCreateNetdevPhysCall, - this, _1, _2)); - - mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, - this, _1, _2)); + connection.setDeclareMountCallback(bind(&ZonesManager::handleDeclareMountCall, + this, _1, _2)); - mHostConnection.setDeleteNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, - this, _1, _2)); + connection.setDeclareLinkCallback(bind(&ZonesManager::handleDeclareLinkCall, + this, _1, _2)); - mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, - this, _1, _2)); + connection.setGetDeclarationsCallback(bind(&ZonesManager::handleGetDeclarationsCall, + this, _1, _2)); - mHostConnection.setDeclareMountCallback(bind(&ZonesManager::handleDeclareMountCall, + connection.setRemoveDeclarationCallback(bind(&ZonesManager::handleRemoveDeclarationCall, this, _1, _2)); - mHostConnection.setDeclareLinkCallback(bind(&ZonesManager::handleDeclareLinkCall, - this, _1, _2)); + connection.setSetActiveZoneCallback(bind(&ZonesManager::handleSetActiveZoneCall, + this, _1, _2)); - mHostConnection.setGetDeclarationsCallback(bind(&ZonesManager::handleGetDeclarationsCall, - this, _1, _2)); + connection.setCreateZoneCallback(bind(&ZonesManager::handleCreateZoneCall, + this, _1, _2)); - mHostConnection.setRemoveDeclarationCallback(bind(&ZonesManager::handleRemoveDeclarationCall, - this, _1, _2)); + connection.setDestroyZoneCallback(bind(&ZonesManager::handleDestroyZoneCall, + this, _1, _2)); - mHostConnection.setSetActiveZoneCallback(bind(&ZonesManager::handleSetActiveZoneCall, - this, _1, _2)); + connection.setShutdownZoneCallback(bind(&ZonesManager::handleShutdownZoneCall, + this, _1, _2)); - mHostConnection.setCreateZoneCallback(bind(&ZonesManager::handleCreateZoneCall, - this, _1, _2)); + connection.setStartZoneCallback(bind(&ZonesManager::handleStartZoneCall, + this, _1, _2)); - mHostConnection.setDestroyZoneCallback(bind(&ZonesManager::handleDestroyZoneCall, - this, _1, _2)); + connection.setLockZoneCallback(bind(&ZonesManager::handleLockZoneCall, + this, _1, _2)); - mHostConnection.setShutdownZoneCallback(bind(&ZonesManager::handleShutdownZoneCall, - this, _1, _2)); + connection.setUnlockZoneCallback(bind(&ZonesManager::handleUnlockZoneCall, + this, _1, _2)); - mHostConnection.setStartZoneCallback(bind(&ZonesManager::handleStartZoneCall, - this, _1, _2)); + connection.setGrantDeviceCallback(bind(&ZonesManager::handleGrantDeviceCall, + this, _1, _2)); - mHostConnection.setLockZoneCallback(bind(&ZonesManager::handleLockZoneCall, - this, _1, _2)); + connection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall, + this, _1, _2)); - mHostConnection.setUnlockZoneCallback(bind(&ZonesManager::handleUnlockZoneCall, - this, _1, _2)); + connection.setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, + this, "", _1, _2)); - mHostConnection.setGrantDeviceCallback(bind(&ZonesManager::handleGrantDeviceCall, - this, _1, _2)); + connection.setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, + this, "")); - mHostConnection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall, - this, _1, _2)); + connection.setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, + this, "", _1, _2)); +} - mHostConnection.setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, - this, "", _1, _2)); +ZonesManager::ZonesManager(const std::string& configPath) + : mWorker(utils::Worker::create()) + , mDetachOnExit(false) +{ + LOGD("Instantiating ZonesManager object..."); - mHostConnection.setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, - this, "")); + config::loadFromJsonFile(configPath, mConfig); + config::loadFromKVStoreWithJsonFile(mConfig.dbPath, + configPath, + mDynamicConfig, + getVasumDbPrefix()); - mHostConnection.setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, - this, "", _1, _2)); + setHandlers(mHostIPCConnection); +#ifdef DBUS_CONNECTION + using namespace std::placeholders; + mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); + mHostDbusConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall, + this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); + setHandlers(mHostDbusConnection); +#endif //DBUS_CONNECTION for (const auto& zoneId : mDynamicConfig.zoneIds) { insertZone(zoneId, getTemplatePathForExistingZone(zoneId)); @@ -737,14 +738,14 @@ void ZonesManager::handleProxyCall(const std::string& caller, return; } - mHostConnection.proxyCallAsync(targetBusName, - targetObjectPath, - targetInterface, - targetMethod, - parameters, - asyncResultCallback); + mHostDbusConnection.proxyCallAsync(targetBusName, + targetObjectPath, + targetInterface, + targetMethod, + parameters, + asyncResultCallback); } -#endif +#endif //DBUS_CONNECTION void ZonesManager::handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result) { diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 42477ae..2a2f6d7 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -28,16 +28,16 @@ #include "zone.hpp" #include "zones-manager-config.hpp" -#ifdef DBUS_CONNECTION -#include "host-dbus-connection.hpp" -#include "proxy-call-policy.hpp" -#else #include "host-ipc-connection.hpp" -#endif #include "input-monitor.hpp" #include "utils/worker.hpp" #include "api/method-result-builder.hpp" +#ifdef DBUS_CONNECTION +#include "host-dbus-connection.hpp" +#include "proxy-call-policy.hpp" +#endif //DBUS_CONNECTION + #include #include @@ -118,17 +118,15 @@ public: private: typedef std::recursive_mutex Mutex; typedef std::unique_lock Lock; -#ifdef DBUS_CONNECTION - typedef HostDbusConnection HostConnection; -#else - typedef HostIPCConnection HostConnection; -#endif utils::Worker::Pointer mWorker; Mutex mMutex; // used to protect mZones ZonesManagerConfig mConfig; //TODO make it const ZonesManagerDynamicConfig mDynamicConfig; - HostConnection mHostConnection; +#ifdef DBUS_CONNECTION + HostDbusConnection mHostDbusConnection; +#endif //DBUS_CONNECTION + HostIPCConnection mHostIPCConnection; // to hold InputMonitor pointer to monitor if zone switching sequence is recognized std::unique_ptr mSwitchingSequenceMonitor; // like set but keep insertion order @@ -172,7 +170,7 @@ private: const std::string& targetMethod, GVariant* parameters, dbus::MethodResultBuilder::Pointer result); -#endif +#endif //DBUS_CONNECTION // Handlers -------------------------------------------------------- void handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result); void handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer result); @@ -222,6 +220,9 @@ private: api::MethodResultBuilder::Pointer result); void handleRevokeDeviceCall(const api::RevokeDeviceIn& data, api::MethodResultBuilder::Pointer result); + + template + void setHandlers(Connection& connnection); }; diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index f0e6b2e..adc325e 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -23,8 +23,6 @@ * @brief Unit tests of the client C API */ -#ifndef DBUS_CONNECTION - #include #include "ut.hpp" #include @@ -35,6 +33,10 @@ #include "host-ipc-definitions.hpp" #include "logger/logger.hpp" +#ifdef DBUS_CONNECTION +#include "utils/glib-loop.hpp" +#endif //DBUS_CONNECTION + #include #include #include @@ -56,6 +58,9 @@ const std::string TEMPLATE_NAME = "console-ipc"; struct Fixture { utils::ScopedDir mZonesPathGuard; utils::ScopedDir mRunGuard; +#ifdef DBUS_CONNECTION + utils::ScopedGlibLoop mLoop; +#endif //DBUS_CONNECTION std::unique_ptr cm; @@ -412,5 +417,3 @@ BOOST_AUTO_TEST_CASE(ZoneGetNetdevs) BOOST_AUTO_TEST_SUITE_END() - -#endif /* !DBUS_CONNECTION */ diff --git a/tests/unit_tests/server/configs/CMakeLists.txt b/tests/unit_tests/server/configs/CMakeLists.txt index c5880b1..a91d5d8 100644 --- a/tests/unit_tests/server/configs/CMakeLists.txt +++ b/tests/unit_tests/server/configs/CMakeLists.txt @@ -46,10 +46,6 @@ CONFIGURE_FILE(ut-zones-manager/test-daemon.conf.in ${CMAKE_BINARY_DIR}/ut-zones-manager/test-daemon.conf @ONLY) FILE(GLOB manager_manager_CONF_GEN ${CMAKE_BINARY_DIR}/ut-zones-manager/*.conf) -CONFIGURE_FILE(ut-zones-manager/templates/console-dbus.conf.in - ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/console-dbus.conf @ONLY) -CONFIGURE_FILE(ut-zones-manager/templates/console-ipc.conf.in - ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/console-ipc.conf @ONLY) FILE(GLOB manager_templates_CONF_GEN ${CMAKE_BINARY_DIR}/ut-zones-manager/templates/*.conf) diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in deleted file mode 100644 index 2ff5998..0000000 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-dbus.conf.in +++ /dev/null @@ -1,18 +0,0 @@ -{ - "lxcTemplate" : "minimal-dbus.sh", - "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; /usr/bin/dbus-daemon --config-file=@VSM_TEST_CONFIG_INSTALL_DIR@/server/ut-zones-manager/ut-dbus.conf --fork; read"], - "requestedState" : "running", - "ipv4Gateway" : "", - "ipv4" : "", - "privilege" : 20, - "vt" : -1, - "switchToDefaultAfterTimeout" : true, - "cpuQuotaForeground" : -1, - "cpuQuotaBackground" : 1000, - "shutdownTimeout" : 10, - "runMountPoint" : "/tmp/ut-run/~NAME~", - "provisions" : [], - "permittedToSend" : [ "/tmp/.*" ], - "permittedToRecv" : [ "/tmp/.*" ], - "validLinkPrefixes" : [] -} diff --git a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in b/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in deleted file mode 100644 index fab7e58..0000000 --- a/tests/unit_tests/server/configs/ut-zones-manager/templates/console-ipc.conf.in +++ /dev/null @@ -1,18 +0,0 @@ -{ - "lxcTemplate" : "minimal.sh", - "initWithArgs" : ["/bin/sh", "-c", "trap exit SIGTERM; read"], - "requestedState" : "running", - "ipv4Gateway" : "", - "ipv4" : "", - "privilege" : 20, - "vt" : -1, - "switchToDefaultAfterTimeout" : true, - "cpuQuotaForeground" : -1, - "cpuQuotaBackground" : 1000, - "shutdownTimeout" : 10, - "runMountPoint" : "/tmp/ut-run/~NAME~", - "provisions" : [], - "permittedToSend" : [ "/tmp/.*" ], - "permittedToRecv" : [ "/tmp/.*" ], - "validLinkPrefixes" : [] -} diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp index a2811a9..e052117 100644 --- a/tests/unit_tests/server/ut-zones-manager.cpp +++ b/tests/unit_tests/server/ut-zones-manager.cpp @@ -34,12 +34,11 @@ #include "test-dbus-definitions.hpp" #include "dbus/connection.hpp" #include "dbus/exception.hpp" -#else +#endif //DBUS_CONNECTION #include "host-ipc-definitions.hpp" #include #include #include -#endif #include "exception.hpp" #include "utils/glib-loop.hpp" @@ -65,7 +64,8 @@ using namespace config; using namespace vasum::utils; #ifdef DBUS_CONNECTION using namespace dbus; -#endif +#endif //DBUS_CONNECTION + namespace { @@ -82,11 +82,6 @@ const std::string FILE_CONTENT = "File content\n" const std::string NON_EXISTANT_ZONE_ID = "NON_EXISTANT_ZONE_ID"; const std::string ZONES_PATH = "/tmp/ut-zones"; // the same as in daemon.conf const std::string SIMPLE_TEMPLATE = "console"; -#ifdef DBUS_CONNECTION -const std::string ZONE_ACCESS_TEMPLATE = "console-dbus"; -#else -const std::string ZONE_ACCESS_TEMPLATE = "console-ipc"; -#endif #ifdef DBUS_CONNECTION /** @@ -105,7 +100,7 @@ dropException(const DbusConnection::AsyncMethodCallCallback& fun) }; } -class DbusAccessory { +class HostDbusAccessory { public: static const int HOST_ID = 0; @@ -114,10 +109,9 @@ public: )> TestApiMethodCallback; typedef std::function VoidResultCallback; typedef std::function NotificationCallback; - typedef std::map Connections; - DbusAccessory() + HostDbusAccessory() : mId(0), mClient(DbusConnection::create(acquireAddress())), mNameAcquired(false), @@ -125,7 +119,7 @@ public: { } - DbusAccessory(int id) + HostDbusAccessory(int id) : mId(id), mClient(DbusConnection::create(acquireAddress())), mNameAcquired(false), @@ -136,8 +130,8 @@ public: void setName(const std::string& name) { mClient->setName(name, - std::bind(&DbusAccessory::onNameAcquired, this), - std::bind(&DbusAccessory::onDisconnect, this)); + std::bind(&HostDbusAccessory::onNameAcquired, this), + std::bind(&HostDbusAccessory::onDisconnect, this)); if(!waitForName()) { mClient.reset(); @@ -168,7 +162,7 @@ public: void signalSubscribe(const DbusConnection::SignalCallback& callback) { - mClient->signalSubscribe(callback, isHost() ? api::BUS_NAME : api::BUS_NAME); + mClient->signalSubscribe(callback, isHost() ? api::dbus::BUS_NAME : api::dbus::BUS_NAME); } void subscribeNotification(const NotificationCallback& callback) @@ -179,9 +173,9 @@ public: const std::string& signalName, GVariant* parameters) { - if (objectPath == api::OBJECT_PATH && - interface == api::INTERFACE && - signalName == api::SIGNAL_NOTIFICATION && + if (objectPath == api::dbus::OBJECT_PATH && + interface == api::dbus::INTERFACE && + signalName == api::dbus::SIGNAL_NOTIFICATION && g_variant_is_of_type(parameters, G_VARIANT_TYPE("(sss)"))) { const gchar* zone = NULL; @@ -191,25 +185,25 @@ public: callback({zone, application, message}); } }; - mClient->signalSubscribe(handler, api::BUS_NAME); + mClient->signalSubscribe(handler, api::dbus::BUS_NAME); } void signalSwitchToDefault() { // emit signal from dbus connection - mClient->emitSignal(api::OBJECT_PATH, - api::INTERFACE, - api::SIGNAL_SWITCH_TO_DEFAULT, + mClient->emitSignal(api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::SIGNAL_SWITCH_TO_DEFAULT, nullptr); } void callMethodNotify() { GVariant* parameters = g_variant_new("(ss)", TEST_APP_NAME.c_str(), TEST_MESSAGE.c_str()); - mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_NOTIFY_ACTIVE_ZONE, + mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_NOTIFY_ACTIVE_ZONE, parameters, "()"); } @@ -217,10 +211,10 @@ public: std::string callMethodMove(const std::string& dest, const std::string& path) { GVariant* parameters = g_variant_new("(ss)", dest.c_str(), path.c_str()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_FILE_MOVE_REQUEST, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_FILE_MOVE_REQUEST, parameters, "(s)"); @@ -278,13 +272,13 @@ public: interface.c_str(), method.c_str(), parameters); - GVariantPtr result = mClient->callMethod(isHost() ? api::BUS_NAME : - api::BUS_NAME, - isHost() ? api::OBJECT_PATH : - api::OBJECT_PATH, - isHost() ? api::INTERFACE : - api::INTERFACE, - api::METHOD_PROXY_CALL, + GVariantPtr result = mClient->callMethod(isHost() ? api::dbus::BUS_NAME : + api::dbus::BUS_NAME, + isHost() ? api::dbus::OBJECT_PATH : + api::dbus::OBJECT_PATH, + isHost() ? api::dbus::INTERFACE : + api::dbus::INTERFACE, + api::dbus::METHOD_PROXY_CALL, packedParameters, "(v)"); GVariant* unpackedResult = NULL; @@ -295,10 +289,10 @@ public: std::vector callMethodGetZoneIds() { assert(isHost()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_GET_ZONE_ID_LIST, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_GET_ZONE_ID_LIST, NULL, "(as)"); @@ -320,10 +314,10 @@ public: std::string callMethodGetActiveZoneId() { assert(isHost()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_GET_ACTIVE_ZONE_ID, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_GET_ACTIVE_ZONE_ID, NULL, "(s)"); @@ -336,10 +330,10 @@ public: { assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_SET_ACTIVE_ZONE, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_SET_ACTIVE_ZONE, parameters, "()"); @@ -357,10 +351,10 @@ public: assert(isHost()); GVariant* parameters = g_variant_new("(ss)", id.c_str(), templateName.c_str()); - mClient->callMethodAsync(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_CREATE_ZONE, + mClient->callMethodAsync(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_CREATE_ZONE, parameters, "()", dropException(asyncResult)); @@ -377,10 +371,10 @@ public: assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - mClient->callMethodAsync(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_DESTROY_ZONE, + mClient->callMethodAsync(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_DESTROY_ZONE, parameters, "()", dropException(asyncResult)); @@ -397,10 +391,10 @@ public: assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - mClient->callMethodAsync(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_SHUTDOWN_ZONE, + mClient->callMethodAsync(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_SHUTDOWN_ZONE, parameters, "()", dropException(asyncResult)); @@ -417,10 +411,10 @@ public: assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - mClient->callMethodAsync(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_START_ZONE, + mClient->callMethodAsync(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_START_ZONE, parameters, "()", dropException(asyncResult)); @@ -430,10 +424,10 @@ public: { assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_LOCK_ZONE, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_LOCK_ZONE, parameters, "()"); } @@ -442,10 +436,10 @@ public: { assert(isHost()); GVariant* parameters = g_variant_new("(s)", id.c_str()); - GVariantPtr result = mClient->callMethod(api::BUS_NAME, - api::OBJECT_PATH, - api::INTERFACE, - api::METHOD_UNLOCK_ZONE, + GVariantPtr result = mClient->callMethod(api::dbus::BUS_NAME, + api::dbus::OBJECT_PATH, + api::dbus::INTERFACE, + api::dbus::METHOD_UNLOCK_ZONE, parameters, "()"); } @@ -473,10 +467,7 @@ private: } }; -typedef DbusAccessory HostAccessory; - -#else -//#ifdef DBUS_CONNECTION +#endif //DBUS_CONNECTION class HostIPCAccessory { public: @@ -491,21 +482,21 @@ public: std::vector callMethodGetZoneIds() { - const auto out = mClient.callSync(api::METHOD_GET_ZONE_ID_LIST, + const auto out = mClient.callSync(api::ipc::METHOD_GET_ZONE_ID_LIST, std::make_shared()); return out->values; } std::string callMethodGetActiveZoneId() { - const auto out = mClient.callSync(api::METHOD_GET_ACTIVE_ZONE_ID, + const auto out = mClient.callSync(api::ipc::METHOD_GET_ACTIVE_ZONE_ID, std::make_shared()); return out->value; } void callMethodSetActiveZone(const std::string& id) { - mClient.callSync(api::METHOD_SET_ACTIVE_ZONE, + mClient.callSync(api::ipc::METHOD_SET_ACTIVE_ZONE, std::make_shared(api::ZoneId{id})); } @@ -518,7 +509,7 @@ public: result(); } }; - mClient.callAsync(api::METHOD_CREATE_ZONE, + mClient.callAsync(api::ipc::METHOD_CREATE_ZONE, std::make_shared(api::CreateZoneIn{id, templateName}), asyncResult); } @@ -531,7 +522,7 @@ public: result(); } }; - mClient.callAsync(api::METHOD_DESTROY_ZONE, + mClient.callAsync(api::ipc::METHOD_DESTROY_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } @@ -544,7 +535,7 @@ public: result(); } }; - mClient.callAsync(api::METHOD_SHUTDOWN_ZONE, + mClient.callAsync(api::ipc::METHOD_SHUTDOWN_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } @@ -557,21 +548,21 @@ public: result(); } }; - mClient.callAsync(api::METHOD_START_ZONE, + mClient.callAsync(api::ipc::METHOD_START_ZONE, std::make_shared(api::ZoneId{id}), asyncResult); } void callMethodLockZone(const std::string& id) { - mClient.callSync(api::METHOD_LOCK_ZONE, + mClient.callSync(api::ipc::METHOD_LOCK_ZONE, std::make_shared(api::ZoneId{id}), EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } void callMethodUnlockZone(const std::string& id) { - mClient.callSync(api::METHOD_UNLOCK_ZONE, + mClient.callSync(api::ipc::METHOD_UNLOCK_ZONE, std::make_shared(api::ZoneId{id}), EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } @@ -581,19 +572,19 @@ public: auto callbackWrapper = [callback] (const ipc::PeerID, std::shared_ptr& data) { callback(*data); }; - mClient.setSignalHandler(api::SIGNAL_NOTIFICATION, + mClient.setSignalHandler(api::ipc::SIGNAL_NOTIFICATION, callbackWrapper); } void signalSwitchToDefault() { - mClient.signal(api::SIGNAL_SWITCH_TO_DEFAULT, std::make_shared()); + mClient.signal(api::ipc::SIGNAL_SWITCH_TO_DEFAULT, std::make_shared()); } void callMethodNotify() { mClient.callSync( - api::METHOD_NOTIFY_ACTIVE_ZONE, + api::ipc::METHOD_NOTIFY_ACTIVE_ZONE, std::make_shared(api::NotifActiveZoneIn{TEST_APP_NAME, TEST_MESSAGE}), EVENT_TIMEOUT*10); //Prevent from IPCTimeoutException see LockUnlockZone } @@ -601,7 +592,7 @@ public: std::string callMethodMove(const std::string& dest, const std::string& path) { auto result = mClient.callSync( - api::METHOD_FILE_MOVE_REQUEST, + api::ipc::METHOD_FILE_MOVE_REQUEST, std::make_shared(api::FileMoveRequestIn{dest, path}), EVENT_TIMEOUT*10); return result->value; @@ -612,10 +603,6 @@ private: ipc::Client mClient; }; -typedef HostIPCAccessory HostAccessory; - -#endif //DBUS_CONNECTION - template bool spinWaitFor(int timeoutMs, Predicate pred) { @@ -629,6 +616,8 @@ bool spinWaitFor(int timeoutMs, Predicate pred) return true; } +} // namespace + struct Fixture { vasum::utils::ScopedGlibLoop mLoop; @@ -641,7 +630,21 @@ struct Fixture { {} }; -} // namespace +struct IPCFixture : Fixture { + typedef HostIPCAccessory HostAccessory; +}; + +#ifdef DBUS_CONNECTION +struct DbusFixture : Fixture { + typedef HostDbusAccessory HostAccessory; +}; +#endif //DBUS_CONNECTION + +#ifdef DBUS_CONNECTION +#define ACCESSORS IPCFixture, DbusFixture +#else //DBUS_CONNECTION +#define ACCESSORS IPCFixture +#endif //DBUS_CONNECTION BOOST_FIXTURE_TEST_SUITE(ZonesManagerSuite, Fixture) @@ -713,22 +716,13 @@ BOOST_AUTO_TEST_CASE(Focus) BOOST_CHECK(cm.getRunningForegroundZoneId() == "zone3"); } -BOOST_AUTO_TEST_CASE(StartStopWithZoneAccess) -{ - ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); - cm.restoreAll(); -} - #ifdef ZONE_CONNECTION BOOST_AUTO_TEST_CASE(NotifyActiveZone) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); Latch signalReceivedLatch; @@ -782,9 +776,9 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZone) BOOST_AUTO_TEST_CASE(MoveFile) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); Latch notificationLatch; @@ -867,15 +861,15 @@ BOOST_AUTO_TEST_CASE(MoveFile) } #endif -BOOST_AUTO_TEST_CASE(SwitchToDefault) +MULTI_FIXTURE_TEST_CASE(SwitchToDefault, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; auto isDefaultFocused = [&cm]() -> bool { return cm.getRunningForegroundZoneId() == "zone1"; @@ -889,15 +883,15 @@ BOOST_AUTO_TEST_CASE(SwitchToDefault) BOOST_CHECK(spinWaitFor(EVENT_TIMEOUT, isDefaultFocused)); } -BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) +MULTI_FIXTURE_TEST_CASE(AllowSwitchToDefault, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; auto isDefaultFocused = [&cm]() -> bool { return cm.getRunningForegroundZoneId() == "zone1"; @@ -922,15 +916,15 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) } #ifdef DBUS_CONNECTION -BOOST_AUTO_TEST_CASE(ProxyCall) +MULTI_FIXTURE_TEST_CASE(ProxyCall, F, DbusFixture) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; host.setName(testapi::BUS_NAME); auto handler = [](const std::string& argument, MethodResultBuilder::Pointer result) { @@ -967,7 +961,7 @@ BOOST_AUTO_TEST_CASE(ProxyCall) DbusCustomException, WhatEquals("Proxy call forbidden")); } -#endif // DBUS_CONNECTION +#endif //DBUS_CONNECTION namespace { @@ -975,14 +969,14 @@ const std::set EXPECTED_CONNECTIONS_NONE = { "zone1", "zone2", "zon } // namespace -BOOST_AUTO_TEST_CASE(GetZoneIds) +MULTI_FIXTURE_TEST_CASE(GetZoneIds, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); cm.createZone("zone2", SIMPLE_TEMPLATE); cm.createZone("zone3", SIMPLE_TEMPLATE); - HostAccessory host; + typename F::HostAccessory host; std::vector zoneIds = {"zone1", "zone2", @@ -992,7 +986,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIds) BOOST_CHECK(returnedIds == zoneIds);// order should be preserved } -BOOST_AUTO_TEST_CASE(GetActiveZoneId) +MULTI_FIXTURE_TEST_CASE(GetActiveZoneId, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -1000,7 +994,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; std::vector zoneIds = {"zone1", "zone2", @@ -1015,7 +1009,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) BOOST_CHECK(host.callMethodGetActiveZoneId() == ""); } -BOOST_AUTO_TEST_CASE(SetActiveZone) +MULTI_FIXTURE_TEST_CASE(SetActiveZone, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -1023,7 +1017,7 @@ BOOST_AUTO_TEST_CASE(SetActiveZone) cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; std::vector zoneIds = {"zone1", "zone2", @@ -1044,7 +1038,7 @@ BOOST_AUTO_TEST_CASE(SetActiveZone) WhatEquals("Could not activate stopped or paused zone")); } -BOOST_AUTO_TEST_CASE(CreateDestroyZone) +MULTI_FIXTURE_TEST_CASE(CreateDestroyZone, F, ACCESSORS) { const std::string zone1 = "test1"; const std::string zone2 = "test2"; @@ -1060,7 +1054,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZone) callDone.set(); }; - HostAccessory host; + typename F::HostAccessory host; // create zone1 host.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); @@ -1096,7 +1090,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZone) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } -BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) +MULTI_FIXTURE_TEST_CASE(CreateDestroyZonePersistence, F, ACCESSORS) { const std::string zone = "test1"; @@ -1109,7 +1103,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) ZonesManager cm(TEST_CONFIG_PATH); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; return host.callMethodGetZoneIds(); }; @@ -1118,7 +1112,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) // create zone { ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; + typename F::HostAccessory host; host.callAsyncMethodCreateZone(zone, SIMPLE_TEMPLATE, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } @@ -1132,7 +1126,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) // destroy zone { ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; + typename F::HostAccessory host; host.callAsyncMethodDestroyZone(zone, resultCallback); BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } @@ -1140,7 +1134,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) BOOST_CHECK(getZoneIds().empty()); } -BOOST_AUTO_TEST_CASE(ZoneStatePersistence) +MULTI_FIXTURE_TEST_CASE(ZoneStatePersistence, F, ACCESSORS) { const std::string zone1 = "zone1"; const std::string zone2 = "zone2"; @@ -1156,7 +1150,7 @@ BOOST_AUTO_TEST_CASE(ZoneStatePersistence) // firts run { ZonesManager cm(TEST_CONFIG_PATH); - HostAccessory host; + typename F::HostAccessory host; // zone1 - created host.callAsyncMethodCreateZone(zone1, SIMPLE_TEMPLATE, resultCallback); @@ -1211,21 +1205,21 @@ BOOST_AUTO_TEST_CASE(ZoneStatePersistence) } } -BOOST_AUTO_TEST_CASE(StartShutdownZone) +MULTI_FIXTURE_TEST_CASE(StartShutdownZone, F, ACCESSORS) { const std::string zone1 = "zone1"; const std::string zone2 = "zone2"; ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone(zone1, ZONE_ACCESS_TEMPLATE); - cm.createZone(zone2, ZONE_ACCESS_TEMPLATE); + cm.createZone(zone1, SIMPLE_TEMPLATE); + cm.createZone(zone2, SIMPLE_TEMPLATE); Latch callDone; auto resultCallback = [&]() { callDone.set(); }; - HostAccessory host; + typename F::HostAccessory host; // start zone1 host.callAsyncMethodStartZone(zone1, resultCallback); @@ -1251,15 +1245,15 @@ BOOST_AUTO_TEST_CASE(StartShutdownZone) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } -BOOST_AUTO_TEST_CASE(LockUnlockZone) +MULTI_FIXTURE_TEST_CASE(LockUnlockZone, F, ACCESSORS) { ZonesManager cm(TEST_CONFIG_PATH); - cm.createZone("zone1", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone2", ZONE_ACCESS_TEMPLATE); - cm.createZone("zone3", ZONE_ACCESS_TEMPLATE); + cm.createZone("zone1", SIMPLE_TEMPLATE); + cm.createZone("zone2", SIMPLE_TEMPLATE); + cm.createZone("zone3", SIMPLE_TEMPLATE); cm.restoreAll(); - HostAccessory host; + typename F::HostAccessory host; std::vector zoneIds = {"zone1", "zone2", @@ -1272,7 +1266,7 @@ BOOST_AUTO_TEST_CASE(LockUnlockZone) //This try catch clause is for prevent from test crashing //and should be removed after resolve following errors //TODO: Abort when zone is locked on destroying ZonesManager - HostAccessory host2; //TODO: After IPCTimeoutException host is useless -- fix it + typename F::HostAccessory host2; //TODO: After IPCTimeoutException host is useless -- fix it try { host2.callMethodUnlockZone(zoneId); } catch (...) {}; throw; } -- 2.7.4 From 49bcbe69cf98fcad1abe8416cd41698478d583ae Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 29 Apr 2015 12:49:46 +0200 Subject: [PATCH 16/16] Remove strerror usage [Bug] strerror isn't thread-safe [Cause] Thread usage [Solution] Replaces all strerror with strerror_r [Verification] Build, run test Change-Id: I9fc5e84da011d80af7fb7a7877fe868e8e300ea9 --- common/ipc/internals/socket.cpp | 34 ++++++++++++++++++++-------------- common/utils/environment.cpp | 2 +- common/utils/eventfd.cpp | 5 +++-- common/utils/fd-utils.cpp | 25 +++++++++++++++---------- common/utils/fs.cpp | 17 +++++++++-------- common/utils/img.cpp | 13 +++++++------ common/utils/signal.cpp | 10 ++++++---- common/utils/vt.cpp | 9 +++++---- libs/config/fdstore.cpp | 15 ++++++++++++--- server/server.cpp | 3 +-- 10 files changed, 79 insertions(+), 54 deletions(-) diff --git a/common/ipc/internals/socket.cpp b/common/ipc/internals/socket.cpp index 3cdbf7c..26e1c27 100644 --- a/common/ipc/internals/socket.cpp +++ b/common/ipc/internals/socket.cpp @@ -49,8 +49,9 @@ void setFdOptions(int fd) { // Prevent from inheriting fd by zones if (-1 == ::fcntl(fd, F_SETFD, FD_CLOEXEC)) { - LOGE("Error in fcntl: " + std::string(strerror(errno))); - throw IPCException("Error in fcntl: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in fcntl: " + msg); + throw IPCException("Error in fcntl: " + msg); } } @@ -90,8 +91,9 @@ std::shared_ptr Socket::accept() { int sockfd = ::accept(mFD, nullptr, nullptr); if (sockfd == -1) { - LOGE("Error in accept: " << std::string(strerror(errno))); - throw IPCException("Error in accept: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in accept: " << msg); + throw IPCException("Error in accept: " + msg); } setFdOptions(sockfd); return std::make_shared(sockfd); @@ -139,8 +141,9 @@ int Socket::createZoneSocket(const std::string& path) int sockfd = ::socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == -1) { - LOGE("Error in socket: " + std::string(strerror(errno))); - throw IPCException("Error in socket: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in socket: " + msg); + throw IPCException("Error in socket: " + msg); } setFdOptions(sockfd); @@ -154,7 +157,7 @@ int Socket::createZoneSocket(const std::string& path) if (-1 == ::bind(sockfd, reinterpret_cast(&serverAddress), sizeof(struct sockaddr_un))) { - std::string message = strerror(errno); + std::string message = getSystemErrorMessage(); utils::close(sockfd); LOGE("Error in bind: " << message); throw IPCException("Error in bind: " + message); @@ -162,7 +165,7 @@ int Socket::createZoneSocket(const std::string& path) if (-1 == ::listen(sockfd, MAX_QUEUE_LENGTH)) { - std::string message = strerror(errno); + std::string message = getSystemErrorMessage(); utils::close(sockfd); LOGE("Error in listen: " << message); throw IPCException("Error in listen: " + message); @@ -190,8 +193,9 @@ Socket Socket::connectSocket(const std::string& path) int fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { - LOGE("Error in socket: " + std::string(strerror(errno))); - throw IPCException("Error in socket: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in socket: " + msg); + throw IPCException("Error in socket: " + msg); } setFdOptions(fd); @@ -202,17 +206,19 @@ Socket Socket::connectSocket(const std::string& path) if (-1 == connect(fd, reinterpret_cast(&serverAddress), sizeof(struct sockaddr_un))) { + const std::string msg = getSystemErrorMessage(); utils::close(fd); - LOGE("Error in connect: " + std::string(strerror(errno))); - throw IPCException("Error in connect: " + std::string(strerror(errno))); + LOGE("Error in connect: " + msg); + throw IPCException("Error in connect: " + msg); } // Nonblock socket int flags = fcntl(fd, F_GETFL, 0); if (-1 == fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { + const std::string msg = getSystemErrorMessage(); utils::close(fd); - LOGE("Error in fcntl: " + std::string(strerror(errno))); - throw IPCException("Error in fcntl: " + std::string(strerror(errno))); + LOGE("Error in fcntl: " + msg); + throw IPCException("Error in fcntl: " + msg); } return Socket(fd); diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index 511fcda..209f9ba 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -147,7 +147,7 @@ bool setSuppGroups(const std::vector& groups) } if (::setgroups(gids.size(), gids.data()) != 0) { - LOGE("setgroups() failed: " << strerror(errno)); + LOGE("setgroups() failed: " << getSystemErrorMessage()); return false; } diff --git a/common/utils/eventfd.cpp b/common/utils/eventfd.cpp index 2fd8d62..d69d572 100644 --- a/common/utils/eventfd.cpp +++ b/common/utils/eventfd.cpp @@ -41,8 +41,9 @@ EventFD::EventFD() { mFD = ::eventfd(0, EFD_SEMAPHORE | EFD_CLOEXEC); if (mFD == -1) { - LOGE("Error in eventfd: " << getSystemErrorMessage()); - throw UtilsException("Error in eventfd: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in eventfd: " << msg); + throw UtilsException("Error in eventfd: " + msg); } } diff --git a/common/utils/fd-utils.cpp b/common/utils/fd-utils.cpp index 59bad36..17448b5 100644 --- a/common/utils/fd-utils.cpp +++ b/common/utils/fd-utils.cpp @@ -67,8 +67,9 @@ void waitForEvent(int fd, if (errno == EINTR) { continue; } - LOGE("Error in poll: " + getSystemErrorMessage()); - throw UtilsException("Error in poll: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in poll: " + msg); + throw UtilsException("Error in poll: " + msg); } if (ret == 0) { @@ -128,8 +129,9 @@ void write(int fd, const void* bufferPtr, const size_t size, int timeoutMS) // Neglected errors LOGD("Retrying write"); } else { - LOGE("Error during writing: " + getSystemErrorMessage()); - throw UtilsException("Error during writing: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error during writing: " + msg); + throw UtilsException("Error during writing: " + msg); } waitForEvent(fd, POLLOUT, deadline); @@ -160,8 +162,9 @@ void read(int fd, void* bufferPtr, const size_t size, int timeoutMS) // Neglected errors LOGD("Retrying read"); } else { - LOGE("Error during reading: " + getSystemErrorMessage()); - throw UtilsException("Error during reading: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error during reading: " + msg); + throw UtilsException("Error during reading: " + msg); } waitForEvent(fd, POLLIN, deadline); @@ -172,8 +175,9 @@ unsigned int getMaxFDNumber() { struct rlimit rlim; if (-1 == getrlimit(RLIMIT_NOFILE, &rlim)) { - LOGE("Error during getrlimit: " + getSystemErrorMessage()); - throw UtilsException("Error during getrlimit: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error during getrlimit: " + msg); + throw UtilsException("Error during getrlimit: " + msg); } return rlim.rlim_cur; } @@ -184,8 +188,9 @@ void setMaxFDNumber(unsigned int limit) rlim.rlim_cur = limit; rlim.rlim_max = limit; if (-1 == setrlimit(RLIMIT_NOFILE, &rlim)) { - LOGE("Error during setrlimit: " + getSystemErrorMessage()); - throw UtilsException("Error during setrlimit: " + getSystemErrorMessage()); + const std::string msg = getSystemErrorMessage(); + LOGE("Error during setrlimit: " + msg); + throw UtilsException("Error during setrlimit: " + msg); } } diff --git a/common/utils/fs.cpp b/common/utils/fs.cpp index e3a59b3..e4dcd7f 100644 --- a/common/utils/fs.cpp +++ b/common/utils/fs.cpp @@ -122,7 +122,7 @@ bool removeFile(const std::string& path) LOGD(path << ": exists, removing."); if (::remove(path.c_str())) { if (errno != ENOENT) { - LOGE(path << ": failed to delete: " << ::strerror(errno)); + LOGE(path << ": failed to delete: " << getSystemErrorMessage()); return false; } } @@ -145,7 +145,7 @@ const unsigned long RUN_MOUNT_POINT_FLAGS = MS_NOSUID | MS_NODEV | MS_STRICTATIM bool mountTmpfs(const std::string& path, unsigned long flags, const std::string& options) { if (::mount("tmpfs", path.c_str(), "tmpfs", flags, options.c_str()) != 0) { - LOGD("Mount failed for '" << path << "', options=" << options << ": " << strerror(errno)); + LOGD("Mount failed for '" << path << "', options=" << options << ": " << getSystemErrorMessage()); return false; } return true; @@ -192,7 +192,7 @@ bool mount(const std::string& source, bool umount(const std::string& path) { if (::umount(path.c_str()) != 0) { - LOGD("Umount failed for '" << path << "': " << strerror(errno)); + LOGD("Umount failed for '" << path << "': " << getSystemErrorMessage()); return false; } return true; @@ -213,12 +213,12 @@ bool hasSameMountPoint(const std::string& path1, const std::string& path2, bool& struct stat s1, s2; if (::stat(path1.c_str(), &s1)) { - LOGD("Failed to get stat of " << path1 << ": " << strerror(errno)); + LOGD("Failed to get stat of " << path1 << ": " << getSystemErrorMessage()); return false; } if (::stat(path2.c_str(), &s2)) { - LOGD("Failed to get stat of " << path2 << ": " << strerror(errno)); + LOGD("Failed to get stat of " << path2 << ": " << getSystemErrorMessage()); return false; } @@ -305,11 +305,11 @@ bool copyDirContentsRec(const boost::filesystem::path& src, const boost::filesys ::stat(current.string().c_str(), &info); if (fs::is_symlink(destination)) { if (::lchown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) { - LOGW("Failed to change owner of symlink " << destination.string() << ": " << strerror(errno)); + LOGW("Failed to change owner of symlink " << destination.string() << ": " << getSystemErrorMessage()); } } else { if (::chown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) { - LOGW("Failed to change owner of file " << destination.string() << ": " << strerror(errno)); + LOGW("Failed to change owner of file " << destination.string() << ": " << getSystemErrorMessage()); } } } @@ -366,11 +366,12 @@ bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem: // set owner if (::chown(path.c_str(), uid, gid) != 0) { + int err = errno; // remove the directory only if it hadn't existed before if (runDirCreated) { fs::remove(dirPath); } - LOGE("chown() failed for path '" << path << "': " << strerror(errno)); + LOGE("chown() failed for path '" << path << "': " << getSystemErrorMessage(err)); return false; } diff --git a/common/utils/img.cpp b/common/utils/img.cpp index a33b5fd..785291c 100644 --- a/common/utils/img.cpp +++ b/common/utils/img.cpp @@ -27,6 +27,7 @@ #include "utils/img.hpp" #include "utils/fs.hpp" #include "utils/paths.hpp" +#include "base-exception.hpp" #include #include @@ -52,7 +53,7 @@ bool isLoopDevFree(const std::string& loopdev, bool& ret) // open loop device FD int loopFD = ::open(loopdev.c_str(), O_RDWR); if (loopFD < 0) { - LOGD("Failed to open loop device descriptor: " << ::strerror(errno)); + LOGD("Failed to open loop device descriptor: " << getSystemErrorMessage()); return false; } @@ -77,21 +78,21 @@ bool mountLoop(const std::string& img, // get image file FD int fileFD = ::open(img.c_str(), O_RDWR); if (fileFD < 0) { - LOGD("Failed to open image file descriptor: " << ::strerror(errno)); + LOGD("Failed to open image file descriptor: " << getSystemErrorMessage()); return false; } // get loop device FD int loopFD = ::open(loopdev.c_str(), O_RDWR); if (loopFD < 0) { - LOGD("Failed to open loop device descriptor: " << ::strerror(errno)); + LOGD("Failed to open loop device descriptor: " << getSystemErrorMessage()); ::close(fileFD); return false; } // set loop device if (::ioctl(loopFD, LOOP_SET_FD, fileFD)) { - LOGD("Failed to assign loop device to image: " << ::strerror(errno)); + LOGD("Failed to assign loop device to image: " << getSystemErrorMessage()); ::close(fileFD); ::close(loopFD); return false; @@ -99,7 +100,7 @@ bool mountLoop(const std::string& img, // mount loop device to path if (::mount(loopdev.c_str(), path.c_str(), type.c_str(), flags, options.c_str()) != 0) { - LOGD("Mount failed for '" << path << "', options=" << options << ": " << strerror(errno)); + LOGD("Mount failed for '" << path << "', options=" << options << ": " << getSystemErrorMessage()); ::ioctl(loopFD, LOOP_CLR_FD, 0); ::close(fileFD); ::close(loopFD); @@ -150,7 +151,7 @@ bool mountImage(const std::string& image, const std::string& path, const std::st bool umountImage(const std::string& path, const std::string& loopdev) { if (::umount(path.c_str()) != 0) { - LOGD("Umount failed for '" << path << "': " << strerror(errno)); + LOGD("Umount failed for '" << path << "': " << getSystemErrorMessage()); return false; } diff --git a/common/utils/signal.cpp b/common/utils/signal.cpp index fdb571c..11ea8f2 100644 --- a/common/utils/signal.cpp +++ b/common/utils/signal.cpp @@ -38,13 +38,15 @@ void signalBlock(const int signalToBlock) { ::sigset_t set; if (-1 == ::sigemptyset(&set)) { - LOGE("Error in sigemptyset: " << std::string(strerror(errno))); - throw UtilsException("Error in sigemptyset: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in sigemptyset: " << msg); + throw UtilsException("Error in sigemptyset: " + msg); } if (-1 ==::sigaddset(&set, signalToBlock)) { - LOGE("Error in sigaddset: " << std::string(strerror(errno))); - throw UtilsException("Error in sigaddset: " + std::string(strerror(errno))); + const std::string msg = getSystemErrorMessage(); + LOGE("Error in sigaddset: " << msg); + throw UtilsException("Error in sigaddset: " + msg); } int ret = ::pthread_sigmask(SIG_BLOCK, &set, nullptr /*&oldSet*/); diff --git a/common/utils/vt.cpp b/common/utils/vt.cpp index df8a923..44461e4 100644 --- a/common/utils/vt.cpp +++ b/common/utils/vt.cpp @@ -25,6 +25,7 @@ #include "config.hpp" #include "utils/vt.hpp" #include "logger/logger.hpp" +#include "base-exception.hpp" #include #include @@ -46,14 +47,14 @@ bool activateVT(const int& vt) { int consoleFD = ::open(TTY_DEV.c_str(), O_WRONLY); if (consoleFD < 0) { - LOGE("console open failed: " << errno << " (" << strerror(errno) << ")"); + LOGE("console open failed: " << errno << " (" << getSystemErrorMessage() << ")"); 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) << ")"); + LOGE("Failed to get vt state: " << errno << " (" << getSystemErrorMessage() << ")"); ::close(consoleFD); return false; } @@ -66,14 +67,14 @@ bool activateVT(const int& vt) // activate vt if (::ioctl(consoleFD, VT_ACTIVATE, vt)) { - LOGE("Failed to activate vt" << vt << ": " << errno << " (" << strerror(errno) << ")"); + LOGE("Failed to activate vt" << vt << ": " << errno << " (" << getSystemErrorMessage() << ")"); ::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) << ")"); + LOGE("Failed to wait for vt" << vt << " activation: " << errno << " (" << getSystemErrorMessage() << ")"); ::close(consoleFD); return false; } diff --git a/libs/config/fdstore.cpp b/libs/config/fdstore.cpp index 2b761eb..c0b7d08 100644 --- a/libs/config/fdstore.cpp +++ b/libs/config/fdstore.cpp @@ -37,6 +37,15 @@ namespace config { namespace { +const int ERROR_MESSAGE_BUFFER_CAPACITY = 256; + +std::string getSystemErrorMessage() +{ + char buf[ERROR_MESSAGE_BUFFER_CAPACITY]; + return strerror_r(errno, buf, sizeof(buf)); +} + + void waitForEvent(int fd, short event, const std::chrono::high_resolution_clock::time_point deadline) @@ -59,7 +68,7 @@ void waitForEvent(int fd, if (errno == EINTR) { continue; } - throw ConfigException("Error in poll: " + std::string(strerror(errno))); + throw ConfigException("Error in poll: " + getSystemErrorMessage()); } if (ret == 0) { @@ -110,7 +119,7 @@ void FDStore::write(const void* bufferPtr, const size_t size, const unsigned int } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { // Neglected errors } else { - throw ConfigException("Error during writing: " + std::string(strerror(errno))); + throw ConfigException("Error during writing: " + getSystemErrorMessage()); } waitForEvent(mFD, POLLOUT, deadline); @@ -139,7 +148,7 @@ void FDStore::read(void* bufferPtr, const size_t size, const unsigned int timeou } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { // Neglected errors } else { - throw ConfigException("Error during reading: " + std::string(strerror(errno))); + throw ConfigException("Error during reading: " + getSystemErrorMessage()); } waitForEvent(mFD, POLLIN, deadline); diff --git a/server/server.cpp b/server/server.cpp index f64ea03..ab8cba3 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -130,8 +130,7 @@ void Server::reloadIfRequired(char* argv[]) { if (gUpdateTriggered) { execve(argv[0], argv, environ); - - LOGE("Failed to reload " << argv[0] << ": " << strerror(errno)); + LOGE("Failed to reload " << argv[0] << ": " << getSystemErrorMessage()); } } -- 2.7.4