2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Mateusz Malicki <m.malicki2@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
22 * @author Mateusz Malicki (m.malicki2@samsung.com)
23 * @brief This file contains vasum-server's client implementation
26 //TODO: Make dispatcher related function thread-safe.
27 //For now vsm_connect, vsm_get_dispatcher_type, vsm_set_dispatcher_type,
28 //vsm_get_poll_fd, vsm_enter_eventloop can't be used at the same time.
29 //TODO: Make vsm_get_status_message thread-safe version (vsm_get_status_message_r)
32 #include "vasum-client-impl.hpp"
34 #include "exception.hpp"
35 #include "utils/exception.hpp"
36 #include "logger/logger.hpp"
37 #include "host-ipc-definitions.hpp"
38 #include "ipc/client.hpp"
39 #include "api/messages.hpp"
46 #include <arpa/inet.h>
49 #include <boost/algorithm/string/split.hpp>
50 #include <boost/algorithm/string/classification.hpp>
53 using namespace utils;
54 using namespace vasum;
58 const int TIMEOUT_INFINITE = -1;
60 VsmZoneState getZoneState(const char* state)
62 if (strcmp(state, "STOPPED") == 0) {
64 } else if (strcmp(state, "STARTING") == 0) {
66 } else if (strcmp(state, "RUNNING") == 0) {
68 } else if (strcmp(state, "STOPPING") == 0) {
70 } else if (strcmp(state, "ABORTING") == 0) {
72 } else if (strcmp(state, "FREEZING") == 0) {
74 } else if (strcmp(state, "FROZEN") == 0) {
76 } else if (strcmp(state, "THAWED") == 0) {
78 } else if (strcmp(state, "LOCKED") == 0) {
80 } else if (strcmp(state, "MAX_STATE") == 0) {
82 } else if (strcmp(state, "ACTIVATING") == 0) {
85 throw InvalidResponseException("Unknown state");
88 void convert(const api::VectorOfStrings& in, VsmArrayString& out)
90 out = reinterpret_cast<char**>(calloc(in.values.size() + 1, sizeof(char*)));
91 for (size_t i = 0; i < in.values.size(); ++i) {
92 out[i] = ::strdup(in.values[i].c_str());
96 void convert(const api::ZoneInfoOut& info, Zone& zone)
98 Zone vsmZone = static_cast<Zone>(malloc(sizeof(*vsmZone)));
99 vsmZone->id = ::strdup(info.id.c_str());
100 vsmZone->terminal = info.vt;
101 vsmZone->state = getZoneState(info.state.c_str());
102 vsmZone->rootfs_path = ::strdup(info.rootPath.c_str());
106 string toString(const in_addr* addr)
108 char buf[INET_ADDRSTRLEN];
109 const char* ret = inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
111 throw InvalidArgumentException(getSystemErrorMessage());
116 string toString(const in6_addr* addr)
118 char buf[INET6_ADDRSTRLEN];
119 const char* ret = inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN);
121 throw InvalidArgumentException(getSystemErrorMessage());
126 bool readFirstLineOfFile(const string& path, string& ret)
139 #define IS_SET(param) \
141 throw InvalidArgumentException(#param " is not set"); \
144 Client::Status::Status()
145 : mVsmStatus(VSMCLIENT_SUCCESS), mMsg()
149 Client::Status::Status(VsmStatus status, const string& msg)
150 : mVsmStatus(status), mMsg(msg)
154 Client::Client() noexcept
158 Client::~Client() noexcept
162 bool Client::isConnected() const
164 return mClient && mClient->isStarted();
167 bool Client::isInternalDispatcherEnabled() const
169 return static_cast<bool>(mInternalDispatcher);
172 ipc::epoll::EventPoll& Client::getEventPoll() const
174 if ((mInternalDispatcher && mEventPoll) || (!mInternalDispatcher && !mEventPoll)) {
175 throw OperationFailedException("Can't determine dispatcher method");
178 if (isInternalDispatcherEnabled()) {
179 return mInternalDispatcher->getPoll();
185 VsmStatus Client::coverException(const function<void(void)>& worker) noexcept
190 mStatus = Status(VSMCLIENT_SUCCESS);
191 } catch (const IOException& ex) {
192 mStatus = Status(VSMCLIENT_IO_ERROR, ex.what());
193 } catch (const OperationFailedException& ex) {
194 mStatus = Status(VSMCLIENT_OPERATION_FAILED, ex.what());
195 } catch (const InvalidArgumentException& ex) {
196 mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, ex.what());
197 } catch (const InvalidResponseException& ex) {
198 mStatus = Status(VSMCLIENT_OTHER_ERROR, ex.what());
199 } catch (const ClientException& ex) {
200 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
201 } catch (const ipc::IPCUserException& ex) {
202 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
203 } catch (const ipc::IPCException& ex) {
204 mStatus = Status(VSMCLIENT_IO_ERROR, ex.what());
205 } catch (const exception& ex) {
206 mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
208 VsmStatus ret = mStatus.mVsmStatus;
209 mStatusMutex.unlock();
213 VsmStatus Client::connectSystem() noexcept
215 return connect(HOST_IPC_SOCKET);
218 VsmStatus Client::connect(const std::string& address) noexcept
220 return coverException([&] {
221 if (!mInternalDispatcher && !mEventPoll) {
222 vsm_set_dispatcher_type(VSMDISPATCHER_INTERNAL);
224 mClient.reset(new ipc::Client(getEventPoll(), address));
229 VsmStatus Client::disconnect() noexcept
231 return coverException([&] {
236 VsmStatus Client::vsm_get_poll_fd(int* fd) noexcept
238 return coverException([&] {
240 if (isInternalDispatcherEnabled()) {
241 throw OperationFailedException("Can't get event fd from internal dispatcher");
243 *fd = mEventPoll->getPollFD();
247 VsmStatus Client::vsm_enter_eventloop(int /* flags */, int timeout) noexcept
249 return coverException([&] {
250 if (isInternalDispatcherEnabled()) {
251 throw OperationFailedException("Can't enter to event loop of internal dispatcher");
253 mEventPoll->dispatchIteration(timeout);
257 VsmStatus Client::vsm_set_dispatcher_type(VsmDispacherType dispacher) noexcept
259 return coverException([&] {
261 throw OperationFailedException("Can't change dispacher");
264 case VSMDISPATCHER_INTERNAL:
265 mInternalDispatcher.reset(new ipc::epoll::ThreadDispatcher());
268 case VSMDISPATCHER_EXTERNAL:
269 mEventPoll.reset(new ipc::epoll::EventPoll());
270 mInternalDispatcher.reset();
273 throw OperationFailedException("Unsupported EventDispacher type");
278 VsmStatus Client::vsm_get_dispatcher_type(VsmDispacherType* dispacher) noexcept
280 return coverException([&] {
283 if (isInternalDispatcherEnabled()) {
284 *dispacher = VSMDISPATCHER_INTERNAL;
286 *dispacher = VSMDISPATCHER_EXTERNAL;
291 const char* Client::vsm_get_status_message() const noexcept
293 return mStatus.mMsg.c_str();
296 VsmStatus Client::vsm_get_status() const noexcept
298 lock_guard<mutex> lock(mStatusMutex);
299 return mStatus.mVsmStatus;
302 VsmStatus Client::vsm_get_zone_dbuses(VsmArrayString* /*keys*/, VsmArrayString* /*values*/) noexcept
304 return coverException([&] {
305 //TODO: Remove vsm_get_zone_dbuses from API
306 throw OperationFailedException("Not implemented");
310 VsmStatus Client::vsm_lock_queue() noexcept
312 return coverException([&] {
313 *mClient->callSync<api::Void, api::Void>(
314 vasum::api::ipc::METHOD_LOCK_QUEUE,
315 std::make_shared<api::Void>());
319 VsmStatus Client::vsm_unlock_queue() noexcept
321 return coverException([&] {
322 *mClient->callSync<api::Void, api::Void>(
323 vasum::api::ipc::METHOD_UNLOCK_QUEUE,
324 std::make_shared<api::Void>());
328 VsmStatus Client::vsm_get_zone_ids(VsmArrayString* array) noexcept
330 return coverException([&] {
333 api::ZoneIds zoneIds = *mClient->callSync<api::Void, api::ZoneIds>(
334 vasum::api::ipc::METHOD_GET_ZONE_ID_LIST,
335 std::make_shared<api::Void>());
336 convert(zoneIds, *array);
340 VsmStatus Client::vsm_get_active_zone_id(VsmString* id) noexcept
342 return coverException([&] {
345 api::ZoneId zoneId = *mClient->callSync<api::Void, api::ZoneId>(
346 api::ipc::METHOD_GET_ACTIVE_ZONE_ID,
347 std::make_shared<api::Void>());
348 *id = ::strdup(zoneId.value.c_str());
352 VsmStatus Client::vsm_lookup_zone_by_pid(int pid, VsmString* id) noexcept
354 return coverException([&] {
357 const string path = "/proc/" + to_string(pid) + "/cpuset";
360 if (!readFirstLineOfFile(path, cpuset)) {
361 throw InvalidArgumentException("Process not found");
365 if (!parseZoneIdFromCpuSet(cpuset, zoneId)) {
366 throw OperationFailedException("unknown format of cpuset");
369 *id = ::strdup(zoneId.c_str());
373 VsmStatus Client::vsm_lookup_zone_by_id(const char* id, Zone* zone) noexcept
375 return coverException([&] {
379 api::ZoneInfoOut info = *mClient->callSync<api::ZoneId, api::ZoneInfoOut>(
380 api::ipc::METHOD_GET_ZONE_INFO,
381 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
382 convert(info, *zone);
386 VsmStatus Client::vsm_lookup_zone_by_terminal_id(int, VsmString*) noexcept
388 return coverException([&] {
389 //TODO: Implement vsm_lookup_zone_by_terminal_id
390 throw OperationFailedException("Not implemented");
394 VsmStatus Client::vsm_set_active_zone(const char* id) noexcept
396 return coverException([&] {
399 mClient->callSync<api::ZoneId, api::Void>(
400 api::ipc::METHOD_SET_ACTIVE_ZONE,
401 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
405 VsmStatus Client::vsm_create_zone(const char* id, const char* tname) noexcept
407 return coverException([&] {
410 string template_name = tname ? tname : "default";
411 mClient->callSync<api::CreateZoneIn, api::Void>(
412 api::ipc::METHOD_CREATE_ZONE,
413 std::make_shared<api::CreateZoneIn>(api::CreateZoneIn{ id, template_name }),
418 VsmStatus Client::vsm_destroy_zone(const char* id) noexcept
420 return coverException([&] {
422 mClient->callSync<api::ZoneId, api::Void>(
423 api::ipc::METHOD_DESTROY_ZONE,
424 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
429 VsmStatus Client::vsm_shutdown_zone(const char* id) noexcept
431 return coverException([&] {
433 mClient->callSync<api::ZoneId, api::Void>(
434 api::ipc::METHOD_SHUTDOWN_ZONE,
435 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
440 VsmStatus Client::vsm_start_zone(const char* id) noexcept
442 return coverException([&] {
444 mClient->callSync<api::ZoneId, api::Void>(
445 api::ipc::METHOD_START_ZONE,
446 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
451 VsmStatus Client::vsm_lock_zone(const char* id) noexcept
453 return coverException([&] {
455 mClient->callSync<api::ZoneId, api::Void>(
456 api::ipc::METHOD_LOCK_ZONE,
457 std::make_shared<api::ZoneId>(api::ZoneId{ id }),
462 VsmStatus Client::vsm_unlock_zone(const char* id) noexcept
464 return coverException([&] {
466 mClient->callSync<api::ZoneId, api::Void>(
467 api::ipc::METHOD_UNLOCK_ZONE,
468 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
472 VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateFunction /* zoneDbusStateCallback */,
474 VsmSubscriptionId* /* subscriptionId */) noexcept
476 return coverException([&] {
477 //TODO: Implement vsm_add_state_callback
478 throw OperationFailedException("Not implemented");
482 VsmStatus Client::vsm_del_state_callback(VsmSubscriptionId subscriptionId) noexcept
484 return coverException([&] {
485 mClient->removeMethod(subscriptionId);
489 VsmStatus Client::vsm_grant_device(const char* id, const char* device, uint32_t flags) noexcept
491 return coverException([&] {
495 mClient->callSync<api::GrantDeviceIn, api::Void>(
496 api::ipc::METHOD_GRANT_DEVICE,
497 std::make_shared<api::GrantDeviceIn>(api::GrantDeviceIn{ id, device, flags }));
501 VsmStatus Client::vsm_revoke_device(const char* id, const char* device) noexcept
503 return coverException([&] {
507 mClient->callSync<api::RevokeDeviceIn, api::Void>(
508 api::ipc::METHOD_REVOKE_DEVICE,
509 std::make_shared<api::RevokeDeviceIn>(api::RevokeDeviceIn{ id, device }));
513 VsmStatus Client::vsm_zone_get_netdevs(const char* id, VsmArrayString* netdevIds) noexcept
515 return coverException([&] {
519 api::NetDevList netdevs = *mClient->callSync<api::ZoneId, api::NetDevList>(
520 api::ipc::METHOD_GET_NETDEV_LIST,
521 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
522 convert(netdevs, *netdevIds);
526 VsmStatus Client::vsm_netdev_get_ip_addr(const char* id,
527 const char* netdevId,
528 std::vector<InetAddr>& addrs) noexcept
530 using namespace boost::algorithm;
532 return coverException([&] {
538 api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
539 api::ipc::METHOD_GET_NETDEV_ATTRS,
540 std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
542 for (const auto &attr : attrs.values) {
544 if (attr.first == "ipv4") {
547 else if (attr.first == "ipv6") {
548 addr.type = AF_INET6;
552 std::vector<std::string> addrAttrs;
553 for(const auto& addrAttr : split(addrAttrs, attr.second, is_any_of(","))) {
554 size_t pos = addrAttr.find(":");
555 if (pos == string::npos) continue;
557 if (addrAttr.substr(0, pos) == "prefixlen") {
558 addr.prefix = atoi(addrAttr.substr(pos + 1).c_str());
560 else if (addrAttr.substr(0, pos) == "ip") {
561 if (inet_pton(addr.type, addrAttr.substr(pos + 1).c_str(), &addr.addr) != 1) {
568 addrs.push_back(addr);
573 VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id,
574 const char* netdevId,
575 struct in_addr* addr) noexcept
577 std::vector<InetAddr> addrs;
578 VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
579 for (const auto& a : addrs) {
580 if (a.type == AF_INET) {
581 memcpy(addr, &a.addr, sizeof(*addr));
588 VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id,
589 const char* netdevId,
590 struct in6_addr* addr) noexcept
592 std::vector<InetAddr> addrs;
593 VsmStatus st=vsm_netdev_get_ip_addr(id, netdevId, addrs);
594 for (const auto& a : addrs) {
595 if (a.type == AF_INET6) {
596 memcpy(addr, &a.addr, sizeof(*addr));
603 VsmStatus Client::vsm_netdev_add_ipv4_addr(const char* id,
604 const char* netdevId,
605 struct in_addr* addr,
608 return coverException([&] {
613 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
614 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
615 api::ipc::METHOD_SET_NETDEV_ATTRS,
616 std::make_shared<api::SetNetDevAttrsIn>(
617 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv4", value } } }));
621 VsmStatus Client::vsm_netdev_add_ipv6_addr(const char* id,
622 const char* netdevId,
623 struct in6_addr* addr,
626 return coverException([&] {
631 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
632 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
633 api::ipc::METHOD_SET_NETDEV_ATTRS,
634 std::make_shared<api::SetNetDevAttrsIn>(
635 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv6", value } } }));
639 VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* id,
640 const char* netdevId,
641 struct in_addr* addr,
644 return coverException([&] {
650 string ip = toString(addr) + "/" + to_string(prefix);
651 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
652 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
653 std::make_shared<api::DeleteNetdevIpAddressIn>(
654 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
658 VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* id,
659 const char* netdevId,
660 struct in6_addr* addr,
663 return coverException([&] {
669 string ip = toString(addr) + "/" + to_string(prefix);
670 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
671 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
672 std::make_shared<api::DeleteNetdevIpAddressIn>(
673 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
678 VsmStatus Client::vsm_netdev_up(const char* id, const char* netdevId) noexcept
680 return coverException([&] {
684 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
685 api::ipc::METHOD_SET_NETDEV_ATTRS,
686 std::make_shared<api::SetNetDevAttrsIn>(
687 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(IFF_UP) },
688 { "change", to_string(IFF_UP) } } }));
692 VsmStatus Client::vsm_netdev_down(const char* id, const char* netdevId) noexcept
694 return coverException([&] {
698 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
699 api::ipc::METHOD_SET_NETDEV_ATTRS,
700 std::make_shared<api::SetNetDevAttrsIn>(
701 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(~IFF_UP) },
702 { "change", to_string(IFF_UP) } } }));
706 VsmStatus Client::vsm_create_netdev_veth(const char* id,
708 const char* hostDev) noexcept
710 return coverException([&] {
715 mClient->callSync<api::CreateNetDevVethIn, api::Void>(
716 api::ipc::METHOD_CREATE_NETDEV_VETH,
717 std::make_shared<api::CreateNetDevVethIn>(
718 api::CreateNetDevVethIn{ id, zoneDev, hostDev }));
722 VsmStatus Client::vsm_create_netdev_macvlan(const char* id,
725 enum macvlan_mode mode) noexcept
727 return coverException([&] {
732 mClient->callSync<api::CreateNetDevMacvlanIn, api::Void>(
733 api::ipc::METHOD_CREATE_NETDEV_MACVLAN,
734 std::make_shared<api::CreateNetDevMacvlanIn>(
735 api::CreateNetDevMacvlanIn{ id, zoneDev, hostDev, mode }));
739 VsmStatus Client::vsm_create_netdev_phys(const char* id, const char* devId) noexcept
741 return coverException([&] {
745 mClient->callSync<api::CreateNetDevPhysIn, api::Void>(
746 api::ipc::METHOD_CREATE_NETDEV_PHYS,
747 std::make_shared<api::CreateNetDevPhysIn>(
748 api::CreateNetDevPhysIn{ id, devId }));
752 VsmStatus Client::vsm_lookup_netdev_by_name(const char* id,
753 const char* netdevId,
754 Netdev* netdev) noexcept
756 using namespace boost::algorithm;
758 return coverException([&] {
763 api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
764 api::ipc::METHOD_GET_NETDEV_ATTRS,
765 std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
766 auto it = find_if(attrs.values.begin(),
768 [](const api::StringPair& entry) {
769 return entry.first == "type";
773 if (it == attrs.values.end()) {
774 throw OperationFailedException("Can't fetch netdev type");
777 switch (stoi(it->second)) {
778 case 1<<0 /*IFF_802_1Q_VLAN*/: type = VSMNETDEV_VETH; break;
779 case 1<<21 /*IFF_MACVLAN*/: type = VSMNETDEV_MACVLAN; break;
781 throw InvalidResponseException("Unknown netdev type: " + it->second);
784 *netdev = static_cast<Netdev>(malloc(sizeof(**netdev)));
785 (*netdev)->name = ::strdup(id);
786 (*netdev)->type = type;
790 VsmStatus Client::vsm_destroy_netdev(const char* id, const char* devId) noexcept
792 return coverException([&] {
796 mClient->callSync<api::DestroyNetDevIn, api::Void>(
797 api::ipc::METHOD_DESTROY_NETDEV,
798 std::make_shared<api::DestroyNetDevIn>(api::DestroyNetDevIn{ id, devId }));
802 VsmStatus Client::vsm_declare_file(const char* id,
807 VsmString* declarationId) noexcept
809 return coverException([&] {
813 api::Declaration declaration = *mClient->callSync<api::DeclareFileIn, api::Declaration>(
814 api::ipc::METHOD_DECLARE_FILE,
815 std::make_shared<api::DeclareFileIn>(
816 api::DeclareFileIn{ id, type, path, flags, (int)mode }));
817 if (declarationId != NULL) {
818 *declarationId = ::strdup(declaration.value.c_str());
823 VsmStatus Client::vsm_declare_mount(const char *source,
829 VsmString* declarationId) noexcept
831 return coverException([&] {
840 api::Declaration declaration = *mClient->callSync<api::DeclareMountIn, api::Declaration>(
841 api::ipc::METHOD_DECLARE_MOUNT,
842 std::make_shared<api::DeclareMountIn>(
843 api::DeclareMountIn{ source, id, target, type, flags, data }));
844 if (declarationId != NULL) {
845 *declarationId = ::strdup(declaration.value.c_str());
850 VsmStatus Client::vsm_declare_link(const char* source,
853 VsmString* declarationId) noexcept
855 return coverException([&] {
860 api::Declaration declaration = *mClient->callSync<api::DeclareLinkIn, api::Declaration>(
861 api::ipc::METHOD_DECLARE_LINK,
862 std::make_shared<api::DeclareLinkIn>(api::DeclareLinkIn{ source, id, target }));
863 if (declarationId != NULL) {
864 *declarationId = ::strdup(declaration.value.c_str());
869 VsmStatus Client::vsm_list_declarations(const char* id, VsmArrayString* declarations) noexcept
871 return coverException([&] {
873 IS_SET(declarations);
875 api::Declarations declarationsOut = *mClient->callSync<api::ZoneId, api::Declarations>(
876 api::ipc::METHOD_GET_DECLARATIONS,
877 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
878 convert(declarationsOut, *declarations);
882 VsmStatus Client::vsm_remove_declaration(const char* id, VsmString declaration) noexcept
884 return coverException([&] {
888 mClient->callSync<api::RemoveDeclarationIn, api::Void>(
889 api::ipc::METHOD_REMOVE_DECLARATION,
890 std::make_shared<api::RemoveDeclarationIn>(api::RemoveDeclarationIn{ id, declaration }));
894 VsmStatus Client::vsm_clean_up_zones_root() noexcept
896 return coverException([&] {
897 mClient->callSync<api::Void, api::Void>(
898 api::ipc::METHOD_CLEAN_UP_ZONES_ROOT,
899 std::make_shared<api::Void>());