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,
531 using namespace boost::algorithm;
533 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 auto it = find_if(attrs.values.begin(),
544 [type](const api::StringPair& entry) {
545 return entry.first == (type == AF_INET ? "ipv4" : "ipv6");
548 if (it != attrs.values.end()) {
549 vector<string> addrAttrs;
550 for(auto addrAttr : split(addrAttrs, it->second, is_any_of(","))) {
551 size_t pos = addrAttr.find(":");
552 if (addrAttr.substr(0, pos) == "ip") {
553 if (pos != string::npos && pos < addrAttr.length() &&
554 inet_pton(type, addrAttr.substr(pos + 1).c_str(), addr) == 1) {
555 //XXX: return only one address
558 throw InvalidResponseException("Wrong address format returned");
563 throw OperationFailedException("Address not found");
567 VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* id,
568 const char* netdevId,
569 struct in_addr* addr) noexcept
571 return vsm_netdev_get_ip_addr(id, netdevId, AF_INET, addr);
574 VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* id,
575 const char* netdevId,
576 struct in6_addr* addr) noexcept
578 return vsm_netdev_get_ip_addr(id, netdevId, AF_INET6, addr);
581 VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* id,
582 const char* netdevId,
583 struct in_addr* addr,
586 return coverException([&] {
591 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
592 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
593 api::ipc::METHOD_SET_NETDEV_ATTRS,
594 std::make_shared<api::SetNetDevAttrsIn>(
595 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv4", value } } }));
599 VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* id,
600 const char* netdevId,
601 struct in6_addr* addr,
604 return coverException([&] {
609 string value = "ip:" + toString(addr) + ",""prefixlen:" + to_string(prefix);
610 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
611 api::ipc::METHOD_SET_NETDEV_ATTRS,
612 std::make_shared<api::SetNetDevAttrsIn>(
613 api::SetNetDevAttrsIn{ id, netdevId, { { "ipv6", value } } }));
617 VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* id,
618 const char* netdevId,
619 struct in_addr* addr,
622 return coverException([&] {
628 string ip = toString(addr) + "/" + to_string(prefix);
629 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
630 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
631 std::make_shared<api::DeleteNetdevIpAddressIn>(
632 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
636 VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* id,
637 const char* netdevId,
638 struct in6_addr* addr,
641 return coverException([&] {
647 string ip = toString(addr) + "/" + to_string(prefix);
648 mClient->callSync<api::DeleteNetdevIpAddressIn, api::Void>(
649 api::ipc::METHOD_DELETE_NETDEV_IP_ADDRESS,
650 std::make_shared<api::DeleteNetdevIpAddressIn>(
651 api::DeleteNetdevIpAddressIn{ id, netdevId, ip }));
656 VsmStatus Client::vsm_netdev_up(const char* id, const char* netdevId) noexcept
658 return coverException([&] {
662 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
663 api::ipc::METHOD_SET_NETDEV_ATTRS,
664 std::make_shared<api::SetNetDevAttrsIn>(
665 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(IFF_UP) },
666 { "change", to_string(IFF_UP) } } }));
670 VsmStatus Client::vsm_netdev_down(const char* id, const char* netdevId) noexcept
672 return coverException([&] {
676 mClient->callSync<api::SetNetDevAttrsIn, api::Void>(
677 api::ipc::METHOD_SET_NETDEV_ATTRS,
678 std::make_shared<api::SetNetDevAttrsIn>(
679 api::SetNetDevAttrsIn{ id, netdevId, { { "flags", to_string(~IFF_UP) },
680 { "change", to_string(IFF_UP) } } }));
684 VsmStatus Client::vsm_create_netdev_veth(const char* id,
686 const char* hostDev) noexcept
688 return coverException([&] {
693 mClient->callSync<api::CreateNetDevVethIn, api::Void>(
694 api::ipc::METHOD_CREATE_NETDEV_VETH,
695 std::make_shared<api::CreateNetDevVethIn>(
696 api::CreateNetDevVethIn{ id, zoneDev, hostDev }));
700 VsmStatus Client::vsm_create_netdev_macvlan(const char* id,
703 enum macvlan_mode mode) noexcept
705 return coverException([&] {
710 mClient->callSync<api::CreateNetDevMacvlanIn, api::Void>(
711 api::ipc::METHOD_CREATE_NETDEV_MACVLAN,
712 std::make_shared<api::CreateNetDevMacvlanIn>(
713 api::CreateNetDevMacvlanIn{ id, zoneDev, hostDev, mode }));
717 VsmStatus Client::vsm_create_netdev_phys(const char* id, const char* devId) noexcept
719 return coverException([&] {
723 mClient->callSync<api::CreateNetDevPhysIn, api::Void>(
724 api::ipc::METHOD_CREATE_NETDEV_PHYS,
725 std::make_shared<api::CreateNetDevPhysIn>(
726 api::CreateNetDevPhysIn{ id, devId }));
730 VsmStatus Client::vsm_lookup_netdev_by_name(const char* id,
731 const char* netdevId,
732 Netdev* netdev) noexcept
734 using namespace boost::algorithm;
736 return coverException([&] {
741 api::GetNetDevAttrs attrs = *mClient->callSync<api::GetNetDevAttrsIn, api::GetNetDevAttrs>(
742 api::ipc::METHOD_GET_NETDEV_ATTRS,
743 std::make_shared<api::GetNetDevAttrsIn>(api::GetNetDevAttrsIn{ id, netdevId }));
744 auto it = find_if(attrs.values.begin(),
746 [](const api::StringPair& entry) {
747 return entry.first == "type";
751 if (it == attrs.values.end()) {
752 throw OperationFailedException("Can't fetch netdev type");
755 switch (stoi(it->second)) {
756 case 1<<0 /*IFF_802_1Q_VLAN*/: type = VSMNETDEV_VETH; break;
757 case 1<<21 /*IFF_MACVLAN*/: type = VSMNETDEV_MACVLAN; break;
759 throw InvalidResponseException("Unknown netdev type: " + it->second);
762 *netdev = static_cast<Netdev>(malloc(sizeof(**netdev)));
763 (*netdev)->name = ::strdup(id);
764 (*netdev)->type = type;
768 VsmStatus Client::vsm_destroy_netdev(const char* id, const char* devId) noexcept
770 return coverException([&] {
774 mClient->callSync<api::DestroyNetDevIn, api::Void>(
775 api::ipc::METHOD_DESTROY_NETDEV,
776 std::make_shared<api::DestroyNetDevIn>(api::DestroyNetDevIn{ id, devId }));
780 VsmStatus Client::vsm_declare_file(const char* id,
785 VsmString* declarationId) noexcept
787 return coverException([&] {
791 api::Declaration declaration = *mClient->callSync<api::DeclareFileIn, api::Declaration>(
792 api::ipc::METHOD_DECLARE_FILE,
793 std::make_shared<api::DeclareFileIn>(
794 api::DeclareFileIn{ id, type, path, flags, (int)mode }));
795 if (declarationId != NULL) {
796 *declarationId = ::strdup(declaration.value.c_str());
801 VsmStatus Client::vsm_declare_mount(const char *source,
807 VsmString* declarationId) noexcept
809 return coverException([&] {
818 api::Declaration declaration = *mClient->callSync<api::DeclareMountIn, api::Declaration>(
819 api::ipc::METHOD_DECLARE_MOUNT,
820 std::make_shared<api::DeclareMountIn>(
821 api::DeclareMountIn{ source, id, target, type, flags, data }));
822 if (declarationId != NULL) {
823 *declarationId = ::strdup(declaration.value.c_str());
828 VsmStatus Client::vsm_declare_link(const char* source,
831 VsmString* declarationId) noexcept
833 return coverException([&] {
838 api::Declaration declaration = *mClient->callSync<api::DeclareLinkIn, api::Declaration>(
839 api::ipc::METHOD_DECLARE_LINK,
840 std::make_shared<api::DeclareLinkIn>(api::DeclareLinkIn{ source, id, target }));
841 if (declarationId != NULL) {
842 *declarationId = ::strdup(declaration.value.c_str());
847 VsmStatus Client::vsm_list_declarations(const char* id, VsmArrayString* declarations) noexcept
849 return coverException([&] {
851 IS_SET(declarations);
853 api::Declarations declarationsOut = *mClient->callSync<api::ZoneId, api::Declarations>(
854 api::ipc::METHOD_GET_DECLARATIONS,
855 std::make_shared<api::ZoneId>(api::ZoneId{ id }));
856 convert(declarationsOut, *declarations);
860 VsmStatus Client::vsm_remove_declaration(const char* id, VsmString declaration) noexcept
862 return coverException([&] {
866 mClient->callSync<api::RemoveDeclarationIn, api::Void>(
867 api::ipc::METHOD_REMOVE_DECLARATION,
868 std::make_shared<api::RemoveDeclarationIn>(api::RemoveDeclarationIn{ id, declaration }));
872 VsmStatus Client::vsm_clean_up_zones_root() noexcept
874 return coverException([&] {
875 mClient->callSync<api::Void, api::Void>(
876 api::ipc::METHOD_CLEAN_UP_ZONES_ROOT,
877 std::make_shared<api::Void>());