//vsm_get_poll_fd, vsm_enter_eventloop can't be used at the same time.
//TODO: Make vsm_get_status_message thread-safe version (vsm_get_status_message_r)
-#include <config.hpp>
+#include "config.hpp"
#include "vasum-client-impl.hpp"
#include "utils.hpp"
#include "exception.hpp"
#include "utils/exception.hpp"
-#include "host-ipc-connection.hpp"
#include "logger/logger.hpp"
+#include "host-ipc-definitions.hpp"
+#include "ipc/client.hpp"
+#include "api/messages.hpp"
#include <algorithm>
#include <vector>
+#include <memory>
#include <cstring>
#include <fstream>
#include <arpa/inet.h>
namespace {
+const int TIMEOUT_INFINITE = -1;
+
VsmZoneState getZoneState(const char* state)
{
if (strcmp(state, "STOPPED") == 0) {
}
}
-void convert(const api::ZoneInfoOut& info, VsmZone& zone)
+void convert(const api::ZoneInfoOut& info, Zone& zone)
{
- VsmZone vsmZone = reinterpret_cast<VsmZone>(malloc(sizeof(*vsmZone)));
+ Zone vsmZone = static_cast<Zone>(malloc(sizeof(*vsmZone)));
vsmZone->id = ::strdup(info.id.c_str());
vsmZone->terminal = info.vt;
vsmZone->state = getZoneState(info.state.c_str());
{
}
+bool Client::isConnected() const
+{
+ return mClient && mClient->isStarted();
+}
+
bool Client::isInternalDispatcherEnabled() const
{
return static_cast<bool>(mInternalDispatcher);
if (!mInternalDispatcher && !mEventPoll) {
vsm_set_dispatcher_type(VSMDISPATCHER_INTERNAL);
}
- mHostClient.connect(address, getEventPoll());
+ mClient.reset(new ipc::Client(getEventPoll(), address));
+ mClient->start();
});
}
VsmStatus Client::disconnect() noexcept
{
return coverException([&] {
- mHostClient.disconnect();
+ mClient.reset();
});
}
VsmStatus Client::vsm_set_dispatcher_type(VsmDispacherType dispacher) noexcept
{
return coverException([&] {
- if (mHostClient.isConnected()) {
+ if (isConnected()) {
throw OperationFailedException("Can't change dispacher");
}
switch (dispacher) {
});
}
-VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept
+VsmStatus Client::vsm_lock_queue() noexcept
{
return coverException([&] {
- IS_SET(array);
+ *mClient->callSync<api::Void, api::Void>(
+ vasum::api::ipc::METHOD_LOCK_QUEUE,
+ std::make_shared<api::Void>());
+ });
+}
- api::ZoneIds zoneIds;
- mHostClient.callGetZoneIds(zoneIds);
- convert(zoneIds, *array);
+VsmStatus Client::vsm_unlock_queue() noexcept
+{
+ return coverException([&] {
+ *mClient->callSync<api::Void, api::Void>(
+ vasum::api::ipc::METHOD_UNLOCK_QUEUE,
+ std::make_shared<api::Void>());
});
}
-VsmStatus Client::vsm_get_active_zone_id(VsmString* id) noexcept
+VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept
{
return coverException([&] {
- IS_SET(id);
+ IS_SET(array);
- api::ZoneId zoneId;
- mHostClient.callGetActiveZoneId(zoneId);
- *id = ::strdup(zoneId.value.c_str());
+ api::ZoneIds zoneIds = *mClient->callSync<api::Void, api::ZoneIds>(
+ vasum::api::ipc::METHOD_GET_ZONE_ID_LIST,
+ std::make_shared<api::Void>());
+ convert(zoneIds, *array);
});
}
-VsmStatus Client::vsm_get_zone_rootpath(const char* id, VsmString* rootpath) noexcept
+VsmStatus Client::vsm_get_active_zone_id(VsmString* id) noexcept
{
return coverException([&] {
IS_SET(id);
- IS_SET(rootpath);
- api::ZoneInfoOut info;
- mHostClient.callGetZoneInfo({ id }, info);
- *rootpath = ::strdup(info.rootPath.c_str());
+ api::ZoneId zoneId = *mClient->callSync<api::Void, api::ZoneId>(
+ api::ipc::METHOD_GET_ACTIVE_ZONE_ID,
+ std::make_shared<api::Void>());
+ *id = ::strdup(zoneId.value.c_str());
});
}
});
}
-VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept
+VsmStatus Client::vsm_lookup_zone_by_id(const char* id, Zone* zone) noexcept
{
return coverException([&] {
IS_SET(id);
IS_SET(zone);
- api::ZoneInfoOut info;
- mHostClient.callGetZoneInfo({ id }, info);
+ api::ZoneInfoOut info = *mClient->callSync<api::ZoneId, api::ZoneInfoOut>(
+ api::ipc::METHOD_GET_ZONE_INFO,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }));
convert(info, *zone);
});
}
return coverException([&] {
IS_SET(id);
- mHostClient.callSetActiveZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_SET_ACTIVE_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }));
});
}
IS_SET(id);
string template_name = tname ? tname : "default";
- mHostClient.callCreateZone({ id, template_name });
+ mClient->callSync<api::CreateZoneIn, api::Void>(
+ api::ipc::METHOD_CREATE_ZONE,
+ std::make_shared<api::CreateZoneIn>(api::CreateZoneIn{ id, template_name }),
+ TIMEOUT_INFINITE);
});
}
{
return coverException([&] {
IS_SET(id);
- mHostClient.callDestroyZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_DESTROY_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }),
+ TIMEOUT_INFINITE);
});
}
{
return coverException([&] {
IS_SET(id);
- mHostClient.callShutdownZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_SHUTDOWN_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }),
+ TIMEOUT_INFINITE);
});
}
{
return coverException([&] {
IS_SET(id);
- mHostClient.callStartZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_START_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }),
+ TIMEOUT_INFINITE);
});
}
{
return coverException([&] {
IS_SET(id);
- mHostClient.callLockZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_LOCK_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }),
+ TIMEOUT_INFINITE);
});
}
{
return coverException([&] {
IS_SET(id);
- mHostClient.callUnlockZone({ id });
+ mClient->callSync<api::ZoneId, api::Void>(
+ api::ipc::METHOD_UNLOCK_ZONE,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }));
});
}
VsmStatus Client::vsm_del_state_callback(VsmSubscriptionId subscriptionId) noexcept
{
return coverException([&] {
- mHostClient.unsubscribe(subscriptionId);
+ mClient->removeMethod(subscriptionId);
});
}
IS_SET(id);
IS_SET(device);
- mHostClient.callGrantDevice({ id, device, flags });
+ mClient->callSync<api::GrantDeviceIn, api::Void>(
+ api::ipc::METHOD_GRANT_DEVICE,
+ std::make_shared<api::GrantDeviceIn>(api::GrantDeviceIn{ id, device, flags }));
});
}
IS_SET(id);
IS_SET(device);
- mHostClient.callRevokeDevice({ id, device });
+ mClient->callSync<api::RevokeDeviceIn, api::Void>(
+ api::ipc::METHOD_REVOKE_DEVICE,
+ std::make_shared<api::RevokeDeviceIn>(api::RevokeDeviceIn{ id, device }));
});
}
IS_SET(id);
IS_SET(netdevIds);
- api::NetDevList netdevs;
- mHostClient.callGetNetdevList({ id }, netdevs);
+ api::NetDevList netdevs = *mClient->callSync<api::ZoneId, api::NetDevList>(
+ api::ipc::METHOD_GET_NETDEV_LIST,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }));
convert(netdevs, *netdevIds);
});
}
VsmStatus Client::vsm_netdev_get_ip_addr(const char* id,
const char* netdevId,
- int type,
- void* addr) noexcept
+ std::vector<InetAddr>& addrs) noexcept
{
using namespace boost::algorithm;
return coverException([&] {
IS_SET(id);
IS_SET(netdevId);
- IS_SET(addr);
- api::GetNetDevAttrs attrs;
- mHostClient.callGetNetdevAttrs({ id, netdevId }, attrs);
+ addrs.clear();
- auto it = find_if(attrs.values.begin(),
- attrs.values.end(),
- [type](const api::StringPair& entry) {
- return entry.first == (type == AF_INET ? "ipv4" : "ipv6");
- });
+ api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
+ api::ipc::METHOD_GET_NETDEV_ATTRS,
+ std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
+
+ for (const auto &attr : attrs.values) {
+ InetAddr addr;
+ if (attr.first == "ipv4") {
+ addr.type = AF_INET;
+ }
+ else if (attr.first == "ipv6") {
+ addr.type = AF_INET6;
+ }
+ else continue;
- if (it != attrs.values.end()) {
- vector<string> addrAttrs;
- for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) {
+ std::vector<std::string> addrAttrs;
+ for(const auto& addrAttr : split(addrAttrs, attr.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");
+ if (pos == string::npos) continue;
+
+ if (addrAttr.substr(0, pos) == "prefixlen") {
+ addr.prefix = atoi(addrAttr.substr(pos + 1).c_str());
+ }
+ else if (addrAttr.substr(0, pos) == "ip") {
+ if (inet_pton(addr.type, addrAttr.substr(pos + 1).c_str(), &addr.addr) != 1) {
+ addr.type = -1;
+ break;
}
}
}
+ if (addr.type >= 0)
+ addrs.push_back(addr);
}
- throw OperationFailedException("Address not found");
});
}
const char* netdevId,
struct in_addr* addr) noexcept
{
- return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr);
+ std::vector<InetAddr> addrs;
+ VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
+ for (const auto& a : addrs) {
+ if (a.type == AF_INET) {
+ memcpy(addr, &a.addr, sizeof(*addr));
+ break;
+ }
+ }
+ return st;
}
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);
+ std::vector<InetAddr> addrs;
+ VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
+ for (const auto& a : addrs) {
+ if (a.type == AF_INET6) {
+ memcpy(addr, &a.addr, sizeof(*addr));
+ break;
+ }
+ }
+ return st;
}
-VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id,
+VsmStatus Client::vsm_netdev_add_ipv4_addr(const char* id,
const char* netdevId,
struct in_addr* addr,
int prefix) noexcept
IS_SET(addr);
string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
- mHostClient.callSetNetdevAttrs({ id, netdevId, { { "ipv4", value } } } );
+ mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
+ api::ipc::METHOD_SET_NETDEV_ATTRS,
+ std::make_shared<api::SetNetDevAttrsIn>(
+ api::SetNetDevAttrsIn{ id, netdevId, { { "ipv4", value } } }));
});
}
-VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id,
+VsmStatus Client::vsm_netdev_add_ipv6_addr(const char* id,
const char* netdevId,
struct in6_addr* addr,
int prefix) noexcept
IS_SET(addr);
string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
- mHostClient.callSetNetdevAttrs({ id, netdevId, { { "ipv6", value } } } );
+ mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
+ api::ipc::METHOD_SET_NETDEV_ATTRS,
+ std::make_shared<api::SetNetDevAttrsIn>(
+ api::SetNetDevAttrsIn{ id, netdevId, { { "ipv6", value } } }));
});
}
//CIDR notation
string ip = toString(addr) + "/" + to_string(prefix);
- mHostClient.callDeleteNetdevIpAddress({ id, netdevId, ip });
+ mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
+ api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
+ std::make_shared<api::DeleteNetdevIpAddressIn>(
+ api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
});
}
//CIDR notation
string ip = toString(addr) + "/" + to_string(prefix);
- mHostClient.callDeleteNetdevIpAddress({ id, netdevId, ip });
+ mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
+ api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
+ std::make_shared<api::DeleteNetdevIpAddressIn>(
+ api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
});
}
IS_SET(id);
IS_SET(netdevId);
- mHostClient.callSetNetdevAttrs({ id, netdevId, { { "flags", to_string(IFF_UP) },
- { "change", to_string(IFF_UP) } } } );
+ mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
+ api::ipc::METHOD_SET_NETDEV_ATTRS,
+ std::make_shared<api::SetNetDevAttrsIn>(
+ api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(IFF_UP) },
+ { "change", to_string(IFF_UP) } } }));
});
}
IS_SET(id);
IS_SET(netdevId);
- mHostClient.callSetNetdevAttrs({ id, netdevId, { { "flags", to_string(~IFF_UP) },
- { "change", to_string(IFF_UP) } } } );
+ mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
+ api::ipc::METHOD_SET_NETDEV_ATTRS,
+ std::make_shared<api::SetNetDevAttrsIn>(
+ api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(~IFF_UP) },
+ { "change", to_string(IFF_UP) } } }));
});
}
IS_SET(zoneDev);
IS_SET(hostDev);
- mHostClient.callCreateNetdevVeth({ id, zoneDev, hostDev });
+ mClient->callSync<api::CreateNetDevVethIn, api::Void>(
+ api::ipc::METHOD_CREATE_NETDEV_VETH,
+ std::make_shared<api::CreateNetDevVethIn>(
+ api::CreateNetDevVethIn{ id, zoneDev, hostDev }));
});
}
IS_SET(zoneDev);
IS_SET(hostDev);
- mHostClient.callCreateNetdevMacvlan({ id, zoneDev, hostDev, mode });
+ mClient->callSync<api::CreateNetDevMacvlanIn, api::Void>(
+ api::ipc::METHOD_CREATE_NETDEV_MACVLAN,
+ std::make_shared<api::CreateNetDevMacvlanIn>(
+ api::CreateNetDevMacvlanIn{ id, zoneDev, hostDev, mode }));
});
}
IS_SET(id);
IS_SET(devId);
- mHostClient.callCreateNetdevPhys({ id, devId });
+ mClient->callSync<api::CreateNetDevPhysIn, api::Void>(
+ api::ipc::METHOD_CREATE_NETDEV_PHYS,
+ std::make_shared<api::CreateNetDevPhysIn>(
+ api::CreateNetDevPhysIn{ id, devId }));
});
}
VsmStatus Client::vsm_lookup_netdev_by_name(const char* id,
const char* netdevId,
- VsmNetdev* netdev) noexcept
+ Netdev* netdev) noexcept
{
using namespace boost::algorithm;
IS_SET(netdevId);
IS_SET(netdev);
- api::GetNetDevAttrs attrs;
- mHostClient.callGetNetdevAttrs({ id, netdevId }, attrs);
+ api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
+ api::ipc::METHOD_GET_NETDEV_ATTRS,
+ std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
auto it = find_if(attrs.values.begin(),
attrs.values.end(),
[](const api::StringPair& entry) {
throw InvalidResponseException("Unknown netdev type: " + it->second);
}
- *netdev = reinterpret_cast<VsmNetdev>(malloc(sizeof(**netdev)));
+ *netdev = static_cast<Netdev>(malloc(sizeof(**netdev)));
(*netdev)->name = ::strdup(id);
(*netdev)->type = type;
});
IS_SET(id);
IS_SET(devId);
- mHostClient.callDestroyNetdev({ id, devId });
+ mClient->callSync<api::DestroyNetDevIn, api::Void>(
+ api::ipc::METHOD_DESTROY_NETDEV,
+ std::make_shared<api::DestroyNetDevIn>(api::DestroyNetDevIn{ id, devId }));
});
}
IS_SET(id);
IS_SET(path);
- api::Declaration declaration;
- mHostClient.callDeclareFile({ id, type, path, flags, (int)mode }, declaration);
+ api::Declaration declaration = *mClient->callSync<api::DeclareFileIn, api::Declaration>(
+ api::ipc::METHOD_DECLARE_FILE,
+ std::make_shared<api::DeclareFileIn>(
+ api::DeclareFileIn{ id, type, path, flags, (int)mode }));
if (declarationId != NULL) {
*declarationId = ::strdup(declaration.value.c_str());
}
data = "";
}
- api::Declaration declaration;
- mHostClient.callDeclareMount({ source, id, target, type, flags, data }, declaration);
+ api::Declaration declaration = *mClient->callSync<api::DeclareMountIn, api::Declaration>(
+ api::ipc::METHOD_DECLARE_MOUNT,
+ std::make_shared<api::DeclareMountIn>(
+ api::DeclareMountIn{ source, id, target, type, flags, data }));
if (declarationId != NULL) {
*declarationId = ::strdup(declaration.value.c_str());
}
IS_SET(id);
IS_SET(target);
- api::Declaration declaration;
- mHostClient.callDeclareLink({ source, id, target }, declaration);
+ api::Declaration declaration = *mClient->callSync<api::DeclareLinkIn, api::Declaration>(
+ api::ipc::METHOD_DECLARE_LINK,
+ std::make_shared<api::DeclareLinkIn>(api::DeclareLinkIn{ source, id, target }));
if (declarationId != NULL) {
*declarationId = ::strdup(declaration.value.c_str());
}
IS_SET(id);
IS_SET(declarations);
- api::Declarations declarationsOut;
- mHostClient.callGetDeclarations({ id }, declarationsOut);
+ api::Declarations declarationsOut = *mClient->callSync<api::ZoneId, api::Declarations>(
+ api::ipc::METHOD_GET_DECLARATIONS,
+ std::make_shared<api::ZoneId>(api::ZoneId{ id }));
convert(declarationsOut, *declarations);
});
}
IS_SET(id);
IS_SET(declaration);
- mHostClient.callRemoveDeclaration({ id, declaration });
- });
-}
-
-VsmStatus Client::vsm_notify_active_zone(const char* /*application*/, const char* /*message*/) noexcept
-{
- return coverException([&] {
- //TODO: Implement vsm_notify_active_zone
- throw OperationFailedException("Not implemented");
- });
-}
-
-VsmStatus Client::vsm_file_move_request(const char* /*destZone*/, const char* /*path*/) noexcept
-{
- return coverException([&] {
- //TODO: Implement vsm_file_move_request
- throw OperationFailedException("Not implemented");
- });
-}
-
-VsmStatus Client::vsm_add_notification_callback(VsmNotificationFunction /*notificationCallback*/,
- void* /*data*/,
- VsmSubscriptionId* /*subscriptionId*/) noexcept
-{
- return coverException([&] {
- //TODO: Implement vsm_add_notification_callback
- throw OperationFailedException("Not implemented");
+ mClient->callSync<api::RemoveDeclarationIn, api::Void>(
+ api::ipc::METHOD_REMOVE_DECLARATION,
+ std::make_shared<api::RemoveDeclarationIn>(api::RemoveDeclarationIn{ id, declaration }));
});
}
-VsmStatus Client::vsm_del_notification_callback(VsmSubscriptionId subscriptionId) noexcept
+VsmStatus Client::vsm_clean_up_zones_root() noexcept
{
return coverException([&] {
- mHostClient.unsubscribe(subscriptionId);
+ mClient->callSync<api::Void, api::Void>(
+ api::ipc::METHOD_CLEAN_UP_ZONES_ROOT,
+ std::make_shared<api::Void>());
});
}