From 476935e75959c057dcd506804cc873e29d30a425 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 2 Mar 2015 12:44:42 +0100 Subject: [PATCH 01/16] Ability to fetch information from netlink (list netdev) [Feature] Ability to fetch information from netlink, list netdevs [Cause] N/A [Solution] N/A [Verification] Build, run test, run cli command (zone_get_netdevs) Change-Id: I404f6c2c47b0d2882b94649c134981a09a978a52 --- common/netlink/netlink-message.cpp | 223 +++++++++++++++++++++++++++++------- common/netlink/netlink-message.hpp | 132 ++++++++++++++++++++- common/netlink/netlink.cpp | 161 ++++++++++++++++---------- common/netlink/netlink.hpp | 17 ++- server/netdev.cpp | 38 +++--- server/netdev.hpp | 2 + server/zone-admin.cpp | 2 +- tests/unit_tests/server/ut-zone.cpp | 19 ++- 8 files changed, 473 insertions(+), 121 deletions(-) diff --git a/common/netlink/netlink-message.cpp b/common/netlink/netlink-message.cpp index 9f33450..ac42c58 100644 --- a/common/netlink/netlink-message.cpp +++ b/common/netlink/netlink-message.cpp @@ -29,8 +29,10 @@ #include +#include #include #include +#include #include #include @@ -38,16 +40,15 @@ #include #include -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - namespace { -const int NLMSG_GOOD_SIZE = 2*PAGE_SIZE; -inline rtattr* NLMSG_TAIL(nlmsghdr* nmsg) +inline const rtattr* asAttr(const void* data) { return reinterpret_cast(data); } +inline const nlmsghdr* asHdr(const void* data) { return reinterpret_cast(data); } +inline rtattr* asAttr(void* data) { return reinterpret_cast(data); } +inline nlmsghdr* asHdr(void* data) { return reinterpret_cast(data); } +inline char* NLMSG_TAIL(nlmsghdr* nmsg) { - return reinterpret_cast(reinterpret_cast(nmsg) + NLMSG_ALIGN(nmsg->nlmsg_len)); + return reinterpret_cast(nmsg) + NLMSG_ALIGN(nmsg->nlmsg_len); } } // namespace @@ -55,10 +56,15 @@ inline rtattr* NLMSG_TAIL(nlmsghdr* nmsg) namespace vasum { namespace netlink { +NetlinkResponse send(const NetlinkMessage& msg) +{ + return send(msg, 0); +} + NetlinkMessage::NetlinkMessage(uint16_t type, uint16_t flags) { - static uint32_t seq = 0; - mNlmsg.resize(NLMSG_GOOD_SIZE, 0); + static std::atomic seq(0); + mNlmsg.resize(NLMSG_HDRLEN, 0); hdr().nlmsg_len = NLMSG_HDRLEN; hdr().nlmsg_flags = flags | NLM_F_ACK; hdr().nlmsg_type = type; @@ -68,18 +74,17 @@ NetlinkMessage::NetlinkMessage(uint16_t type, uint16_t flags) NetlinkMessage& NetlinkMessage::beginNested(int ifla) { - struct rtattr *nest = NLMSG_TAIL(&hdr()); + auto offset = std::distance(reinterpret_cast(&hdr()), NLMSG_TAIL(&hdr())); put(ifla, NULL, 0); - mNested.push(nest); + mNested.push(offset); return *this; } NetlinkMessage& NetlinkMessage::endNested() { assert(!mNested.empty()); - rtattr *nest = reinterpret_cast(mNested.top()); - nest->rta_len = std::distance(reinterpret_cast(nest), - reinterpret_cast(NLMSG_TAIL(&hdr()))); + rtattr* nest = asAttr(reinterpret_cast(&hdr()) + mNested.top()); + nest->rta_len = std::distance(reinterpret_cast(nest), NLMSG_TAIL(&hdr())); mNested.pop(); return *this; } @@ -96,7 +101,7 @@ NetlinkMessage& NetlinkMessage::put(int ifla, const void* data, int len) int newLen = NLMSG_ALIGN(hdr().nlmsg_len) + RTA_ALIGN(rtalen); setMinCapacity(newLen); - rta = NLMSG_TAIL(&hdr()); + rta = asAttr(NLMSG_TAIL(&hdr())); rta->rta_type = ifla; rta->rta_len = rtalen; memcpy(RTA_DATA(rta), data, len); @@ -113,11 +118,11 @@ NetlinkMessage& NetlinkMessage::put(const void* data, int len) } nlmsghdr& NetlinkMessage::hdr() { - return *reinterpret_cast(mNlmsg.data()); + return *asHdr(mNlmsg.data()); } const nlmsghdr& NetlinkMessage::hdr() const { - return *reinterpret_cast(mNlmsg.data()); + return *asHdr(mNlmsg.data()); } void NetlinkMessage::setMinCapacity(unsigned int size) @@ -127,41 +132,179 @@ void NetlinkMessage::setMinCapacity(unsigned int size) } } -void send(const NetlinkMessage& msg) +NetlinkResponse::NetlinkResponse(std::unique_ptr>&& message) + : mNlmsg(std::move(message)) + , mNlmsgHdr(asHdr(mNlmsg.get()->data())) + , mPosition(NLMSG_HDRLEN) { - //TODO: Handle messages with responses - assert(msg.hdr().nlmsg_flags & NLM_F_ACK); +} + +bool NetlinkResponse::hasMessage() const +{ + unsigned int tail = size() - getHdrPosition(); + bool hasHeader = NLMSG_OK(mNlmsgHdr, tail); + if (!hasHeader) { + return false; + } + //Check if isn't ACK message + return NLMSG_PAYLOAD(mNlmsgHdr,0) > sizeof(uint32_t); +} + +int NetlinkResponse::getMessageType() const +{ + return mNlmsgHdr->nlmsg_type; +} + +void NetlinkResponse::fetchNextMessage() +{ + if (mNlmsgHdr->nlmsg_type == NLMSG_DONE) { + throw VasumException("There is no next message"); + } + int tail = size() - mPosition; + mNlmsgHdr = NLMSG_NEXT(mNlmsgHdr, tail); + mPosition = getHdrPosition() + NLMSG_HDRLEN; +} + +bool NetlinkResponse::hasAttribute() const +{ + assert(mPosition >= getHdrPosition()); + int tail = mNlmsgHdr->nlmsg_len - (mPosition - getHdrPosition()); + return RTA_OK(asAttr(get(0)), tail); +} - const int answerLen = NLMSG_ALIGN(msg.hdr().nlmsg_len + sizeof(nlmsgerr)); - std::unique_ptr answerBuff(new char[answerLen]); - nlmsghdr* answer = reinterpret_cast(answerBuff.get()); - answer->nlmsg_len = answerLen; +bool NetlinkResponse::isNestedAttribute() const +{ + return asAttr(get(RTA_LENGTH(0)))->rta_len == RTA_LENGTH(0); +} + +void NetlinkResponse::skipAttribute() +{ + const rtattr *rta = asAttr(get(RTA_LENGTH(0))); + if (size() < mPosition + RTA_ALIGN(rta->rta_len)) { + LOGE("Skipping out of buffer:" + << " to: " << mPosition + RTA_ALIGN(rta->rta_len) + << ", buf size: " << size()); + throw VasumException("Skipping out of buffer"); + } + seek(RTA_ALIGN(rta->rta_len)); +} + +NetlinkResponse& NetlinkResponse::openNested(int ifla) +{ + const rtattr *rta = asAttr(get(RTA_LENGTH(0))); + if (rta->rta_type == ifla) { + LOGE("Wrong attribute type, expected: " << ifla << ", got: " << rta->rta_type); + throw VasumException("Wrong attribute type"); + } + int pos = mPosition; + seek(RTA_LENGTH(0)); + mNested.push(pos); + return *this; +} + +NetlinkResponse& NetlinkResponse::closeNested() +{ + assert(!mNested.empty()); + int pos = mNested.top(); + const rtattr *rta = asAttr(mNlmsg->data() + pos); + if (rta->rta_len != mPosition - pos) { + LOGE("There is no nested attribute end. Did you read all attributes (read: " + << mPosition - pos << ", length: " << rta->rta_len); + throw VasumException("There is no nested attribute end"); + } + mNested.pop(); + mPosition = pos; + return *this; +} +NetlinkResponse& NetlinkResponse::fetch(int ifla, std::string& value, int maxSize) +{ + value = std::string(get(ifla, maxSize)); + skipAttribute(); + return *this; +} + +const char* NetlinkResponse::get(int ifla, int len) const +{ + const rtattr *rta = asAttr(get(RTA_LENGTH(len < 0 ? 0 : len))); + if (rta->rta_type != ifla) { + LOGE("Wrong attribute type, expected:" << ifla << ", got: " << rta->rta_type); + throw VasumException("Wrong attribute type"); + } + if (len >= 0 && rta->rta_len != RTA_LENGTH(len)) { + LOGE("Wrong attribute length, expected: " << rta->rta_len + ", got " << len); + throw VasumException("Wrong attribute length"); + } + return reinterpret_cast(RTA_DATA(get(rta->rta_len))); +} + +const char* NetlinkResponse::get(int len) const +{ + if (size() < mPosition + len) { + LOGE("Read out of buffer:" + << " from: " << mPosition + len + << ", buf size: " << size()); + throw VasumException("Read out of buffer"); + } + return mNlmsg->data() + mPosition; +} + +NetlinkResponse& NetlinkResponse::fetch(int ifla, char* data, int len) +{ + std::copy_n(get(ifla, len), len, data); + skipAttribute(); + return *this; +} + +NetlinkResponse& NetlinkResponse::fetch(char* data, int len) +{ + std::copy_n(get(len), len, data); + seek(len); + return *this; +} + +int NetlinkResponse::getAttributeType() const +{ + return asAttr(get(RTA_LENGTH(0)))->rta_type; +} + +NetlinkResponse& NetlinkResponse::seek(int len) +{ + if (size() < mPosition + len) { + throw VasumException("Skipping out of buffer"); + } + mPosition += len; + return *this; +} + +int NetlinkResponse::size() const +{ + return mNlmsg->size(); +} + +inline int NetlinkResponse::getHdrPosition() const +{ + return std::distance(reinterpret_cast(mNlmsg->data()), + reinterpret_cast(mNlmsgHdr)); +} + +NetlinkResponse send(const NetlinkMessage& msg, int pid) +{ + assert(msg.hdr().nlmsg_flags & NLM_F_ACK); + + std::unique_ptr> data; Netlink nl; - nl.open(); + nl.open(pid); try { nl.send(&msg.hdr()); - //Receive ACK Netlink Message - do { - nl.rcv(answer); - } while (answer->nlmsg_type == NLMSG_NOOP); + data = nl.rcv(msg.hdr().nlmsg_seq); } catch (const std::exception& ex) { LOGE("Sending failed (" << ex.what() << ")"); nl.close(); throw; } nl.close(); - if (answer->nlmsg_type != NLMSG_ERROR) { - // It is not NACK/ACK message - throw VasumException("Sending failed ( unrecognized message type )"); - } - nlmsgerr *err = reinterpret_cast(NLMSG_DATA(answer)); - if (answer->nlmsg_seq != msg.hdr().nlmsg_seq) { - throw VasumException("Sending failed ( answer message was mismatched )"); - } - if (err->error) { - throw VasumException("Sending failed (" + getSystemErrorMessage(-err->error) + ")"); - } + return NetlinkResponse(std::move(data)); } } // namespace netlink diff --git a/common/netlink/netlink-message.hpp b/common/netlink/netlink-message.hpp index e828feb..6b84de4 100644 --- a/common/netlink/netlink-message.hpp +++ b/common/netlink/netlink-message.hpp @@ -25,6 +25,7 @@ #ifndef COMMON_NETLINK_NETLINK_MESSAGE_HPP #define COMMON_NETLINK_NETLINK_MESSAGE_HPP +#include #include #include #include @@ -35,6 +36,9 @@ namespace vasum { namespace netlink { +class NetlinkResponse; +class NetlinkMessage; + /** * NetlinkMessage is used to creatie a netlink messages */ @@ -81,21 +85,124 @@ public: * Send netlink message * * It is not thread safe + * @param msg Netlink message + * @param pid Process id which describes network namespace */ - friend void send(const NetlinkMessage& msg); + friend NetlinkResponse send(const NetlinkMessage& msg, int pid); private: std::vector mNlmsg; - std::stack mNested; + std::stack mNested; NetlinkMessage& put(int ifla, const void* data, int len); NetlinkMessage& put(const void* data, int len); nlmsghdr& hdr(); const nlmsghdr& hdr() const; void setMinCapacity(unsigned int size); +}; + +/** + * NetlinkResponse is used to read netlink messages + */ +class NetlinkResponse { +public: + /** + * Check if theres is next message in netlink response + */ + bool hasMessage() const; + + /** + * Fetch next message + */ + void fetchNextMessage(); + /** + * Get message type + */ + int getMessageType() const; + /** + * Check if there is any attribute in message + */ + bool hasAttribute() const; + + /** + * Check if current attribute is nested + */ + bool isNestedAttribute() const; + + /** + * Skip attribute + */ + void skipAttribute(); + + /** + * Start reading nested attribute + */ + NetlinkResponse& openNested(int ifla); + + /** + * End reading nested attribute + */ + NetlinkResponse& closeNested(); + + ///@{ + /** + * Fetch attribute + */ + NetlinkResponse& fetch(int ifla, std::string& value, int maxSize = std::string::npos); + template + NetlinkResponse& fetch(int ifla, T& value); + ///@} + + /** + * Get attributie type + **/ + int getAttributeType() const; + + /** + * Fetch data of type T + */ + template + NetlinkResponse& fetch(T& value); + + /** + * Skip data of type T + */ + template + NetlinkResponse& skip(); + + /** + * Send netlink message + * + * It is not thread safe + * @param msg Netlink message + * @param pid Process id which describes network namespace + */ + friend NetlinkResponse send(const NetlinkMessage& msg, int pid); +private: + NetlinkResponse(std::unique_ptr>&& message); + + std::unique_ptr> mNlmsg; + std::stack mNested; + nlmsghdr* mNlmsgHdr; + int mPosition; + + const char* get(int ifla, int iflasize) const; + const char* get(int size = 0) const; + NetlinkResponse& fetch(int ifla, char* data, int len); + NetlinkResponse& fetch(char* data, int len); + NetlinkResponse& seek(int len); + int size() const; + int getHdrPosition() const; }; +/** + * Send netlink message + * + * It is not thread safe + */ +NetlinkResponse send(const NetlinkMessage& msg); + template NetlinkMessage& NetlinkMessage::put(int ifla, const T& value) { @@ -110,6 +217,27 @@ NetlinkMessage& NetlinkMessage::put(const T& value) return put(&value, sizeof(value)); } +template +NetlinkResponse& NetlinkResponse::fetch(int ifla, T& value) +{ + static_assert(std::is_pod::value, "Require trivial and standard-layout"); + return fetch(ifla, reinterpret_cast(&value), sizeof(value)); +} + +template +NetlinkResponse& NetlinkResponse::fetch(T& value) +{ + static_assert(std::is_pod::value, "Require trivial and standard-layout structure"); + return fetch(reinterpret_cast(&value), sizeof(value)); +} + +template +NetlinkResponse& NetlinkResponse::skip() +{ + static_assert(std::is_pod::value, "Require trivial and standard-layout structure"); + return seek(sizeof(T)); +} + } // namespace netlink } // namespace vasum diff --git a/common/netlink/netlink.cpp b/common/netlink/netlink.cpp index fa86b45..e5cf8a7 100644 --- a/common/netlink/netlink.cpp +++ b/common/netlink/netlink.cpp @@ -26,6 +26,8 @@ #include "netlink.hpp" #include "utils.hpp" #include "base-exception.hpp" +#include "utils/make-clean.hpp" +#include "utils/environment.hpp" #include #include @@ -34,21 +36,54 @@ #include #include -namespace vasum { +#ifndef PAGE_SIZE +#define PAGE_SIZE 4096 +#endif + +using namespace vasum; namespace { -template -T make_clean() +const int NLMSG_RCV_GOOD_SIZE = 2*PAGE_SIZE; + +int vsm_recvmsg(int fd, struct msghdr *msg, int flags) { - static_assert(std::is_pod::value, "make_clean require trivial and standard-layout"); - T value; - std::fill_n(reinterpret_cast(&value), sizeof(value), 0); - return value; + int ret = recvmsg(fd, msg, flags); + if (ret < 0) { + LOGE("Can't receive message: " + getSystemErrorMessage()); + } else if (ret == 0 && msg->msg_iov && msg->msg_iov->iov_len > 0) { + LOGE("Peer has performed an orderly shutdown"); + } else if (msg->msg_flags & MSG_TRUNC) { + LOGE("Can't receive message: " + getSystemErrorMessage(EMSGSIZE)); + } else if (msg->msg_flags & MSG_ERRQUEUE) { + LOGE("No data was received but an extended error"); + } else if (msg->msg_flags & MSG_OOB) { + LOGE("Internal error (expedited or out-of-band data were received)"); + } else if (msg->msg_flags & MSG_CTRUNC) { + LOGE("Some control data were discarded"); + } else if (msg->msg_flags & MSG_EOR) { + LOGE("End-of-record"); + } else { + // All ok + return ret; + } + throw VasumException("Can't receive netlink message"); +} + +void vsm_sendmsg(int fd, const struct msghdr *msg, int flags) +{ + int ret = sendmsg(fd, msg, flags); + if (ret < 0) { + LOGE("Can't send message: " << getSystemErrorMessage()); + throw VasumException("Can't send netlink message"); + } } } // namespace +namespace vasum { +namespace netlink { + Netlink::Netlink() : mFd(-1) { } @@ -58,22 +93,30 @@ Netlink::~Netlink() close(); } -void Netlink::open() +void Netlink::open(int netNsPid) { + auto fdFactory = []{ return socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); }; + assert(mFd == -1); - mFd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (netNsPid == 0 || netNsPid == getpid()) { + mFd = fdFactory(); + if (mFd == -1) { + LOGE("Can't open socket: " << getSystemErrorMessage()); + } + } else { + mFd = utils::passNemaspacedFd(netNsPid, CLONE_NEWNET, fdFactory); + } if (mFd == -1) { - LOGE("Can't open socket (" << getSystemErrorMessage() << ")"); throw VasumException("Can't open netlink connection"); } - sockaddr_nl local = make_clean(); + sockaddr_nl local = utils::make_clean(); local.nl_family = AF_NETLINK; if (bind(mFd, (struct sockaddr *)&local, sizeof(local)) < 0) { int err = errno; close(); - LOGE("Can't bind to socket (" << getSystemErrorMessage(err) << ")"); + LOGE("Can't bind to socket: " << getSystemErrorMessage(err)); throw VasumException("Can't set up netlink connection"); } } @@ -86,70 +129,72 @@ void Netlink::close() } } -void Netlink::send(const nlmsghdr *nlmsg) +unsigned int Netlink::send(const void *nlmsg) { - msghdr msg = make_clean(); - sockaddr_nl nladdr = make_clean(); - iovec iov = make_clean(); + msghdr msg = utils::make_clean(); + sockaddr_nl nladdr = utils::make_clean(); + iovec iov = utils::make_clean(); - iov.iov_base = (void *)nlmsg; - iov.iov_len = nlmsg->nlmsg_len; + iov.iov_base = const_cast(nlmsg); + iov.iov_len = reinterpret_cast(nlmsg)->nlmsg_len; msg.msg_name = &nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; nladdr.nl_family = AF_NETLINK; - int ret = sendmsg(mFd, &msg, 0); - if (ret < 0) { - LOGE("Can't send message (" << getSystemErrorMessage() << ")"); - throw VasumException("Can't send netlink message"); - } + vsm_sendmsg(mFd, &msg, 0); + return reinterpret_cast(nlmsg)->nlmsg_seq; } -int Netlink::rcv(nlmsghdr *answer) +std::unique_ptr> Netlink::rcv(unsigned int nlmsgSeq) { - //TODO: Handle too small buffer situation (buffer resizing) - msghdr msg = make_clean(); - sockaddr_nl nladdr = make_clean(); - iovec iov = make_clean(); + std::unique_ptr> buf(new std::vector()); + + msghdr msg = utils::make_clean(); + sockaddr_nl nladdr = utils::make_clean(); + iovec iov = utils::make_clean(); - iov.iov_base = answer; - iov.iov_len = answer->nlmsg_len; msg.msg_name = &nladdr; msg.msg_namelen = sizeof(nladdr); msg.msg_iov = &iov; msg.msg_iovlen = 1; nladdr.nl_family = AF_NETLINK; - int ret = recvmsg(mFd, &msg, 0); - if (ret < 0) { - LOGE("Can't receive message (" + getSystemErrorMessage() + ")"); - throw VasumException("Can't receive netlink message"); - } - if (ret == 0) { - LOGE("Peer has performed an orderly shutdown"); - throw VasumException("Can't receive netlink message"); - } - if (msg.msg_flags & MSG_TRUNC) { - LOGE("Can't receive message (" + getSystemErrorMessage(EMSGSIZE) + ")"); - throw VasumException("Can't receive netlink message"); - } - if (msg.msg_flags & MSG_ERRQUEUE) { - LOGE("No data was received but an extended error"); - throw VasumException("Can't receive netlink message"); - } - if (msg.msg_flags & MSG_OOB) { - LOGE("Internal error (expedited or out-of-band data were received)"); - throw VasumException("Can't receive netlink message"); - } - if (msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) { - assert(!"This should not happen!"); - LOGE("Internal error (" << std::to_string(msg.msg_flags) << ")"); - throw VasumException("Internal error while recaiving netlink message"); - } - - return ret; + nlmsghdr* answer; + nlmsghdr* lastOk = NULL; + size_t offset = 0; + do { + buf->resize(offset + NLMSG_RCV_GOOD_SIZE); + answer = reinterpret_cast(buf->data() + offset); + iov.iov_base = answer; + iov.iov_len = buf->size() - offset; + unsigned int ret = vsm_recvmsg(mFd, &msg, 0); + for (unsigned int len = ret; NLMSG_OK(answer, len); answer = NLMSG_NEXT(answer, len)) { + lastOk = answer; + if (answer->nlmsg_type == NLMSG_ERROR) { + // It is NACK/ACK message + nlmsgerr *err = reinterpret_cast(NLMSG_DATA(answer)); + if (answer->nlmsg_seq != nlmsgSeq) { + throw VasumException("Sending failed: answer message was mismatched"); + } + if (err->error) { + throw VasumException("Sending failed: " + getSystemErrorMessage(-err->error)); + } + } else if (answer->nlmsg_type == NLMSG_OVERRUN) { + throw VasumException("Sending failed: data lost"); + } + } + if (lastOk == NULL) { + LOGE("Something went terribly wrong. Check vsm_recvmsg function"); + throw VasumException("Can't receive data from system"); + } + offset += NLMSG_ALIGN(ret); + } while (lastOk->nlmsg_type != NLMSG_DONE && lastOk->nlmsg_flags & NLM_F_MULTI); + + buf->resize(offset); + return buf; } +} //namespace netlink } //namespace vasum diff --git a/common/netlink/netlink.hpp b/common/netlink/netlink.hpp index 2e73ce8..8d33957 100644 --- a/common/netlink/netlink.hpp +++ b/common/netlink/netlink.hpp @@ -25,9 +25,11 @@ #ifndef COMMON_NETLINK_NETLINK_HPP #define COMMON_NETLINK_NETLINK_HPP -#include +#include +#include namespace vasum { +namespace netlink { /** * Netlink class is responsible for communicating @@ -43,8 +45,10 @@ public: /** * Open connnection + * + * @param netNsPid pid which defines net namespace */ - void open(); + void open(int netNsPid = 0); /** * Close connection @@ -58,8 +62,9 @@ public: * different instances at the same time * * @param nlmsg pointer to message + * @return sequence number */ - void send(const nlmsghdr *nlmsg); + unsigned int send(const void* nlmsg); /** * Receive message @@ -67,13 +72,15 @@ public: * It is not thread safe and even you shouldn't call this function on * different instances at the same time * - * @param answer pointer to answer buffer + * @param nlmsgSeq sequence number + * @return received data */ - int rcv(nlmsghdr *answer); + std::unique_ptr> rcv(unsigned int nlmsgSeq); private: int mFd; }; +} // namesapce netlink } // namespace vasum #endif /* COMMON_NETLINK_NETLINK_HPP */ diff --git a/server/netdev.cpp b/server/netdev.cpp index b4a2d21..f8f9264 100644 --- a/server/netdev.cpp +++ b/server/netdev.cpp @@ -25,6 +25,7 @@ #include "config.hpp" #include "netdev.hpp" #include "netlink/netlink-message.hpp" +#include "utils/make-clean.hpp" #include "utils.hpp" #include "exception.hpp" @@ -55,15 +56,6 @@ namespace netdev { namespace { -template -T make_clean() -{ - static_assert(std::is_pod::value, "make_clean require trivial and standard-layout"); - T value; - std::fill_n(reinterpret_cast(&value), sizeof(value), 0); - return value; -} - string getUniqueVethName() { auto find = [](const ifaddrs* ifaddr, const string& name) -> bool { @@ -109,7 +101,7 @@ void createPipedNetdev(const string& netdev1, const string& netdev2) validateNetdevName(netdev2); NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); - ifinfomsg infoPeer = make_clean(); + ifinfomsg infoPeer = utils::make_clean(); infoPeer.ifi_family = AF_UNSPEC; infoPeer.ifi_change = 0xFFFFFFFF; nlm.put(infoPeer) @@ -138,7 +130,7 @@ void attachToBridge(const string& bridge, const string& netdev) throw ZoneOperationException("Can't attach to bridge"); } - struct ifreq ifr = make_clean(); + struct ifreq ifr = utils::make_clean(); strncpy(ifr.ifr_name, bridge.c_str(), IFNAMSIZ); ifr.ifr_ifindex = index; int err = ioctl(fd, SIOCBRADDIF, &ifr); @@ -156,7 +148,7 @@ int setFlags(const string& name, uint32_t mask, uint32_t flags) { uint32_t index = getInterfaceIndex(name); NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); - ifinfomsg infoPeer = make_clean(); + ifinfomsg infoPeer = utils::make_clean(); infoPeer.ifi_family = AF_UNSPEC; infoPeer.ifi_index = index; infoPeer.ifi_flags = flags; @@ -176,7 +168,7 @@ void moveToNS(const string& netdev, pid_t pid) { uint32_t index = getInterfaceIndex(netdev); NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK); - ifinfomsg infopeer = make_clean(); + ifinfomsg infopeer = utils::make_clean(); infopeer.ifi_family = AF_UNSPEC; infopeer.ifi_index = index; nlm.put(infopeer) @@ -191,7 +183,7 @@ void createMacvlan(const string& master, const string& slave, const macvlan_mode uint32_t index = getInterfaceIndex(master); NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK); - ifinfomsg infopeer = make_clean(); + ifinfomsg infopeer = utils::make_clean(); infopeer.ifi_family = AF_UNSPEC; infopeer.ifi_change = 0xFFFFFFFF; nlm.put(infopeer) @@ -237,6 +229,24 @@ void movePhys(const pid_t& nsPid, const string& devId) moveToNS(devId, nsPid); } +std::vector listNetdev(const pid_t& nsPid) +{ + NetlinkMessage nlm(RTM_GETLINK, NLM_F_REQUEST|NLM_F_DUMP|NLM_F_ROOT); + ifinfomsg info = utils::make_clean(); + info.ifi_family = AF_PACKET; + nlm.put(info); + NetlinkResponse response = send(nlm, nsPid); + std::vector interfaces; + while (response.hasMessage()) { + std::string ifName; + response.skip(); + response.fetch(IFLA_IFNAME, ifName); + interfaces.push_back(ifName); + response.fetchNextMessage(); + } + return interfaces; +} + } //namespace netdev } //namespace vasum diff --git a/server/netdev.hpp b/server/netdev.hpp index de761ca..b3d658a 100644 --- a/server/netdev.hpp +++ b/server/netdev.hpp @@ -26,6 +26,7 @@ #define SERVER_NETDEV_HPP #include +#include #include #include @@ -38,6 +39,7 @@ void createMacvlan(const pid_t& nsPid, const std::string& hostDev, const macvlan_mode& mode); void movePhys(const pid_t& nsPid, const std::string& devId); +std::vector listNetdev(const pid_t& nsPid); } //namespace netdev } //namespace vasum diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index 8005fb4..64092a8 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -314,7 +314,7 @@ ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& /* netdev */ std::vector ZoneAdmin::getNetdevList() { - throw ZoneOperationException("Not implemented"); + return netdev::listNetdev(mZone.getInitPid()); } } // namespace vasum diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index 37f65be..a8b608f 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -33,13 +33,13 @@ #include "utils/glib-loop.hpp" #include "utils/scoped-dir.hpp" #include "config/exception.hpp" +#include "netdev.hpp" #include #include #include #include - using namespace vasum; using namespace config; @@ -126,5 +126,22 @@ BOOST_AUTO_TEST_CASE(DbusConnectionTest) // TODO: DbusReconnectionTest +BOOST_AUTO_TEST_CASE(ListNetdevTest) +{ + typedef std::vector NetdevList; + + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + // Depending on the kernel configuration there can be lots of interfaces (f.e. sit0, ip6tnl0) + NetdevList netdevs = c->getNetdevList(); + // Check if there is mandatory loopback interface + BOOST_CHECK(find(netdevs.begin(), netdevs.end(), "lo") != netdevs.end()); + NetdevList hostNetdevs = netdev::listNetdev(0); + // Check if we get interfaces from zone net namespace + BOOST_CHECK(hostNetdevs != netdevs); + + c->stop(false); +} BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 5a16448719fc2b94c103becb4dc3d523dda5372a Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 3 Mar 2015 16:01:44 +0100 Subject: [PATCH 02/16] Add destroyNetdev, createBridge and tests for netdev [Feature] Add destroyNetdev, createBridge, CreateNetdevVethTest, CreateNetdevMacvlanTest [Cause] N/A [Solution] Netlink interface [Verification] Build, run test Change-Id: Iba17d864158d35d71d2fae83742ef13d729d5a7f --- cli/command-line-interface.cpp | 13 +++++++ cli/command-line-interface.hpp | 7 ++++ cli/main.cpp | 9 +++++ client/vasum-client-impl.cpp | 6 +-- server/host-connection.cpp | 15 +++++++ server/host-connection.hpp | 10 +++++ server/host-dbus-definitions.hpp | 5 +++ server/netdev.cpp | 78 +++++++++++++++++++++++++++++++++---- server/netdev.hpp | 12 +++++- server/zone-admin.cpp | 5 +++ server/zone-admin.hpp | 5 +++ server/zone.cpp | 6 +++ server/zone.hpp | 5 +++ server/zones-manager.cpp | 22 +++++++++++ server/zones-manager.hpp | 3 ++ tests/unit_tests/server/ut-zone.cpp | 65 +++++++++++++++++++++++++++++++ 16 files changed, 255 insertions(+), 11 deletions(-) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index ecf6b9c..100aaa1 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -397,6 +397,19 @@ void create_netdev_phys(int pos, int argc, const char** argv) argv[pos + 2])); } +void destroy_netdev(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 2) { + throw runtime_error("Not enough parameters"); + } + one_shot(bind(vsm_destroy_netdev, + _1, + argv[pos + 1], + argv[pos + 2])); +} + void zone_get_netdevs(int pos, int argc, const char** argv) { using namespace std::placeholders; diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index eb33428..006396c 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -209,6 +209,13 @@ void create_netdev_macvlan(int pos, int argc, const char** argv); void create_netdev_phys(int pos, int argc, const char** argv); /** + * Parses command line arguments and call vsm_destroy_netdev + * + * @see vsm_destroy_netdev + */ +void destroy_netdev(int pos, int argc, const char** argv); + +/** * Parses command line arguments and prints result of vsm_zone_get_netdevs * * @see vsm_zone_get_netdevs diff --git a/cli/main.cpp b/cli/main.cpp index a30146e..c915415 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -173,6 +173,15 @@ std::map commands = { } }, { + "destroy_netdev", { + destroy_netdev, + "destroy_netdev zone_id devId", + "Destroy netdev in zone", + {{"zone_id", "id zone name"}, + {"devId", "network device id"}} + } + }, + { "zone_get_netdevs", { zone_get_netdevs, "zone_get_netdevs zone_id", diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 1ac4c3c..fb1b2ec 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -768,10 +768,10 @@ VsmStatus Client::vsm_lookup_netdev_by_name(const char*, const char*, VsmNetdev* return vsm_get_status(); } -VsmStatus Client::vsm_destroy_netdev(const char*, const char*) noexcept +VsmStatus Client::vsm_destroy_netdev(const char* zone, const char* devId) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); - return vsm_get_status(); + GVariant* args_in = g_variant_new("(ss)", zone, devId); + return callMethod(HOST_INTERFACE, api::host::METHOD_DESTROY_NETDEV, args_in); } VsmStatus Client::vsm_declare_file(const char* zone, diff --git a/server/host-connection.cpp b/server/host-connection.cpp index a1a7448..d0b612a 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -162,6 +162,11 @@ void HostConnection::setCreateNetdevPhysCallback(const CreateNetdevPhysCallback& mCreateNetdevPhysCallback = callback; } +void HostConnection::setDestroyNetdevCallback(const DestroyNetdevCallback& callback) +{ + mDestroyNetdevCallback = callback; +} + void HostConnection::setDeclareFileCallback(const DeclareFileCallback& callback) { mDeclareFileCallback = callback; @@ -393,6 +398,16 @@ void HostConnection::onMessageCall(const std::string& objectPath, } } + if (methodName == api::host::METHOD_DESTROY_NETDEV) { + const gchar* id = NULL; + const gchar* devId = NULL; + g_variant_get(parameters, "(&s&s)", &id, &devId); + if (mDestroyNetdevCallback) { + auto rb = std::make_shared>(result); + mDestroyNetdevCallback(id, devId, rb); + } + } + if (methodName == api::host::METHOD_DECLARE_FILE) { const gchar* zone; int32_t type; diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 3ef8cdf..0ef9585 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -90,6 +90,10 @@ public: const std::string& devId, api::MethodResultBuilder::Pointer result )> CreateNetdevPhysCallback; + typedef std::function DestroyNetdevCallback; typedef std::function" " " + " " + " " + " " + " " " " " " " " diff --git a/server/netdev.cpp b/server/netdev.cpp index f8f9264..e17ecda 100644 --- a/server/netdev.cpp +++ b/server/netdev.cpp @@ -46,6 +46,17 @@ #include #include #include +#include +#include + +//IFLA_BRIDGE_FLAGS and BRIDGE_FLAGS_MASTER +//should be defined in linux/if_bridge.h since kernel v3.7 +#ifndef IFLA_BRIDGE_FLAGS +#define IFLA_BRIDGE_FLAGS 0 +#endif +#ifndef BRIDGE_FLAGS_MASTER +#define BRIDGE_FLAGS_MASTER 1 +#endif using namespace std; using namespace vasum; @@ -205,10 +216,18 @@ void createVeth(const pid_t& nsPid, const string& nsDev, const string& hostDev) string hostVeth = getUniqueVethName(); LOGT("Creating veth: bridge: " << hostDev << ", port: " << hostVeth << ", zone: " << nsDev); createPipedNetdev(nsDev, hostVeth); - //TODO: clean up if following instructions fail - attachToBridge(hostDev, hostVeth); - up(hostVeth); - moveToNS(nsDev, nsPid); + try { + attachToBridge(hostDev, hostVeth); + up(hostVeth); + moveToNS(nsDev, nsPid); + } catch(const exception& ex) { + try { + destroyNetdev(hostVeth); + } catch (const exception& ex) { + LOGE("Can't destroy netdev pipe: " << hostVeth << ", " << nsDev); + } + throw; + } } void createMacvlan(const pid_t& nsPid, @@ -218,9 +237,17 @@ void createMacvlan(const pid_t& nsPid, { LOGT("Creating macvlan: host: " << hostDev << ", zone: " << nsDev << ", mode: " << mode); createMacvlan(hostDev, nsDev, mode); - //TODO: clean up if following instructions fail - up(nsDev); - moveToNS(nsDev, nsPid); + try { + up(nsDev); + moveToNS(nsDev, nsPid); + } catch(const exception& ex) { + try { + destroyNetdev(nsDev); + } catch (const exception& ex) { + LOGE("Can't destroy netdev: " << nsDev); + } + throw; + } } void movePhys(const pid_t& nsPid, const string& devId) @@ -247,6 +274,43 @@ std::vector listNetdev(const pid_t& nsPid) return interfaces; } +void destroyNetdev(const string& netdev, const pid_t pid) +{ + LOGT("Destroying netdev: " << netdev); + validateNetdevName(netdev); + + NetlinkMessage nlm(RTM_DELLINK, NLM_F_REQUEST|NLM_F_ACK); + ifinfomsg infopeer = utils::make_clean(); + infopeer.ifi_family = AF_UNSPEC; + infopeer.ifi_change = 0xFFFFFFFF; + nlm.put(infopeer) + .put(IFLA_IFNAME, netdev); + send(nlm, pid); +} + +void createBridge(const string& netdev) +{ + LOGT("Creating bridge: " << netdev); + validateNetdevName(netdev); + + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK); + ifinfomsg infoPeer = utils::make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_change = 0xFFFFFFFF; + nlm.put(infoPeer) + .beginNested(IFLA_LINKINFO) + .put(IFLA_INFO_KIND, "bridge") + .beginNested(IFLA_INFO_DATA) + .beginNested(IFLA_AF_SPEC) + .put(IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_MASTER) + .endNested() + .endNested() + .endNested() + .put(IFLA_IFNAME, netdev); + send(nlm); +} + + } //namespace netdev } //namespace vasum diff --git a/server/netdev.hpp b/server/netdev.hpp index b3d658a..0e9bfde 100644 --- a/server/netdev.hpp +++ b/server/netdev.hpp @@ -39,7 +39,17 @@ void createMacvlan(const pid_t& nsPid, const std::string& hostDev, const macvlan_mode& mode); void movePhys(const pid_t& nsPid, const std::string& devId); -std::vector listNetdev(const pid_t& nsPid); +std::vector listNetdev(const pid_t& nsPid = 0); +void destroyNetdev(const std::string& netdev, const pid_t pid = 0); + +/** + * Create bridge + * + * Bridge are in BRIDGE_MODE_VEB (loopback) mode and it is software bridge (BRIDGE_FLAGS_MASTER) + * + * @param netdev bridge name + */ +void createBridge(const std::string& netdev); } //namespace netdev } //namespace vasum diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index 64092a8..29577f8 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -302,6 +302,11 @@ void ZoneAdmin::moveNetdev(const std::string& devId) netdev::movePhys(mZone.getInitPid(), devId); } +void ZoneAdmin::destroyNetdev(const std::string& devId) +{ + netdev::destroyNetdev(devId, mZone.getInitPid()); +} + void ZoneAdmin::setNetdevAttrs(const std::string& /* netdev */, const NetdevAttrs& /* attrs */) { throw ZoneOperationException("Not implemented"); diff --git a/server/zone-admin.hpp b/server/zone-admin.hpp index ade4585..c6d26f0 100644 --- a/server/zone-admin.hpp +++ b/server/zone-admin.hpp @@ -150,6 +150,11 @@ public: void moveNetdev(const std::string& devId); /** + * Destroy network device in zone + */ + void destroyNetdev(const std::string& devId); + + /** * Set network device attributes */ void setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs); diff --git a/server/zone.cpp b/server/zone.cpp index 181cc9e..b0c3c28 100644 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -278,6 +278,12 @@ void Zone::moveNetdev(const std::string& devId) mAdmin->moveNetdev(devId); } +void Zone::destroyNetdev(const std::string& devId) +{ + Lock lock(mReconnectMutex); + mAdmin->destroyNetdev(devId); +} + void Zone::goForeground() { Lock lock(mReconnectMutex); diff --git a/server/zone.hpp b/server/zone.hpp index 45bacbd..b981e9a 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -292,6 +292,11 @@ public: void moveNetdev(const std::string& devId); /** + * Destroy network device in zone + */ + void destroyNetdev(const std::string& devId); + + /** * Set network device attributes */ void setNetdevAttrs(const std::string& netdev, const ZoneAdmin::NetdevAttrs& attrs); diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 2dcfaa0..4266820 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -160,6 +160,9 @@ ZonesManager::ZonesManager(const std::string& configPath) mHostConnection.setCreateNetdevPhysCallback(bind(&ZonesManager::handleCreateNetdevPhysCall, this, _1, _2, _3)); + mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, + this, _1, _2, _3)); + mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, this, _1, _2, _3, _4, _5, _6)); @@ -927,6 +930,25 @@ void ZonesManager::handleCreateNetdevPhysCall(const std::string& zone, } } +void ZonesManager::handleDestroyNetdevCall(const std::string& zone, + const std::string& devId, + api::MethodResultBuilder::Pointer result) +{ + LOGI("DestroyNetdev call"); + try { + Lock lock(mMutex); + + getZone(zone).destroyNetdev(devId); + result->setVoid(); + } catch (const InvalidZoneIdException&) { + LOGE("No zone with id=" << zone); + result->setError(api::ERROR_INVALID_ID, "No such zone id"); + } catch (const VasumException& ex) { + LOGE("Can't create netdev: " << ex.what()); + result->setError(api::ERROR_INTERNAL, ex.what()); + } +} + void ZonesManager::handleDeclareFileCall(const std::string& zone, const int32_t& type, const std::string& path, diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 825b1c8..deb9b9d 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -189,6 +189,9 @@ private: void handleCreateNetdevPhysCall(const std::string& zone, const std::string& devId, api::MethodResultBuilder::Pointer result); + void handleDestroyNetdevCall(const std::string& zone, + const std::string& devId, + api::MethodResultBuilder::Pointer result); void handleDeclareFileCall(const std::string& zone, const int32_t& type, const std::string& path, diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index a8b608f..91d0540 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -27,6 +27,7 @@ #include "ut.hpp" #include "zone.hpp" +#include "netdev.hpp" #include "exception.hpp" #include "utils/exception.hpp" @@ -39,8 +40,11 @@ #include #include #include +#include +#include using namespace vasum; +using namespace vasum::netdev; using namespace config; namespace { @@ -53,15 +57,28 @@ const std::string MISSING_CONFIG_PATH = TEMPLATES_DIR + "/missing.conf"; const std::string ZONES_PATH = "/tmp/ut-zones"; const std::string LXC_TEMPLATES_PATH = VSM_TEST_LXC_TEMPLATES_INSTALL_DIR; const std::string DB_PATH = ZONES_PATH + "/vasum.db"; +const std::string BRIDGE_NAME = "brtest01"; +const std::string ZONE_NETDEV = "netdevtest01"; struct Fixture { utils::ScopedGlibLoop mLoop; utils::ScopedDir mZonesPathGuard; utils::ScopedDir mRunGuard; + std::string mBridgeName; Fixture() : mZonesPathGuard(ZONES_PATH) {} + ~Fixture() + { + if (!mBridgeName.empty()) { + try { + destroyNetdev(mBridgeName); + } catch (std::exception& ex) { + BOOST_MESSAGE("Can't destroy bridge: " + std::string(ex.what())); + } + } + } std::unique_ptr create(const std::string& configPath) { @@ -74,11 +91,23 @@ struct Fixture { "")); } + void setupBridge(const std::string& name) + { + createBridge(name); + mBridgeName = name; + } + + void ensureStarted() { // wait for zones init to fully start std::this_thread::sleep_for(std::chrono::milliseconds(200)); } + void ensureStop() + { + // wait for fully stop + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } }; } // namespace @@ -144,4 +173,40 @@ BOOST_AUTO_TEST_CASE(ListNetdevTest) c->stop(false); } +BOOST_AUTO_TEST_CASE(CreateNetdevVethTest) +{ + typedef std::vector NetdevList; + + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + NetdevList netdevs = c->getNetdevList(); + BOOST_CHECK(find(netdevs.begin(), netdevs.end(), ZONE_NETDEV) != netdevs.end()); + c->stop(false); + ensureStop(); + + //Check clean up + NetdevList hostNetdevsInit = listNetdev(); + BOOST_REQUIRE_THROW(c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME), VasumException); + NetdevList hostNetdevsThrow = listNetdev(); + BOOST_CHECK_EQUAL_COLLECTIONS(hostNetdevsInit.begin(), hostNetdevsInit.end(), + hostNetdevsThrow.begin(), hostNetdevsThrow.end()); +} + +BOOST_AUTO_TEST_CASE(CreateNetdevMacvlanTest) +{ + typedef std::vector NetdevList; + + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + NetdevList netdevs = c->getNetdevList(); + BOOST_CHECK(find(netdevs.begin(), netdevs.end(), ZONE_NETDEV) != netdevs.end()); + c->stop(false); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 84a5119de0fdfa01e9a70a37682c29d25119f25e Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Mon, 16 Mar 2015 16:14:54 +0100 Subject: [PATCH 03/16] Epoll modifyFD method added. Some refactor. [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Run tests Change-Id: Idcba92d12a618a8095420f3c941a12d61aef1761 --- common/epoll/event-poll.cpp | 36 +++++-- common/epoll/event-poll.hpp | 11 ++- common/epoll/thread-dispatcher.cpp | 9 +- common/epoll/thread-dispatcher.hpp | 2 + common/ipc/client.cpp | 7 +- common/ipc/internals/processor.hpp | 3 - common/ipc/service.cpp | 15 ++- tests/unit_tests/dbus/ut-connection.cpp | 5 - tests/unit_tests/epoll/ut-event-poll.cpp | 162 ++++++++++++++++++++++++------- tests/unit_tests/utils/ut-glib-loop.cpp | 21 ++-- 10 files changed, 192 insertions(+), 79 deletions(-) diff --git a/common/epoll/event-poll.cpp b/common/epoll/event-poll.cpp index 9eb9fa0..dfb0385 100644 --- a/common/epoll/event-poll.cpp +++ b/common/epoll/event-poll.cpp @@ -79,14 +79,22 @@ void EventPoll::addFD(const int fd, const Events events, Callback&& callback) LOGT("Callback added for fd: " << fd); } +void EventPoll::modifyFD(const int fd, const Events events) +{ + // No need to lock and check mCallbacks map + if (!modifyFDInternal(fd, events)) { + throw UtilsException("Could not modify fd"); + } +} + void EventPoll::removeFD(const int fd) { std::lock_guard lock(mMutex); auto iter = mCallbacks.find(fd); if (iter == mCallbacks.end()) { - LOGW("Failed to remove nonexistent fd: " << fd); - throw UtilsException("FD does not exist"); + LOGT("Callback not found, probably already removed fd: " << fd); + return; } mCallbacks.erase(iter); removeFDInternal(fd); @@ -94,6 +102,7 @@ void EventPoll::removeFD(const int fd) } bool EventPoll::dispatchIteration(const int timeoutMs) + { for (;;) { epoll_event event; @@ -120,19 +129,16 @@ bool EventPoll::dispatchIteration(const int timeoutMs) std::shared_ptr callback(iter->second); try { LOGT("Dispatch fd: " << event.data.fd << ", events: " << eventsToString(event.events)); - return (*callback)(event.data.fd, event.events); + (*callback)(event.data.fd, event.events); + return true; } catch (std::exception& e) { LOGE("Got unexpected exception: " << e.what()); assert(0 && "Callback should not throw any exceptions"); + return true; } } } -void EventPoll::dispatchLoop() -{ - while (dispatchIteration(-1)) {} -} - bool EventPoll::addFDInternal(const int fd, const Events events) { epoll_event event; @@ -147,6 +153,20 @@ bool EventPoll::addFDInternal(const int fd, const Events events) return true; } +bool EventPoll::modifyFDInternal(const int fd, const Events events) +{ + epoll_event event; + memset(&event, 0, sizeof(event)); + event.events = events; + event.data.fd = fd; + + if (epoll_ctl(mPollFD, EPOLL_CTL_MOD, fd, &event) == -1) { + LOGE("Failed to modify fd in poll: " << getSystemErrorMessage()); + return false; + } + return true; +} + void EventPoll::removeFDInternal(const int fd) { if (epoll_ctl(mPollFD, EPOLL_CTL_DEL, fd, NULL) == -1) { diff --git a/common/epoll/event-poll.hpp b/common/epoll/event-poll.hpp index 2d37aaa..67614ab 100644 --- a/common/epoll/event-poll.hpp +++ b/common/epoll/event-poll.hpp @@ -37,7 +37,7 @@ namespace epoll { class EventPoll { public: - typedef std::function Callback; + typedef std::function Callback; EventPoll(); ~EventPoll(); @@ -45,10 +45,16 @@ public: int getPollFD() const; void addFD(const int fd, const Events events, Callback&& callback); + void modifyFD(const int fd, const Events events); void removeFD(const int fd); + /** + * Dispatch at most one signalled FD + * @param timeoutMs how long should wait in case of no pending events + * (0 - return immediately, -1 - wait forever) + * @return false on timeout + */ bool dispatchIteration(const int timeoutMs); - void dispatchLoop(); private: typedef std::recursive_mutex Mutex; @@ -58,6 +64,7 @@ private: std::unordered_map> mCallbacks; bool addFDInternal(const int fd, const Events events); + bool modifyFDInternal(const int fd, const Events events); void removeFDInternal(const int fd); }; diff --git a/common/epoll/thread-dispatcher.cpp b/common/epoll/thread-dispatcher.cpp index a82cad8..d286c19 100644 --- a/common/epoll/thread-dispatcher.cpp +++ b/common/epoll/thread-dispatcher.cpp @@ -29,15 +29,18 @@ namespace vasum { namespace epoll { ThreadDispatcher::ThreadDispatcher() + : mStopped(false) { - auto controlCallback = [this](int, Events) -> bool { + auto controlCallback = [this](int, Events) { mStopEvent.receive(); - return false; // break the loop + mStopped.store(true, std::memory_order_release); }; mPoll.addFD(mStopEvent.getFD(), EPOLLIN, std::move(controlCallback)); mThread = std::thread([this] { - mPoll.dispatchLoop(); + while (!mStopped.load(std::memory_order_acquire)) { + mPoll.dispatchIteration(-1); + } }); } diff --git a/common/epoll/thread-dispatcher.hpp b/common/epoll/thread-dispatcher.hpp index 7d0f30d..5c6c145 100644 --- a/common/epoll/thread-dispatcher.hpp +++ b/common/epoll/thread-dispatcher.hpp @@ -29,6 +29,7 @@ #include "utils/eventfd.hpp" #include +#include namespace vasum { namespace epoll { @@ -45,6 +46,7 @@ public: private: EventPoll mPoll; utils::EventFD mStopEvent; + std::atomic_bool mStopped; std::thread mThread; }; diff --git a/common/ipc/client.cpp b/common/ipc/client.cpp index abecb71..75a62ad 100644 --- a/common/ipc/client.cpp +++ b/common/ipc/client.cpp @@ -58,9 +58,8 @@ void Client::start() } LOGS("Client start"); // Initialize the connection with the server - auto handleEvent = [&](int, epoll::Events) -> bool { + auto handleEvent = [&](int, epoll::Events) { mProcessor.handleEvent(); - return true; }; mEventPoll.addFD(mProcessor.getEventFD(), EPOLLIN, handleEvent); mProcessor.start(); @@ -98,6 +97,7 @@ void Client::handle(const FileDescriptor fd, const epoll::Events pollEvents) if (pollEvents & EPOLLIN) { mProcessor.handleInput(fd); + return; // because handleInput will handle RDHUP } if ((pollEvents & EPOLLHUP) || (pollEvents & EPOLLRDHUP)) { @@ -109,9 +109,8 @@ void Client::setNewPeerCallback(const PeerCallback& newPeerCallback) { LOGS("Client setNewPeerCallback"); auto callback = [newPeerCallback, this](PeerID peerID, FileDescriptor fd) { - auto handleFd = [&](FileDescriptor fd, epoll::Events events) -> bool { + auto handleFd = [&](FileDescriptor fd, epoll::Events events) { handle(fd, events); - return true; }; mEventPoll.addFD(fd, EPOLLIN | EPOLLHUP | EPOLLRDHUP, handleFd); if (newPeerCallback) { diff --git a/common/ipc/internals/processor.hpp b/common/ipc/internals/processor.hpp index 6e0ae81..dec16e8 100644 --- a/common/ipc/internals/processor.hpp +++ b/common/ipc/internals/processor.hpp @@ -80,11 +80,8 @@ const unsigned int DEFAULT_MAX_NUMBER_OF_PEERS = 500; * - new way to generate UIDs * - callbacks for serialization/parsing * - store Sockets in a vector, maybe SocketStore? -* - poll loop outside. * - waiting till the EventQueue is empty before leaving stop() * - no new events added after stop() called -* - when using IPCGSource: addFD and removeFD can be called from addPeer removePeer callbacks, but -* there is no mechanism to ensure the IPCSource exists.. therefore SIGSEGV :) * */ class Processor { diff --git a/common/ipc/service.cpp b/common/ipc/service.cpp index c436726..849ce3c 100644 --- a/common/ipc/service.cpp +++ b/common/ipc/service.cpp @@ -63,17 +63,15 @@ void Service::start() return; } LOGS("Service start"); - auto handleConnection = [&](int, epoll::Events) -> bool { + auto handleConnection = [&](int, epoll::Events) { mAcceptor.handleConnection(); - return true; }; - auto handleProcessorEvent = [&](int, epoll::Events) -> bool { + auto handleProcessorEvent = [&](int, epoll::Events) { mProcessor.handleEvent(); - return true; }; - mEventPoll.addFD(mAcceptor.getConnectionFD(), EPOLLIN, handleConnection); mEventPoll.addFD(mProcessor.getEventFD(), EPOLLIN, handleProcessorEvent); mProcessor.start(); + mEventPoll.addFD(mAcceptor.getConnectionFD(), EPOLLIN, handleConnection); } bool Service::isStarted() @@ -87,9 +85,8 @@ void Service::stop() return; } LOGS("Service stop"); - mProcessor.stop(); - mEventPoll.removeFD(mAcceptor.getConnectionFD()); + mProcessor.stop(); mEventPoll.removeFD(mProcessor.getEventFD()); } @@ -105,6 +102,7 @@ void Service::handle(const FileDescriptor fd, const epoll::Events pollEvents) if (pollEvents & EPOLLIN) { mProcessor.handleInput(fd); + return; // because handleInput will handle RDHUP } if ((pollEvents & EPOLLHUP) || (pollEvents & EPOLLRDHUP)) { @@ -116,9 +114,8 @@ void Service::setNewPeerCallback(const PeerCallback& newPeerCallback) { LOGS("Service setNewPeerCallback"); auto callback = [newPeerCallback, this](PeerID peerID, FileDescriptor fd) { - auto handleFd = [&](FileDescriptor fd, epoll::Events events) -> bool { + auto handleFd = [&](FileDescriptor fd, epoll::Events events) { handle(fd, events); - return true; }; mEventPoll.addFD(fd, EPOLLIN | EPOLLHUP | EPOLLRDHUP, handleFd); if (newPeerCallback) { diff --git a/tests/unit_tests/dbus/ut-connection.cpp b/tests/unit_tests/dbus/ut-connection.cpp index 4948cd7..e52778e 100644 --- a/tests/unit_tests/dbus/ut-connection.cpp +++ b/tests/unit_tests/dbus/ut-connection.cpp @@ -96,11 +96,6 @@ std::string getInterfaceFromIntrospectionXML(const std::string& xml, const std:: } // namespace -BOOST_AUTO_TEST_CASE(GlibLoopTest) -{ - ScopedGlibLoop loop; -} - BOOST_AUTO_TEST_CASE(DbusDaemonTest) { ScopedDbusDaemon daemon; diff --git a/tests/unit_tests/epoll/ut-event-poll.cpp b/tests/unit_tests/epoll/ut-event-poll.cpp index 00cb385..3a26b5e 100644 --- a/tests/unit_tests/epoll/ut-event-poll.cpp +++ b/tests/unit_tests/epoll/ut-event-poll.cpp @@ -29,11 +29,12 @@ #include "epoll/event-poll.hpp" #include "logger/logger.hpp" #include "ipc/internals/socket.hpp" -#include "utils/latch.hpp" +#include "utils/value-latch.hpp" #include "utils/glib-loop.hpp" #include "epoll/glib-dispatcher.hpp" #include "epoll/thread-dispatcher.hpp" +using namespace vasum; using namespace vasum::utils; using namespace vasum::epoll; using namespace vasum::ipc; @@ -66,62 +67,152 @@ BOOST_AUTO_TEST_CASE(GlibPoll) void doSocketTest(EventPoll& poll) { - const std::string PATH = "/tmp/ut-poll.sock"; - const std::string MESSAGE = "This is a test message"; - - Latch goodMessage; - Latch remoteClosed; - - Socket listen = Socket::createSocket(PATH); - std::shared_ptr server; + using namespace std::placeholders; - auto serverCallback = [&](int, Events events) -> bool { + //TODO don't use ipc socket + const std::string PATH = "/tmp/ut-poll.sock"; + const size_t REQUEST_LEN = 5; + const std::string REQUEST_GOOD = "GET 1"; + const std::string REQUEST_BAD = "GET 7"; + const std::string RESPONSE = "This is a response message"; + + // Scenario 1: + // client connects to server listening socket + // client ---good-request---> server + // server ---response---> client + // client disconnects + // + // Scenario 2: + // client connects to server listening socket + // client ---bad-request----> server + // server disconnects + + // { server setup + + auto serverCallback = [&](int /*fd*/, + Events events, + std::shared_ptr socket, + CallbackGuard::Tracker) { LOGD("Server events: " << eventsToString(events)); + if (events & EPOLLIN) { + std::string request(REQUEST_LEN, 'x'); + socket->read(&request.front(), request.size()); + if (request == REQUEST_GOOD) { + poll.modifyFD(socket->getFD(), EPOLLRDHUP | EPOLLOUT); + } else { + // disconnect (socket is kept in callback) + poll.removeFD(socket->getFD()); + } + } + if (events & EPOLLOUT) { - server->write(MESSAGE.data(), MESSAGE.size()); - poll.removeFD(server->getFD()); - server.reset(); + socket->write(RESPONSE.data(), RESPONSE.size()); + poll.modifyFD(socket->getFD(), EPOLLRDHUP); + } + + if (events & EPOLLRDHUP) { + // client has disconnected + poll.removeFD(socket->getFD()); } - return true; }; - auto listenCallback = [&](int, Events events) -> bool { + Socket listenSocket = Socket::createSocket(PATH); + CallbackGuard serverSocketsGuard; + + auto listenCallback = [&](int /*fd*/, Events events) { LOGD("Listen events: " << eventsToString(events)); if (events & EPOLLIN) { - server = listen.accept(); - poll.addFD(server->getFD(), EPOLLHUP | EPOLLRDHUP | EPOLLOUT, serverCallback); + // accept new server connection + std::shared_ptr socket = listenSocket.accept(); + poll.addFD(socket->getFD(), + EPOLLRDHUP | EPOLLIN, + std::bind(serverCallback, _1, _2, socket, serverSocketsGuard.spawn())); } - return true; }; - poll.addFD(listen.getFD(), EPOLLIN, listenCallback); + poll.addFD(listenSocket.getFD(), EPOLLIN, listenCallback); + + // } server setup - Socket client = Socket::connectSocket(PATH); + // { client setup - auto clientCallback = [&](int, Events events) -> bool { + auto clientCallback = [&](int /*fd*/, + Events events, + Socket& socket, + const std::string& request, + ValueLatch& response) { LOGD("Client events: " << eventsToString(events)); + if (events & EPOLLOUT) { + socket.write(request.data(), request.size()); + poll.modifyFD(socket.getFD(), EPOLLRDHUP | EPOLLIN); + } + if (events & EPOLLIN) { - std::string ret(MESSAGE.size(), 'x'); - client.read(&ret.front(), ret.size()); - if (ret == MESSAGE) { - goodMessage.set(); + try { + std::string msg(RESPONSE.size(), 'x'); + socket.read(&msg.front(), msg.size()); + response.set(msg); + } catch (UtilsException&) { + response.set(std::string()); } + poll.modifyFD(socket.getFD(), EPOLLRDHUP); } + if (events & EPOLLRDHUP) { - poll.removeFD(client.getFD()); - remoteClosed.set(); + LOGD("Server has disconnected"); + poll.removeFD(socket.getFD()); //prevent active loop } - return true; }; - poll.addFD(client.getFD(), EPOLLHUP | EPOLLRDHUP | EPOLLIN, clientCallback); - - BOOST_CHECK(goodMessage.wait(TIMEOUT)); - BOOST_CHECK(remoteClosed.wait(TIMEOUT)); - - poll.removeFD(listen.getFD()); + // } client setup + + // Scenario 1 + LOGD("Scerario 1"); + { + Socket client = Socket::connectSocket(PATH); + ValueLatch response; + + poll.addFD(client.getFD(), + EPOLLRDHUP | EPOLLOUT, + std::bind(clientCallback, + _1, + _2, + std::ref(client), + REQUEST_GOOD, + std::ref(response))); + + BOOST_CHECK(response.get(TIMEOUT) == RESPONSE); + + poll.removeFD(client.getFD()); + } + + // Scenario 2 + LOGD("Scerario 2"); + { + Socket client = Socket::connectSocket(PATH); + ValueLatch response; + + poll.addFD(client.getFD(), + EPOLLRDHUP | EPOLLOUT, + std::bind(clientCallback, + _1, + _2, + std::ref(client), + REQUEST_BAD, + std::ref(response))); + + BOOST_CHECK(response.get(TIMEOUT) == std::string()); + + poll.removeFD(client.getFD()); + } + LOGD("Done"); + + poll.removeFD(listenSocket.getFD()); + + // wait for all server sockets (ensure all EPOLLRDHUP are processed) + BOOST_REQUIRE(serverSocketsGuard.waitForTrackers(TIMEOUT)); } BOOST_AUTO_TEST_CASE(ThreadedPollSocket) @@ -146,9 +237,8 @@ BOOST_AUTO_TEST_CASE(PollStacking) EventPoll innerPoll; - auto dispatchInner = [&](int, Events) -> bool { + auto dispatchInner = [&](int, Events) { innerPoll.dispatchIteration(0); - return true; }; dispatcher.getPoll().addFD(innerPoll.getPollFD(), EPOLLIN, dispatchInner); doSocketTest(innerPoll); diff --git a/tests/unit_tests/utils/ut-glib-loop.cpp b/tests/unit_tests/utils/ut-glib-loop.cpp index 30d5342..7c5e318 100644 --- a/tests/unit_tests/utils/ut-glib-loop.cpp +++ b/tests/unit_tests/utils/ut-glib-loop.cpp @@ -26,12 +26,11 @@ #include "config.hpp" #include "ut.hpp" -#include "utils/latch.hpp" #include "utils/glib-loop.hpp" #include -BOOST_AUTO_TEST_SUITE(UtilsGlibLoopSuite) +BOOST_AUTO_TEST_SUITE(GlibLoopSuite) using namespace vasum; using namespace vasum::utils; @@ -39,22 +38,25 @@ using namespace vasum::utils; namespace { -const unsigned int TIMER_INTERVAL_MS = 10; -const unsigned int TIMER_NUMBER = 5; +const unsigned int TIMER_INTERVAL_MS = 100; +const unsigned int TIMER_NUMBER = 4; const unsigned int TIMER_WAIT_FOR = 2 * TIMER_NUMBER * TIMER_INTERVAL_MS; } // namespace +BOOST_AUTO_TEST_CASE(GlibLoopTest) +{ + ScopedGlibLoop loop; +} + BOOST_AUTO_TEST_CASE(GlibTimerEventTest) { ScopedGlibLoop loop; - Latch latch; std::atomic_uint counter(0); CallbackGuard guard; - Glib::OnTimerEventCallback callback = [&]()->bool { - latch.set(); + auto callback = [&]()-> bool { if (++counter >= TIMER_NUMBER) { return false; } @@ -63,8 +65,9 @@ BOOST_AUTO_TEST_CASE(GlibTimerEventTest) Glib::addTimerEvent(TIMER_INTERVAL_MS, callback, guard); - BOOST_REQUIRE(latch.waitForN(TIMER_NUMBER, TIMER_WAIT_FOR)); - BOOST_REQUIRE(latch.wait(TIMER_WAIT_FOR) == false); + BOOST_CHECK(counter < TIMER_NUMBER); + BOOST_CHECK(guard.waitForTrackers(TIMER_WAIT_FOR)); + BOOST_CHECK_EQUAL(counter, TIMER_NUMBER); } BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 29bcde2e47e0560b4c2e4b7976f2c9853cfd6e58 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 5 Mar 2015 17:04:04 +0100 Subject: [PATCH 04/16] Get/set ipv4/ipv6 address, up/down interface [Feature] Possibility to get/set ipv4/ipv6 address, up/down interface [Cause] N/A [Solution] Implemented: vsm_netdev_get_ipv4_addr, vsm_netdev_get_ipv6_addr, vsm_netdev_set_ipv4_addr, vsm_netdev_set_ipv6_addr, vsm_netdev_up, vsm_netdev_down, vsm_lookup_netdev_by_name [Verification] Build, install 1) run test 2) set interfaces attributes (up, down) through cli and check it "lxc-attach -n zoneId --lxcpath=/tmp/ut-zones -- ip addr" Change-Id: I42ffa7e4c8f8cf2e22171d95b62884a2317d1107 --- cli/command-line-interface.cpp | 35 +++++ cli/command-line-interface.hpp | 7 + cli/main.cpp | 9 ++ client/vasum-client-impl.cpp | 158 +++++++++++++++------- client/vasum-client-impl.hpp | 6 + client/vasum-client.h | 6 +- server/netdev.cpp | 256 +++++++++++++++++++++++++++++++++++- server/netdev.hpp | 6 + server/zone-admin.cpp | 8 +- server/zone-admin.hpp | 4 +- tests/unit_tests/server/ut-zone.cpp | 146 +++++++++++++++++++- 11 files changed, 582 insertions(+), 59 deletions(-) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index 100aaa1..2ae3778 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -128,6 +128,23 @@ ostream& operator<<(ostream& out, const VsmZone& zone) return out; } +ostream& operator<<(ostream& out, const VsmNetdevType& netdevType) +{ + switch (netdevType) { + case VSMNETDEV_VETH: out << "VETH"; break; + case VSMNETDEV_PHYS: out << "PHYS"; break; + case VSMNETDEV_MACVLAN: out << "MACVLAN"; break; + } + return out; +} + +ostream& operator<<(ostream& out, const VsmNetdev& netdev) +{ + out << "Name: " << netdev->name + << "\nType: " << netdev->type; + return out; +} + typedef vector> Table; ostream& operator<<(ostream& out, const Table& table) @@ -397,6 +414,24 @@ void create_netdev_phys(int pos, int argc, const char** argv) argv[pos + 2])); } +void lookup_netdev_by_name(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 2) { + throw runtime_error("Not enough parameters"); + } + VsmNetdev vsmNetdev = NULL; + one_shot(bind(vsm_lookup_netdev_by_name, + _1, + argv[pos + 1], + argv[pos + 2], + &vsmNetdev)); + cout << vsmNetdev << endl; + vsm_netdev_free(vsmNetdev); + +} + void destroy_netdev(int pos, int argc, const char** argv) { using namespace std::placeholders; diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index 006396c..6e27c74 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -209,6 +209,13 @@ void create_netdev_macvlan(int pos, int argc, const char** argv); void create_netdev_phys(int pos, int argc, const char** argv); /** + * Parses command line arguments and call vsm_lookup_netdev_by_name + * + * @see vsm_lookup_netdev_by_name + */ +void lookup_netdev_by_name(int pos, int argc, const char** argv); + +/** * Parses command line arguments and call vsm_destroy_netdev * * @see vsm_destroy_netdev diff --git a/cli/main.cpp b/cli/main.cpp index c915415..2431313 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -173,6 +173,15 @@ std::map commands = { } }, { + "lookup_netdev_by_name", { + lookup_netdev_by_name, + "lookup_netdev_by_name zone_id devId", + "Get netdev flags", + {{"zone_id", "id zone name"}, + {"devId", "network device id"}} + } + }, + { "destroy_netdev", { destroy_netdev, "destroy_netdev zone_id devId", diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index fb1b2ec..1de4de0 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -40,6 +40,10 @@ #include #include #include +#include + +#include +#include using namespace std; using namespace dbus; @@ -202,7 +206,6 @@ GVariant* createTupleArray(const vector>& dict) return g_variant_builder_end(&builder); } - VsmStatus toStatus(const exception& ex) { if (typeid(DbusCustomException) == typeid(ex)) { @@ -232,6 +235,29 @@ 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 { @@ -608,36 +634,37 @@ VsmStatus Client::vsm_netdev_get_ipv4_addr(const char* zone, const char* netdevId, struct in_addr* addr) noexcept { + using namespace boost::algorithm; + assert(zone); assert(netdevId); assert(addr); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(ss)", zone, netdevId); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_NETDEV_ATTRS, - args_in, - "(a(ss))", - &out); + NetdevAttrs attrs; + VsmStatus ret = getNetdevAttrs(zone, netdevId, attrs); if (ret != VSMCLIENT_SUCCESS) { return ret; } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - vector> attrs = toDict(unpacked); - g_variant_unref(unpacked); - g_variant_unref(out); auto it = find_if(attrs.begin(), attrs.end(), [](const tuple& entry) { return get<0>(entry) == "ipv4"; }); if (it != attrs.end()) { - if (inet_pton(AF_INET, get<1>(*it).c_str(), addr) != 1) { - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data"); - return vsm_get_status(); - } - mStatus = Status(); - return vsm_get_status(); + 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(); + } + } + } } mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Address not found"); return vsm_get_status(); @@ -647,37 +674,37 @@ VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* zone, const char* netdevId, struct in6_addr* addr) noexcept { + using namespace boost::algorithm; + assert(zone); assert(netdevId); assert(addr); - GVariant* out = NULL; - GVariant* args_in = g_variant_new("(ss)", zone, netdevId); - VsmStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_NETDEV_ATTRS, - args_in, - "(a(ss))", - &out); + NetdevAttrs attrs; + VsmStatus ret = getNetdevAttrs(zone, netdevId, attrs); if (ret != VSMCLIENT_SUCCESS) { return ret; } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - vector> attrs = toDict(unpacked); - g_variant_unref(unpacked); - g_variant_unref(out); - //XXX: return only one address auto it = find_if(attrs.begin(), attrs.end(), [](const tuple& entry) { return get<0>(entry) == "ipv6"; }); if (it != attrs.end()) { - if (inet_pton(AF_INET6, get<1>(*it).c_str(), addr) != 1) { - mStatus = Status(VSMCLIENT_CUSTOM_ERROR, "Invalid response data"); - return vsm_get_status(); - } - mStatus = Status(); - return vsm_get_status(); + 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(); @@ -689,8 +716,9 @@ VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* zone, int mask) noexcept { try { - GVariant* dict = createTupleArray({make_tuple("ipv4", toString(addr)), - make_tuple("mask", to_string(mask))}); + GVariant* dict = createTupleArray({make_tuple("ipv4", + "ip:" + toString(addr) + "," + "prefixlen:" + to_string(mask))}); 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) { @@ -705,8 +733,9 @@ VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone, int mask) noexcept { try { - GVariant* dict = createTupleArray({make_tuple("ipv6", toString(addr)), - make_tuple("mask", to_string(mask))}); + GVariant* dict = createTupleArray({make_tuple("ipv6", + "ip:" + toString(addr) + "," + "prefixlen:" + to_string(mask))}); 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) { @@ -718,7 +747,8 @@ VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone, VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept { try { - GVariant* dict = createTupleArray({make_tuple("up", "true")}); + 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) { @@ -730,7 +760,8 @@ VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept VsmStatus Client::vsm_netdev_down(const char* zone, const char* netdevId) noexcept { try { - GVariant* dict = createTupleArray({make_tuple("up", "false")}); + 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) { @@ -762,9 +793,44 @@ VsmStatus Client::vsm_create_netdev_phys(const char* zone, const char* devId) no return callMethod(HOST_INTERFACE, api::host::METHOD_CREATE_NETDEV_PHYS, args_in); } -VsmStatus Client::vsm_lookup_netdev_by_name(const char*, const char*, VsmNetdev*) noexcept +VsmStatus Client::vsm_lookup_netdev_by_name(const char* zone, + const char* netdevId, + VsmNetdev* netdev) noexcept { - mStatus = Status(VSMCLIENT_OTHER_ERROR, "Not implemented"); + using namespace boost::algorithm; + + assert(zone); + 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(); + } + + 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(); + } + + *netdev = reinterpret_cast(malloc(sizeof(**netdev))); + (*netdev)->name = strdup(zone); + (*netdev)->type = type; + mStatus = Status(); return vsm_get_status(); } diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 9399839..1493a00 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -29,6 +29,8 @@ #include "vasum-client.h" #include #include +#include +#include #include /** @@ -53,6 +55,7 @@ struct DbusInterfaceInfo { */ class Client { private: + typedef std::vector> NetdevAttrs; typedef std::function SignalCallback; struct Status { Status(); @@ -74,6 +77,9 @@ private: SignalCallback signalCallback, VsmSubscriptionId* subscriptionId); VsmStatus signalUnsubscribe(VsmSubscriptionId id); + VsmStatus getNetdevAttrs(const std::string& zone, + const std::string& netdev, + NetdevAttrs& attrs) noexcept; public: Client() noexcept; diff --git a/client/vasum-client.h b/client/vasum-client.h index 0bd40ad..18af990 100644 --- a/client/vasum-client.h +++ b/client/vasum-client.h @@ -160,9 +160,9 @@ typedef VsmZoneStructure* VsmZone; * Netowrk device type */ typedef enum { - VETH, - PHYS, - MACVLAN + VSMNETDEV_VETH, + VSMNETDEV_PHYS, + VSMNETDEV_MACVLAN } VsmNetdevType; /** diff --git a/server/netdev.cpp b/server/netdev.cpp index e17ecda..da58641 100644 --- a/server/netdev.cpp +++ b/server/netdev.cpp @@ -36,17 +36,22 @@ #include #include #include +#include +#include + +#include +#include #include #include #include +#include #include #include #include #include #include #include -#include #include //IFLA_BRIDGE_FLAGS and BRIDGE_FLAGS_MASTER @@ -99,6 +104,22 @@ uint32_t getInterfaceIndex(const string& name) { return index; } +uint32_t getInterfaceIndex(const string& name, pid_t nsPid) { + NetlinkMessage nlm(RTM_GETLINK, NLM_F_REQUEST | NLM_F_ACK); + ifinfomsg infoPeer = utils::make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_change = 0xFFFFFFFF; + nlm.put(infoPeer) + .put(IFLA_IFNAME, name); + NetlinkResponse response = send(nlm, nsPid); + if (!response.hasMessage()) { + throw VasumException("Can't get interface index"); + } + + response.fetch(infoPeer); + return infoPeer.ifi_index; +} + void validateNetdevName(const string& name) { if (name.size() <= 1 || name.size() >= IFNAMSIZ) { @@ -209,6 +230,107 @@ void createMacvlan(const string& master, const string& slave, const macvlan_mode send(nlm); } +std::vector getIpAddresses(const pid_t nsPid, int family, uint32_t index) +{ + NetlinkMessage nlm(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP); + ifaddrmsg infoAddr = utils::make_clean(); + infoAddr.ifa_family = family; + nlm.put(infoAddr); + NetlinkResponse response = send(nlm, nsPid); + if (!response.hasMessage()) { + //There is no interfaces with addresses + return std::vector(); + } + + std::vector addresses; + while (response.hasMessage()) { + ifaddrmsg addrmsg; + response.fetch(addrmsg); + if (addrmsg.ifa_index == index) { + Attrs attrs; + attrs.push_back(make_tuple("prefixlen", std::to_string(addrmsg.ifa_prefixlen))); + attrs.push_back(make_tuple("flags", std::to_string(addrmsg.ifa_flags))); + attrs.push_back(make_tuple("scope", std::to_string(addrmsg.ifa_scope))); + attrs.push_back(make_tuple("family", std::to_string(addrmsg.ifa_family))); + while (response.hasAttribute()) { + assert(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); + char buf[INET6_ADDRSTRLEN]; + in6_addr addr6; + in_addr addr4; + const void* addr = NULL; + int attrType = response.getAttributeType(); + switch (attrType) { + case IFA_ADDRESS: + if (family == AF_INET6) { + response.fetch(IFA_ADDRESS, addr6); + addr = &addr6; + } else { + assert(family == AF_INET); + response.fetch(IFA_ADDRESS, addr4); + addr = &addr4; + } + addr = inet_ntop(family, addr, buf, sizeof(buf)); + if (addr == NULL) { + LOGE("Can't convert ip address: " << getSystemErrorMessage()); + throw VasumException("Can't get ip address"); + } + attrs.push_back(make_tuple("ip", buf)); + break; + default: + response.skipAttribute(); + break; + } + } + addresses.push_back(std::move(attrs)); + } + response.fetchNextMessage(); + } + return addresses; +} + +void setIpAddresses(const pid_t nsPid, + const uint32_t index, + const Attrs& attrs, + int family) +{ + NetlinkMessage nlm(RTM_NEWADDR, NLM_F_CREATE | NLM_F_REQUEST | NLM_F_ACK); + ifaddrmsg infoAddr = utils::make_clean(); + infoAddr.ifa_family = family; + infoAddr.ifa_index = index; + for (const auto& attr : attrs) { + if (get<0>(attr) == "prefixlen") { + infoAddr.ifa_prefixlen = stoul(get<1>(attr)); + } + if (get<0>(attr) == "flags") { + infoAddr.ifa_flags = stoul(get<1>(attr)); + } + if (get<0>(attr) == "scope") { + infoAddr.ifa_scope = stoul(get<1>(attr)); + } + } + nlm.put(infoAddr); + for (const auto& attr : attrs) { + if (get<0>(attr) == "ip") { + if (family == AF_INET6) { + in6_addr addr6; + if (inet_pton(AF_INET6, get<1>(attr).c_str(), &addr6) != 1) { + throw VasumException("Can't set ipv4 address"); + }; + nlm.put(IFA_ADDRESS, addr6); + nlm.put(IFA_LOCAL, addr6); + } else { + assert(family == AF_INET); + in_addr addr4; + if (inet_pton(AF_INET, get<1>(attr).c_str(), &addr4) != 1) { + throw VasumException("Can't set ipv6 address"); + }; + nlm.put(IFA_LOCAL, addr4); + } + } + } + send(nlm, nsPid); +} + } // namespace void createVeth(const pid_t& nsPid, const string& nsDev, const string& hostDev) @@ -310,6 +432,138 @@ void createBridge(const string& netdev) send(nlm); } +Attrs getAttrs(const pid_t nsPid, const std::string& netdev) +{ + auto joinAddresses = [](const Attrs& attrs) -> std::string { + bool first = true; + stringstream ss; + for (const auto& attr : attrs) { + ss << (first ? "" : ",") << get<0>(attr) << ":" << get<1>(attr); + first = false; + } + return ss.str(); + }; + + LOGT("Getting network device informations: " << netdev); + validateNetdevName(netdev); + + NetlinkMessage nlm(RTM_GETLINK, NLM_F_REQUEST | NLM_F_ACK); + ifinfomsg infoPeer = utils::make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_change = 0xFFFFFFFF; + nlm.put(infoPeer) + .put(IFLA_IFNAME, netdev); + NetlinkResponse response = send(nlm, nsPid); + if (!response.hasMessage()) { + throw VasumException("Can't get interface information"); + } + response.fetch(infoPeer); + + Attrs attrs; + while (response.hasAttribute()) { + uint32_t mtu, link; + int attrType = response.getAttributeType(); + switch (attrType) { + case IFLA_MTU: + response.fetch(IFLA_MTU, mtu); + attrs.push_back(make_tuple("mtu", std::to_string(mtu))); + break; + case IFLA_LINK: + response.fetch(IFLA_LINK, link); + attrs.push_back(make_tuple("link", std::to_string(link))); + break; + default: + response.skipAttribute(); + break; + } + } + attrs.push_back(make_tuple("flags", std::to_string(infoPeer.ifi_flags))); + attrs.push_back(make_tuple("type", std::to_string(infoPeer.ifi_type))); + for (const auto& address : getIpAddresses(nsPid, AF_INET, infoPeer.ifi_index)) { + attrs.push_back(make_tuple("ipv4", joinAddresses(address))); + } + for (const auto& address : getIpAddresses(nsPid, AF_INET6, infoPeer.ifi_index)) { + attrs.push_back(make_tuple("ipv6", joinAddresses(address))); + } + + return attrs; +} + +void setAttrs(const pid_t nsPid, const std::string& netdev, const Attrs& attrs) +{ + const set supportedAttrs{"flags", "change", "type", "mtu", "link", "ipv4", "ipv6"}; + + LOGT("Setting network device informations: " << netdev); + validateNetdevName(netdev); + for (const auto& attr : attrs) { + if (supportedAttrs.find(get<0>(attr)) == supportedAttrs.end()) { + throw VasumException("Unsupported attribute: " + get<0>(attr)); + } + } + + NetlinkMessage nlm(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK); + ifinfomsg infoPeer = utils::make_clean(); + infoPeer.ifi_family = AF_UNSPEC; + infoPeer.ifi_index = getInterfaceIndex(netdev, nsPid); + infoPeer.ifi_change = 0xFFFFFFFF; + for (const auto& attr : attrs) { + if (get<0>(attr) == "flags") { + infoPeer.ifi_flags = stoul(get<1>(attr)); + } + if (get<0>(attr) == "change") { + infoPeer.ifi_change = stoul(get<1>(attr)); + } + if (get<0>(attr) == "type") { + infoPeer.ifi_type = stoul(get<1>(attr)); + } + } + nlm.put(infoPeer); + for (const auto& attr : attrs) { + if (get<0>(attr) == "mtu") { + nlm.put(IFLA_MTU, stoul(get<1>(attr))); + } + if (get<0>(attr) == "link") { + nlm.put(IFLA_LINK, stoul(get<1>(attr))); + } + } + + NetlinkResponse response = send(nlm, nsPid); + if (!response.hasMessage()) { + throw VasumException("Can't set interface information"); + } + + //TODO: Multiple addresses should be set at once (add support NLM_F_MULTI to NetlinkMessage). + vector ipv4; + vector ipv6; + for (const auto& attr : attrs) { + if (get<0>(attr) == "ipv4") { + ipv4.push_back(get<1>(attr)); + } + if (get<0>(attr) == "ipv6") { + ipv6.push_back(get<1>(attr)); + } + } + + auto setIp = [nsPid](const vector& ips, uint32_t index, int family) -> void { + using namespace boost::algorithm; + for (const auto& ip : ips) { + Attrs attrs; + vector params; + for (const auto& addrAttr : split(params, ip, is_any_of(","))) { + size_t pos = addrAttr.find(":"); + if (pos == string::npos || pos == addrAttr.length()) { + LOGE("Wrong input data format: ill formed address attribute: " << addrAttr); + VasumException("Wrong input data format: ill formed address attribute"); + } + attrs.push_back(make_tuple(addrAttr.substr(0, pos), addrAttr.substr(pos + 1))); + } + setIpAddresses(nsPid, index, attrs, family); + } + }; + + setIp(ipv4, infoPeer.ifi_index, AF_INET); + setIp(ipv6, infoPeer.ifi_index, AF_INET6); +} } //namespace netdev } //namespace vasum diff --git a/server/netdev.hpp b/server/netdev.hpp index 0e9bfde..5e5821d 100644 --- a/server/netdev.hpp +++ b/server/netdev.hpp @@ -27,12 +27,15 @@ #include #include +#include #include #include namespace vasum { namespace netdev { +typedef std::vector> Attrs; + void createVeth(const pid_t& nsPid, const std::string& nsDev, const std::string& hostDev); void createMacvlan(const pid_t& nsPid, const std::string& nsDev, @@ -51,6 +54,9 @@ void destroyNetdev(const std::string& netdev, const pid_t pid = 0); */ void createBridge(const std::string& netdev); +Attrs getAttrs(const pid_t nsPid, const std::string& netdev); +void setAttrs(const pid_t nsPid, const std::string& netdev, const Attrs& attrs); + } //namespace netdev } //namespace vasum diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index 29577f8..b584279 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -307,14 +307,14 @@ void ZoneAdmin::destroyNetdev(const std::string& devId) netdev::destroyNetdev(devId, mZone.getInitPid()); } -void ZoneAdmin::setNetdevAttrs(const std::string& /* netdev */, const NetdevAttrs& /* attrs */) +void ZoneAdmin::setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs) { - throw ZoneOperationException("Not implemented"); + netdev::setAttrs(mZone.getInitPid(), netdev, attrs); } -ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& /* netdev */) +ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& netdev) { - throw ZoneOperationException("Not implemented"); + return netdev::getAttrs(mZone.getInitPid(), netdev); } std::vector ZoneAdmin::getNetdevList() diff --git a/server/zone-admin.hpp b/server/zone-admin.hpp index c6d26f0..db2b0f2 100644 --- a/server/zone-admin.hpp +++ b/server/zone-admin.hpp @@ -28,7 +28,7 @@ #include "zone-config.hpp" #include "lxc/zone.hpp" - +#include "netdev.hpp" namespace vasum { @@ -41,7 +41,7 @@ enum class SchedulerLevel { class ZoneAdmin { public: - typedef std::vector> NetdevAttrs; + typedef netdev::Attrs NetdevAttrs; /** * ZoneAdmin constructor diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index 91d0540..234dabb 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -40,8 +40,10 @@ #include #include #include +#include #include #include +#include using namespace vasum; using namespace vasum::netdev; @@ -169,8 +171,6 @@ BOOST_AUTO_TEST_CASE(ListNetdevTest) NetdevList hostNetdevs = netdev::listNetdev(0); // Check if we get interfaces from zone net namespace BOOST_CHECK(hostNetdevs != netdevs); - - c->stop(false); } BOOST_AUTO_TEST_CASE(CreateNetdevVethTest) @@ -206,7 +206,147 @@ BOOST_AUTO_TEST_CASE(CreateNetdevMacvlanTest) c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); NetdevList netdevs = c->getNetdevList(); BOOST_CHECK(find(netdevs.begin(), netdevs.end(), ZONE_NETDEV) != netdevs.end()); - c->stop(false); +} + +BOOST_AUTO_TEST_CASE(GetNetdevAttrsTest) +{ + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + ZoneAdmin::NetdevAttrs attrs = c->getNetdevAttrs(ZONE_NETDEV); + bool gotMtu = false; + bool gotFlags = false; + bool gotType = false; + for (auto& attr : attrs) { + if (std::get<0>(attr) == "mtu") { + BOOST_CHECK(!gotMtu); + gotMtu = true; + } else if (std::get<0>(attr) == "flags") { + BOOST_CHECK(!gotFlags); + BOOST_CHECK(IFF_BROADCAST & stol(std::get<1>(attr))); + gotFlags = true; + } else if (std::get<0>(attr) == "type") { + BOOST_CHECK(!gotType); + BOOST_CHECK_EQUAL(1 /*IFF_802_1Q_VLAN */, stol(std::get<1>(attr))); + gotType = true; + } else { + BOOST_CHECK_MESSAGE(false, "Got unexpected option " + std::get<0>(attr)); + } + } + BOOST_CHECK(gotMtu); + BOOST_CHECK(gotFlags); + BOOST_CHECK(gotType); +} + +BOOST_AUTO_TEST_CASE(SetNetdevAttrsTest) +{ + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + ZoneAdmin::NetdevAttrs attrsIn; + attrsIn.push_back(std::make_tuple("mtu", "500")); + c->setNetdevAttrs(ZONE_NETDEV, attrsIn); + + bool gotMtu = false; + ZoneAdmin::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); + for (auto& attr : attrsOut) { + if (std::get<0>(attr) == "mtu") { + BOOST_CHECK(!gotMtu); + BOOST_CHECK_EQUAL(std::get<1>(attr), "500"); + gotMtu = true; + } + } + BOOST_CHECK(gotMtu); + + attrsIn.clear(); + attrsIn.push_back(std::make_tuple("does_not_exists", "500")); + BOOST_REQUIRE_EXCEPTION(c->setNetdevAttrs(ZONE_NETDEV, attrsIn), + VasumException, + WhatEquals("Unsupported attribute: does_not_exists")); +} + +BOOST_AUTO_TEST_CASE(SetNetdevIpv4Test) +{ + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + ZoneAdmin::NetdevAttrs attrsIn; + attrsIn.push_back(std::make_tuple("ipv4", "ip:192.168.4.1,prefixlen:24")); + c->setNetdevAttrs(ZONE_NETDEV, attrsIn); + + ZoneAdmin::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); + int gotIp = 0; + for (auto& attr : attrsOut) { + if (std::get<0>(attr) == "ipv4") { + BOOST_CHECK(std::get<1>(attr).find("ip:192.168.4.1") != std::string::npos); + BOOST_CHECK(std::get<1>(attr).find("prefixlen:24") != std::string::npos); + gotIp++; + } + } + BOOST_CHECK_EQUAL(gotIp, 1); + + attrsIn.clear(); + attrsIn.push_back(std::make_tuple("ipv4", "ip:192.168.4.2,prefixlen:24")); + attrsIn.push_back(std::make_tuple("ipv4", "ip:192.168.4.3,prefixlen:24")); + c->setNetdevAttrs(ZONE_NETDEV, attrsIn); + attrsOut = c->getNetdevAttrs(ZONE_NETDEV); + gotIp = 0; + for (auto& attr : attrsOut) { + if (std::get<0>(attr) == "ipv4") { + BOOST_CHECK(std::get<1>(attr).find("ip:192.168.4.1") != std::string::npos || + std::get<1>(attr).find("ip:192.168.4.2") != std::string::npos || + std::get<1>(attr).find("ip:192.168.4.3") != std::string::npos); + BOOST_CHECK(std::get<1>(attr).find("prefixlen:24") != std::string::npos); + gotIp++; + } + } + BOOST_CHECK_EQUAL(gotIp, 3); +} + +BOOST_AUTO_TEST_CASE(SetNetdevIpv6Test) +{ + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + ZoneAdmin::NetdevAttrs attrsIn; + attrsIn.push_back(std::make_tuple("ipv6", "ip:2001:db8::1,prefixlen:64")); + c->setNetdevAttrs(ZONE_NETDEV, attrsIn); + + ZoneAdmin::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); + int gotIp = 0; + for (auto& attr : attrsOut) { + if (std::get<0>(attr) == "ipv6") { + BOOST_CHECK(std::get<1>(attr).find("ip:2001:db8::1") != std::string::npos); + BOOST_CHECK(std::get<1>(attr).find("prefixlen:64") != std::string::npos); + gotIp++; + } + } + BOOST_CHECK_EQUAL(gotIp, 1); + + attrsIn.clear(); + attrsIn.push_back(std::make_tuple("ipv6", "ip:2001:db8::2,prefixlen:64")); + attrsIn.push_back(std::make_tuple("ipv6", "ip:2001:db8::3,prefixlen:64")); + c->setNetdevAttrs(ZONE_NETDEV, attrsIn); + attrsOut = c->getNetdevAttrs(ZONE_NETDEV); + gotIp = 0; + for (auto& attr : attrsOut) { + if (std::get<0>(attr) == "ipv6") { + BOOST_CHECK(std::get<1>(attr).find("ip:2001:db8::1") != std::string::npos || + std::get<1>(attr).find("ip:2001:db8::2") != std::string::npos || + std::get<1>(attr).find("ip:2001:db8::3") != std::string::npos); + BOOST_CHECK(std::get<1>(attr).find("prefixlen:64") != std::string::npos); + gotIp++; + } + } + BOOST_CHECK_EQUAL(gotIp, 3); } BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 9a6ea1bd77132efc3490e427fd257deaac230f10 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Wed, 25 Mar 2015 11:57:30 +0100 Subject: [PATCH 05/16] Cleanup test case names [Feature] Renamed test case names [Cause] Inconsistent test case names [Solution] Rename tests, keep the naming consistent [Verification] Build, install, run tests Change-Id: I76da5f2bedcbe361ebcd5d4a612129a867599a16 --- tests/unit_tests/client/ut-client-utils.cpp | 2 +- tests/unit_tests/client/ut-client.cpp | 28 ++++++++-------- tests/unit_tests/config/ut-configuration.cpp | 20 +++++------ tests/unit_tests/config/ut-kvstore.cpp | 18 +++++----- tests/unit_tests/dbus/ut-connection.cpp | 40 +++++++++++----------- tests/unit_tests/ipc/ut-ipc.cpp | 2 +- tests/unit_tests/log/ut-logger.cpp | 16 ++++----- tests/unit_tests/lxc/ut-zone.cpp | 16 ++++----- tests/unit_tests/server/ut-input-monitor.cpp | 14 ++++---- tests/unit_tests/server/ut-server.cpp | 10 +++--- tests/unit_tests/server/ut-zone-admin.cpp | 16 ++++----- tests/unit_tests/server/ut-zone-connection.cpp | 8 ++--- tests/unit_tests/server/ut-zone-provision.cpp | 20 +++++------ tests/unit_tests/server/ut-zone.cpp | 16 ++++----- tests/unit_tests/server/ut-zones-manager.cpp | 44 ++++++++++++------------- tests/unit_tests/utils/ut-callback-guard.cpp | 6 ++-- tests/unit_tests/utils/ut-counting-map.cpp | 2 +- tests/unit_tests/utils/ut-fs.cpp | 12 +++---- tests/unit_tests/utils/ut-glib-loop.cpp | 2 +- tests/unit_tests/utils/ut-paths.cpp | 4 +-- tests/unit_tests/utils/ut-same-thread-guard.cpp | 4 +-- tests/unit_tests/utils/ut-value-latch.cpp | 12 +++---- tests/unit_tests/utils/ut-worker.cpp | 14 ++++---- 23 files changed, 163 insertions(+), 163 deletions(-) diff --git a/tests/unit_tests/client/ut-client-utils.cpp b/tests/unit_tests/client/ut-client-utils.cpp index 140238a..459a1b1 100644 --- a/tests/unit_tests/client/ut-client-utils.cpp +++ b/tests/unit_tests/client/ut-client-utils.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE(ClientUtils) -BOOST_AUTO_TEST_CASE(ParseZoneIdFromCpuSetTest) +BOOST_AUTO_TEST_CASE(ParseZoneIdFromCpuSet) { auto testBad = [](const std::string& input) { std::string ret; diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index ce31795..197da5e 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -151,7 +151,7 @@ std::ostream& operator<<(std::ostream& out, VsmStatus status) BOOST_FIXTURE_TEST_SUITE(ClientSuite, Fixture) -BOOST_AUTO_TEST_CASE(NotRunningServerTest) +BOOST_AUTO_TEST_CASE(NotRunningServer) { cm.shutdownAll(); @@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(NotRunningServerTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(GetZoneDbusesTest) +BOOST_AUTO_TEST_CASE(GetZoneDbuses) { VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(GetZoneDbusesTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(GetZoneIdsTest) +BOOST_AUTO_TEST_CASE(GetZoneIds) { VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIdsTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(GetActiveZoneIdTest) +BOOST_AUTO_TEST_CASE(GetActiveZoneId) { VsmClient client = vsm_client_create(); VsmStatus status = vsm_connect(client); @@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneIdTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(SetActiveZoneTest) +BOOST_AUTO_TEST_CASE(SetActiveZone) { const std::string newActiveZoneId = "zone2"; @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(SetActiveZoneTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(CreateZoneTest) +BOOST_AUTO_TEST_CASE(CreateZone) { const std::string newActiveZoneId = ""; @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(CreateZoneTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(StartShutdownZoneTest) +BOOST_AUTO_TEST_CASE(StartShutdownZone) { const std::string newActiveZoneId = "zone1"; @@ -262,7 +262,7 @@ BOOST_AUTO_TEST_CASE(StartShutdownZoneTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(LockUnlockZoneTest) +BOOST_AUTO_TEST_CASE(LockUnlockZone) { const std::string newActiveZoneId = "zone2"; @@ -276,7 +276,7 @@ BOOST_AUTO_TEST_CASE(LockUnlockZoneTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(FileMoveRequestTest) +BOOST_AUTO_TEST_CASE(FileMoveRequest) { const std::string path = "/tmp/fake_path"; const std::string secondZone = "fake_zone"; @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(FileMoveRequestTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(NotificationTest) +BOOST_AUTO_TEST_CASE(Notification) { const std::string MSG_CONTENT = "msg"; const std::string MSG_APP = "app"; @@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE(NotificationTest) } } -BOOST_AUTO_TEST_CASE(GetZoneIdByPidTest1) +BOOST_AUTO_TEST_CASE(GetZoneIdByPidTestSingle) { VsmClient client = vsm_client_create(); VsmString zone; @@ -359,7 +359,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIdByPidTest1) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(GetZoneIdByPidTest2) +BOOST_AUTO_TEST_CASE(GetZoneIdByPidTestMultiple) { std::set ids; @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIdByPidTest2) } } -BOOST_AUTO_TEST_CASE(GrantRevokeTest) +BOOST_AUTO_TEST_CASE(GrantRevoke) { const std::string zoneId = "zone2"; const std::string dev = "tty3"; @@ -405,7 +405,7 @@ BOOST_AUTO_TEST_CASE(GrantRevokeTest) vsm_client_free(client); } -BOOST_AUTO_TEST_CASE(ProvisionTest) +BOOST_AUTO_TEST_CASE(Provision) { VsmClient client = vsm_client_create(); BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, vsm_connect(client)); diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index 8049975..a9a5332 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -52,7 +52,7 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(ConfigurationSuite, Fixture) -BOOST_AUTO_TEST_CASE(FromJsonStringTest) +BOOST_AUTO_TEST_CASE(FromJsonString) { TestConfig testConfig; @@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(FromJsonStringTest) } -BOOST_AUTO_TEST_CASE(ToJsonStringTest) +BOOST_AUTO_TEST_CASE(ToJsonString) { TestConfig testConfig; BOOST_REQUIRE_NO_THROW(loadFromJsonString(jsonTestString, testConfig)); @@ -153,7 +153,7 @@ struct UnionConfig { } // namespace loadErrorsTest -BOOST_AUTO_TEST_CASE(JsonLoadErrorsTest) +BOOST_AUTO_TEST_CASE(JsonLoadErrors) { using namespace loadErrorsTest; @@ -256,7 +256,7 @@ struct NotFunction { } // namespace hasVisitableTest -BOOST_AUTO_TEST_CASE(HasVisibleInternalHelperTest) +BOOST_AUTO_TEST_CASE(HasVisibleInternalHelper) { using namespace hasVisitableTest; @@ -273,7 +273,7 @@ BOOST_AUTO_TEST_CASE(HasVisibleInternalHelperTest) BOOST_CHECK(isVisitable()); } -BOOST_AUTO_TEST_CASE(FromToKVStoreTest) +BOOST_AUTO_TEST_CASE(FromToKVStore) { TestConfig config; loadFromJsonString(jsonTestString, config); @@ -286,7 +286,7 @@ BOOST_AUTO_TEST_CASE(FromToKVStoreTest) BOOST_CHECK_EQUAL(out, jsonTestString); } -BOOST_AUTO_TEST_CASE(FromToFDTest) +BOOST_AUTO_TEST_CASE(FromToFD) { TestConfig config; loadFromJsonString(jsonTestString, config); @@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(FromToFDTest) BOOST_CHECK(::close(fd) >= 0); } -BOOST_AUTO_TEST_CASE(FromKVWithDefaultsTest) +BOOST_AUTO_TEST_CASE(FromKVWithDefaults) { TestConfig config; loadFromJsonString(jsonTestString, config); @@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(FromKVWithDefaultsTest) BOOST_CHECK_EQUAL(out2, jsonTestString); } -BOOST_AUTO_TEST_CASE(PartialConfigTest) +BOOST_AUTO_TEST_CASE(PartialConfig) { // check if partial config is fully supported TestConfig config; @@ -379,7 +379,7 @@ BOOST_AUTO_TEST_CASE(PartialConfigTest) } } -BOOST_AUTO_TEST_CASE(ConfigUnionTest) +BOOST_AUTO_TEST_CASE(ConfigUnion) { TestConfig testConfig; BOOST_REQUIRE_NO_THROW(loadFromJsonString(jsonTestString, testConfig)); @@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(ConfigUnionTest) } -BOOST_AUTO_TEST_CASE(GVariantVisitorTest) +BOOST_AUTO_TEST_CASE(GVariantVisitor) { TestConfig testConfig; BOOST_REQUIRE_NO_THROW(loadFromJsonString(jsonTestString, testConfig)); diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp index 1129bdf..239f568 100644 --- a/tests/unit_tests/config/ut-kvstore.cpp +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -98,7 +98,7 @@ BOOST_FIXTURE_TEST_SUITE(KVStoreSuite, Fixture) const std::string KEY = "KEY"; -BOOST_AUTO_TEST_CASE(SimpleConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(SimpleConstructorDestructor) { std::unique_ptr conPtr; BOOST_REQUIRE_NO_THROW(conPtr.reset(new KVStore(dbPath))); @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(SimpleConstructorDestructorTest) BOOST_CHECK(fs::exists(dbPath)); } -BOOST_AUTO_TEST_CASE(EscapedCharactersTest) +BOOST_AUTO_TEST_CASE(EscapedCharacters) { // '*' ?' '[' ']' are escaped // They shouldn't influence the internal implementation @@ -162,7 +162,7 @@ void testSingleValue(Fixture& f, const A& a, const B& b) } // namespace -BOOST_AUTO_TEST_CASE(SingleValueTest) +BOOST_AUTO_TEST_CASE(SingleValue) { testSingleValue(*this, "A", "B"); testSingleValue(*this, 1, 2); @@ -202,7 +202,7 @@ void testVectorOfValues(Fixture& f, } } // namespace -BOOST_AUTO_TEST_CASE(VectorOfValuesTest) +BOOST_AUTO_TEST_CASE(VectorOfValues) { testVectorOfValues(*this, {"A", "B"}, {"A", "C"}, {"A", "B", "C"}); testVectorOfValues(*this, {1, 2}, {1, 3}, {1, 2, 3}); @@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE(VectorOfValuesTest) testVectorOfValues(*this, {1, 2}, {1, 3}, {1, 2, 3}); } -BOOST_AUTO_TEST_CASE(ClearTest) +BOOST_AUTO_TEST_CASE(Clear) { BOOST_CHECK_NO_THROW(c.clear()); std::vector vec = {"A", "B"}; @@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(ClearTest) BOOST_CHECK_THROW(c.get(KEY), ConfigException); } -BOOST_AUTO_TEST_CASE(TransactionTest) +BOOST_AUTO_TEST_CASE(Transaction) { { KVStore::Transaction trans(c); @@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE(TransactionTest) } } -BOOST_AUTO_TEST_CASE(TransactionStackedTest) +BOOST_AUTO_TEST_CASE(TransactionStacked) { { KVStore::Transaction transOuter(c); @@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(TransactionStackedTest) } } -BOOST_AUTO_TEST_CASE(TransactionThreadsTest) +BOOST_AUTO_TEST_CASE(TransactionThreads) { Latch trans1Started, trans1Release, trans2Released; std::thread thread1([&] { @@ -306,7 +306,7 @@ BOOST_AUTO_TEST_CASE(TransactionThreadsTest) thread2.join(); } -BOOST_AUTO_TEST_CASE(KeyTest) +BOOST_AUTO_TEST_CASE(Key) { BOOST_CHECK_EQUAL(key(), ""); BOOST_CHECK_EQUAL(key<>(), ""); diff --git a/tests/unit_tests/dbus/ut-connection.cpp b/tests/unit_tests/dbus/ut-connection.cpp index e52778e..84ea626 100644 --- a/tests/unit_tests/dbus/ut-connection.cpp +++ b/tests/unit_tests/dbus/ut-connection.cpp @@ -96,24 +96,24 @@ std::string getInterfaceFromIntrospectionXML(const std::string& xml, const std:: } // namespace -BOOST_AUTO_TEST_CASE(DbusDaemonTest) +BOOST_AUTO_TEST_CASE(DbusDaemon) { ScopedDbusDaemon daemon; } -BOOST_AUTO_TEST_CASE(NoDbusTest) +BOOST_AUTO_TEST_CASE(NoDbus) { ScopedGlibLoop loop; BOOST_CHECK_THROW(DbusConnection::create(DBUS_ADDRESS), DbusIOException); } -BOOST_AUTO_TEST_CASE(ConnectionTest) +BOOST_AUTO_TEST_CASE(Connection) { ScopedGlibLoop loop; DbusConnection::Pointer connSystem = DbusConnection::createSystem(); } -BOOST_AUTO_TEST_CASE(SimpleTest) +BOOST_AUTO_TEST_CASE(Simple) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(SimpleTest) BOOST_CHECK(nameLost.empty()); } -BOOST_AUTO_TEST_CASE(ConnectionLostTest) +BOOST_AUTO_TEST_CASE(ConnectionLost) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -147,7 +147,7 @@ BOOST_AUTO_TEST_CASE(ConnectionLostTest) BOOST_CHECK(nameLost.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(NameOwnerTest) +BOOST_AUTO_TEST_CASE(NameOwner) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(NameOwnerTest) //BOOST_CHECK(nameAcquired2.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(GenericSignalTest) +BOOST_AUTO_TEST_CASE(GenericSignal) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(GenericSignalTest) BOOST_CHECK(signalEmitted.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(FilteredSignalTest) +BOOST_AUTO_TEST_CASE(FilteredSignal) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(FilteredSignalTest) BOOST_CHECK(wrongSignalEmitted.empty()); } -BOOST_AUTO_TEST_CASE(RegisterObjectTest) +BOOST_AUTO_TEST_CASE(RegisterObject) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(RegisterObjectTest) BOOST_CHECK_NO_THROW(conn->registerObject(TESTAPI_OBJECT_PATH, TESTAPI_DEFINITION, callback)); } -BOOST_AUTO_TEST_CASE(IntrospectSystemTest) +BOOST_AUTO_TEST_CASE(IntrospectSystem) { ScopedGlibLoop loop; DbusConnection::Pointer conn = DbusConnection::createSystem(); @@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE(IntrospectSystemTest) BOOST_CHECK(!iface.empty()); } -BOOST_AUTO_TEST_CASE(IntrospectTest) +BOOST_AUTO_TEST_CASE(Introspect) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(IntrospectTest) BOOST_CHECK(std::string::npos != iface.find(TESTAPI_SIGNAL_NOTIFY)); } -BOOST_AUTO_TEST_CASE(MethodCallTest) +BOOST_AUTO_TEST_CASE(MethodCall) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -372,7 +372,7 @@ BOOST_AUTO_TEST_CASE(MethodCallTest) DbusCustomException); } -BOOST_AUTO_TEST_CASE(MethodAsyncCallTest) +BOOST_AUTO_TEST_CASE(MethodAsyncCall) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallTest) BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(MethodAsyncCallAsyncHandlerTest) +BOOST_AUTO_TEST_CASE(MethodAsyncCallAsyncHandler) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -513,7 +513,7 @@ BOOST_AUTO_TEST_CASE(MethodAsyncCallAsyncHandlerTest) BOOST_REQUIRE(callDone.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(MethodCallExceptionTest) +BOOST_AUTO_TEST_CASE(MethodCallException) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -559,7 +559,7 @@ BOOST_AUTO_TEST_CASE(MethodCallExceptionTest) DbusOperationException); } -BOOST_AUTO_TEST_CASE(DbusApiTest) +BOOST_AUTO_TEST_CASE(DbusApi) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -575,7 +575,7 @@ BOOST_AUTO_TEST_CASE(DbusApiTest) WhatEquals("Argument: 666")); } -BOOST_AUTO_TEST_CASE(DbusApiNotifyTest) +BOOST_AUTO_TEST_CASE(DbusApiNotify) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -594,7 +594,7 @@ BOOST_AUTO_TEST_CASE(DbusApiNotifyTest) BOOST_CHECK(notified.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(DbusApiNameAcquiredTest) +BOOST_AUTO_TEST_CASE(DbusApiNameAcquired) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -606,7 +606,7 @@ BOOST_AUTO_TEST_CASE(DbusApiNameAcquiredTest) BOOST_CHECK_NO_THROW(client.noop()); } -BOOST_AUTO_TEST_CASE(DbusApiConnectionLost1Test) +BOOST_AUTO_TEST_CASE(DbusApiConnectionLost) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; @@ -622,7 +622,7 @@ BOOST_AUTO_TEST_CASE(DbusApiConnectionLost1Test) BOOST_CHECK_THROW(client.noop(), DbusIOException); } -BOOST_AUTO_TEST_CASE(DbusApiConnectionLost2Test) +BOOST_AUTO_TEST_CASE(DbusApiConnectionLostDelayedCallbackSet) { ScopedDbusDaemon daemon; ScopedGlibLoop loop; diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index 8f47a65..6f2765b 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -702,7 +702,7 @@ MULTI_FIXTURE_TEST_CASE(MixOperations, F, ThreadedFixture, GlibFixture) BOOST_CHECK(l.wait(TIMEOUT)); } -// MULTI_FIXTURE_TEST_CASE(ConnectionLimitTest, F, ThreadedFixture, GlibFixture) +// MULTI_FIXTURE_TEST_CASE(ConnectionLimit, F, ThreadedFixture, GlibFixture) // { // unsigned oldLimit = ipc::getMaxFDNumber(); // ipc::setMaxFDNumber(50); diff --git a/tests/unit_tests/log/ut-logger.cpp b/tests/unit_tests/log/ut-logger.cpp index ef3634e..36f52e3 100644 --- a/tests/unit_tests/log/ut-logger.cpp +++ b/tests/unit_tests/log/ut-logger.cpp @@ -97,7 +97,7 @@ void exampleTestLogs(void) } // namespace -BOOST_AUTO_TEST_CASE(LogLevelSetandGet) +BOOST_AUTO_TEST_CASE(LogLevelSetAndGet) { Logger::setLogLevel(LogLevel::TRACE); BOOST_CHECK(LogLevel::TRACE == Logger::getLogLevel()); @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(LogLevelSetandGet) BOOST_CHECK(LogLevel::ERROR == Logger::getLogLevel()); } -BOOST_AUTO_TEST_CASE(StringLogLevelSetandGet) +BOOST_AUTO_TEST_CASE(StringLogLevelSetAndGet) { Logger::setLogLevel("TRACE"); BOOST_CHECK(LogLevel::TRACE == Logger::getLogLevel()); @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(StringLogLevelSetandGet) WhatEquals("Invalid LogLevel to parse")); //TODO change message } -BOOST_AUTO_TEST_CASE(TestLogsError) +BOOST_AUTO_TEST_CASE(LogsLevelError) { TestLog tf(LogLevel::ERROR); exampleTestLogs(); @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(TestLogsError) BOOST_CHECK(tf.logContains("[TRACE]") == false); } -BOOST_AUTO_TEST_CASE(TestLogsWarn) +BOOST_AUTO_TEST_CASE(LogsLevelWarn) { TestLog tf(LogLevel::WARN); exampleTestLogs(); @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(TestLogsWarn) BOOST_CHECK(tf.logContains("[TRACE]") == false); } -BOOST_AUTO_TEST_CASE(TestLogsInfo) +BOOST_AUTO_TEST_CASE(LogsLevelInfo) { TestLog tf(LogLevel::INFO); exampleTestLogs(); @@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(TestLogsInfo) BOOST_CHECK(tf.logContains("[TRACE]") == false); } -BOOST_AUTO_TEST_CASE(TestLogsDebug) +BOOST_AUTO_TEST_CASE(LogsLevelDebug) { TestLog tf(LogLevel::DEBUG); exampleTestLogs(); @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(TestLogsDebug) BOOST_CHECK(tf.logContains("[TRACE]") == false); } -BOOST_AUTO_TEST_CASE(TestLogsTrace) +BOOST_AUTO_TEST_CASE(LogsLevelTrace) { TestLog tf(LogLevel::TRACE); exampleTestLogs(); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(TestLogsTrace) BOOST_CHECK(tf.logContains("[TRACE]") == true); } -BOOST_AUTO_TEST_CASE(TestLoggerScope) +BOOST_AUTO_TEST_CASE(LoggerScope) { LOGS("Main function scope"); diff --git a/tests/unit_tests/lxc/ut-zone.cpp b/tests/unit_tests/lxc/ut-zone.cpp index 3b375bd..194a2a6 100644 --- a/tests/unit_tests/lxc/ut-zone.cpp +++ b/tests/unit_tests/lxc/ut-zone.cpp @@ -80,12 +80,12 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(LxcZoneSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { LxcZone lxc(LXC_PATH, ZONE_NAME); } -BOOST_AUTO_TEST_CASE(CreateDestroyTest) +BOOST_AUTO_TEST_CASE(CreateDestroy) { LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(!lxc.isDefined()); @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyTest) BOOST_CHECK(!lxc.isDefined()); } -BOOST_AUTO_TEST_CASE(StartShutdownTest) +BOOST_AUTO_TEST_CASE(StartShutdown) { { LxcZone lxc(LXC_PATH, ZONE_NAME); @@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE(StartShutdownTest) BOOST_CHECK(lxc.destroy()); } -BOOST_AUTO_TEST_CASE(StartStopTest) +BOOST_AUTO_TEST_CASE(StartStop) { { LxcZone lxc(LXC_PATH, ZONE_NAME); @@ -149,7 +149,7 @@ BOOST_AUTO_TEST_CASE(StartStopTest) BOOST_CHECK(lxc.destroy()); } -BOOST_AUTO_TEST_CASE(StartHasStoppedTest) +BOOST_AUTO_TEST_CASE(StartHasStopped) { { LxcZone lxc(LXC_PATH, ZONE_NAME); @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(StartHasStoppedTest) BOOST_CHECK(lxc.destroy()); } -BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) +BOOST_AUTO_TEST_CASE(FreezeUnfreeze) { LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); @@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(FreezeUnfreezeTest) BOOST_CHECK(lxc.destroy()); } -BOOST_AUTO_TEST_CASE(FreezeStopTest) +BOOST_AUTO_TEST_CASE(FreezeStop) { LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(FreezeStopTest) BOOST_CHECK(lxc.destroy()); } -BOOST_AUTO_TEST_CASE(RepeatTest) +BOOST_AUTO_TEST_CASE(Repeat) { LxcZone lxc(LXC_PATH, ZONE_NAME); BOOST_CHECK(lxc.create(TEMPLATE, TEMPLATE_ARGS)); diff --git a/tests/unit_tests/server/ut-input-monitor.cpp b/tests/unit_tests/server/ut-input-monitor.cpp index 3560b40..454a307 100644 --- a/tests/unit_tests/server/ut-input-monitor.cpp +++ b/tests/unit_tests/server/ut-input-monitor.cpp @@ -89,12 +89,12 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(InputMonitorSuite, Fixture) -BOOST_AUTO_TEST_CASE(Config_OK) +BOOST_AUTO_TEST_CASE(ConfigOK) { InputMonitor inputMonitor(inputConfig, InputMonitor::NotifyCallback()); } -BOOST_AUTO_TEST_CASE(Config_timeWindowMsTooHigh) +BOOST_AUTO_TEST_CASE(ConfigTimeWindowMsTooHigh) { inputConfig.timeWindowMs = 50000; @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(Config_timeWindowMsTooHigh) WhatEquals("Time window exceeds maximum")); } -BOOST_AUTO_TEST_CASE(Config_deviceFilePathNotExisting) +BOOST_AUTO_TEST_CASE(ConfigDeviceFilePathNotExisting) { inputConfig.device = TEST_INPUT_DEVICE + "notExisting"; @@ -148,12 +148,12 @@ void sendNEvents(Fixture& f, unsigned int noOfEventsToSend) } // namespace -BOOST_AUTO_TEST_CASE(Event_oneAtATime) +BOOST_AUTO_TEST_CASE(EventOneAtATime) { sendNEvents(*this, 1); } -BOOST_AUTO_TEST_CASE(Event_tenAtATime) +BOOST_AUTO_TEST_CASE(EventTenAtATime) { sendNEvents(*this, 10); } @@ -199,12 +199,12 @@ void sendNEventsWithPauses(Fixture& f, unsigned int noOfEventsToSend) } // namespace -BOOST_AUTO_TEST_CASE(Event_oneAtATimeWithPauses) +BOOST_AUTO_TEST_CASE(EventOneAtATimeWithPauses) { sendNEventsWithPauses(*this, 1); } -BOOST_AUTO_TEST_CASE(Event_tenAtATimeWithPauses) +BOOST_AUTO_TEST_CASE(EventTenAtATimeWithPauses) { sendNEventsWithPauses(*this, 10); } diff --git a/tests/unit_tests/server/ut-server.cpp b/tests/unit_tests/server/ut-server.cpp index eccea8a..8466f19 100644 --- a/tests/unit_tests/server/ut-server.cpp +++ b/tests/unit_tests/server/ut-server.cpp @@ -73,34 +73,34 @@ BOOST_FIXTURE_TEST_SUITE(ServerSuite, Fixture) using namespace vasum; using namespace config; -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { std::unique_ptr s; s.reset(new Server(TEST_CONFIG_PATH)); s.reset(); } -BOOST_AUTO_TEST_CASE(MissingConfigTest) +BOOST_AUTO_TEST_CASE(MissingConfig) { BOOST_REQUIRE_EXCEPTION(Server(MISSING_CONFIG_PATH).run(AS_ROOT), ConfigException, WhatEquals("Could not load " + MISSING_CONFIG_PATH)); } -BOOST_AUTO_TEST_CASE(TerminateTest) +BOOST_AUTO_TEST_CASE(Terminate) { Server s(TEST_CONFIG_PATH); s.terminate(); } -BOOST_AUTO_TEST_CASE(TerminateRunTest) +BOOST_AUTO_TEST_CASE(TerminateRun) { Server s(TEST_CONFIG_PATH); s.terminate(); s.run(AS_ROOT); } -BOOST_AUTO_TEST_CASE(RunTerminateTest) +BOOST_AUTO_TEST_CASE(RunTerminate) { Server s(TEST_CONFIG_PATH); std::future runFuture = std::async(std::launch::async, [&] {s.run(AS_ROOT);}); diff --git a/tests/unit_tests/server/ut-zone-admin.cpp b/tests/unit_tests/server/ut-zone-admin.cpp index c711169..3aa38d1 100644 --- a/tests/unit_tests/server/ut-zone-admin.cpp +++ b/tests/unit_tests/server/ut-zone-admin.cpp @@ -79,20 +79,20 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(ZoneAdminSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { auto admin = create(TEST_CONFIG_PATH); admin.reset(); } -BOOST_AUTO_TEST_CASE(MissingConfigTest) +BOOST_AUTO_TEST_CASE(MissingConfig) { BOOST_REQUIRE_EXCEPTION(create(MISSING_CONFIG_PATH), ZoneOperationException, WhatEquals("Could not create zone")); } -BOOST_AUTO_TEST_CASE(StartTest) +BOOST_AUTO_TEST_CASE(Start) { auto admin = create(TEST_CONFIG_PATH); @@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(StartTest) BOOST_CHECK(admin->isRunning()); } -BOOST_AUTO_TEST_CASE(StartBuggyTest) +BOOST_AUTO_TEST_CASE(StartBuggy) { auto admin = create(BUGGY_CONFIG_PATH); BOOST_REQUIRE_EXCEPTION(admin->start(), @@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(StartBuggyTest) WhatEquals("Could not start zone")); } -BOOST_AUTO_TEST_CASE(StopShutdownTest) +BOOST_AUTO_TEST_CASE(StopShutdown) { auto admin = create(TEST_CONFIG_PATH); @@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE(StopShutdownTest) } // This test needs to wait for a shutdown timer in stop() method. This takes 10s+. -BOOST_AUTO_TEST_CASE(StopDestroyTest) +BOOST_AUTO_TEST_CASE(StopDestroy) { auto admin = create(TEST_NO_SHUTDOWN_CONFIG_PATH); @@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE(StopDestroyTest) BOOST_CHECK(admin->isStopped()); } -BOOST_AUTO_TEST_CASE(SuspendResumeTest) +BOOST_AUTO_TEST_CASE(SuspendResume) { auto admin = create(TEST_NO_SHUTDOWN_CONFIG_PATH); @@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE(SuspendResumeTest) BOOST_CHECK(admin->isRunning()); } -BOOST_AUTO_TEST_CASE(SchedulerLevelTest) +BOOST_AUTO_TEST_CASE(ForegroundBackgroundSchedulerLevel) { auto admin = create(TEST_CONFIG_PATH); diff --git a/tests/unit_tests/server/ut-zone-connection.cpp b/tests/unit_tests/server/ut-zone-connection.cpp index 2a72b87..5f2c63b 100644 --- a/tests/unit_tests/server/ut-zone-connection.cpp +++ b/tests/unit_tests/server/ut-zone-connection.cpp @@ -133,12 +133,12 @@ private: BOOST_FIXTURE_TEST_SUITE(ZoneConnectionSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorConnectTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructorConnect) { ZoneConnection(acquireAddress(), nullptr); } -BOOST_AUTO_TEST_CASE(NotifyActiveZoneApiTest) +BOOST_AUTO_TEST_CASE(NotifyActiveZoneApi) { Latch notifyCalled; ZoneConnection connection(acquireAddress(), nullptr); @@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZoneApiTest) BOOST_CHECK(notifyCalled.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(SignalNotificationApiTest) +BOOST_AUTO_TEST_CASE(SignalNotificationApi) { Latch signalEmitted; ZoneConnection connection(acquireAddress(), nullptr); @@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(SignalNotificationApiTest) BOOST_CHECK(signalEmitted.wait(EVENT_TIMEOUT)); } -BOOST_AUTO_TEST_CASE(SignalDisplayOffApiTest) +BOOST_AUTO_TEST_CASE(SignalDisplayOffApi) { Latch displayOffCalled; ZoneConnection connection(acquireAddress(), nullptr); diff --git a/tests/unit_tests/server/ut-zone-provision.cpp b/tests/unit_tests/server/ut-zone-provision.cpp index 4109cb2..a79a260 100644 --- a/tests/unit_tests/server/ut-zone-provision.cpp +++ b/tests/unit_tests/server/ut-zone-provision.cpp @@ -94,7 +94,7 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(ZoneProvisionSuite, Fixture) -BOOST_AUTO_TEST_CASE(DestructorTest) +BOOST_AUTO_TEST_CASE(Destructor) { const fs::path mountTarget = fs::path("/opt/usr/data/ut-from-host-provision"); const fs::path mountSource = fs::path("/tmp/ut-provision"); @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(DestructorTest) BOOST_CHECK(!fs::exists(mountSource)); } -BOOST_AUTO_TEST_CASE(FileTest) +BOOST_AUTO_TEST_CASE(File) { //TODO: Test Fifo const fs::path regularFile = fs::path("/opt/usr/data/ut-regular-file"); @@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(FileTest) zoneProvision.stop(); } -BOOST_AUTO_TEST_CASE(MountTest) +BOOST_AUTO_TEST_CASE(Mount) { //TODO: Test Fifo const fs::path mountTarget = fs::path("/opt/usr/data/ut-from-host-provision"); @@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(MountTest) zoneProvision.stop(); } -BOOST_AUTO_TEST_CASE(LinkTest) +BOOST_AUTO_TEST_CASE(Link) { const fs::path linkFile = fs::path("/ut-from-host-file.txt"); @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(LinkTest) } } -BOOST_AUTO_TEST_CASE(DeclareFileTest) +BOOST_AUTO_TEST_CASE(DeclareFile) { ZoneProvision zoneProvision = create({}); zoneProvision.declareFile(1, "path", 0747, 0777); @@ -252,7 +252,7 @@ BOOST_AUTO_TEST_CASE(DeclareFileTest) BOOST_CHECK_EQUAL(provision.mode, 0777); } -BOOST_AUTO_TEST_CASE(DeclareMountTest) +BOOST_AUTO_TEST_CASE(DeclareMount) { ZoneProvision zoneProvision = create({}); zoneProvision.declareMount("/fake/path1", "/fake/path2", "tmpfs", 077, "fake"); @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(DeclareMountTest) BOOST_CHECK_EQUAL(provision.data, "fake"); } -BOOST_AUTO_TEST_CASE(DeclareLinkTest) +BOOST_AUTO_TEST_CASE(DeclareLink) { ZoneProvision zoneProvision = create({}); zoneProvision.declareLink("/fake/path1", "/fake/path2"); @@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(DeclareLinkTest) BOOST_CHECK_EQUAL(provision.target, "/fake/path2"); } -BOOST_AUTO_TEST_CASE(ProvisionedAlreadyTest) +BOOST_AUTO_TEST_CASE(ProvisionedAlready) { const fs::path dir = fs::path("/opt/usr/data/ut-from-host"); const fs::path linkFile = fs::path("/ut-from-host-file.txt"); @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(ProvisionedAlreadyTest) zoneProvision.stop(); } -BOOST_AUTO_TEST_CASE(ListTest) +BOOST_AUTO_TEST_CASE(List) { std::vector expected; ZoneProvision zoneProvision = create({}); @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(ListTest) } } -BOOST_AUTO_TEST_CASE(RemoveTest) +BOOST_AUTO_TEST_CASE(Remove) { std::vector expected; ZoneProvision zoneProvision = create({}); diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index 234dabb..722f32c 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -117,27 +117,27 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(ZoneSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { auto c = create(TEST_CONFIG_PATH); c.reset(); } -BOOST_AUTO_TEST_CASE(BuggyConfigTest) +BOOST_AUTO_TEST_CASE(BuggyConfig) { BOOST_REQUIRE_EXCEPTION(create(BUGGY_CONFIG_PATH), ZoneOperationException, WhatEquals("Could not create zone")); } -BOOST_AUTO_TEST_CASE(MissingConfigTest) +BOOST_AUTO_TEST_CASE(MissingConfig) { BOOST_REQUIRE_EXCEPTION(create(MISSING_CONFIG_PATH), ConfigException, WhatEquals("Could not load " + MISSING_CONFIG_PATH)); } -BOOST_AUTO_TEST_CASE(StartStopTest) +BOOST_AUTO_TEST_CASE(StartStop) { auto c = create(TEST_CONFIG_PATH); c->start(); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(StartStopTest) c->stop(true); } -BOOST_AUTO_TEST_CASE(DbusConnectionTest) +BOOST_AUTO_TEST_CASE(DbusConnection) { mRunGuard.create("/tmp/ut-run"); // the same path as in lxc template @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(DbusConnectionTest) // TODO: DbusReconnectionTest -BOOST_AUTO_TEST_CASE(ListNetdevTest) +BOOST_AUTO_TEST_CASE(ListNetdev) { typedef std::vector NetdevList; @@ -173,7 +173,7 @@ BOOST_AUTO_TEST_CASE(ListNetdevTest) BOOST_CHECK(hostNetdevs != netdevs); } -BOOST_AUTO_TEST_CASE(CreateNetdevVethTest) +BOOST_AUTO_TEST_CASE(CreateNetdevVeth) { typedef std::vector NetdevList; @@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(CreateNetdevVethTest) hostNetdevsThrow.begin(), hostNetdevsThrow.end()); } -BOOST_AUTO_TEST_CASE(CreateNetdevMacvlanTest) +BOOST_AUTO_TEST_CASE(CreateNetdevMacvlan) { typedef std::vector NetdevList; diff --git a/tests/unit_tests/server/ut-zones-manager.cpp b/tests/unit_tests/server/ut-zones-manager.cpp index ea858e2..b140e6f 100644 --- a/tests/unit_tests/server/ut-zones-manager.cpp +++ b/tests/unit_tests/server/ut-zones-manager.cpp @@ -481,28 +481,28 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(ZonesManagerSuite, Fixture) -BOOST_AUTO_TEST_CASE(ConstructorDestructorTest) +BOOST_AUTO_TEST_CASE(ConstructorDestructor) { std::unique_ptr cm; cm.reset(new ZonesManager(TEST_CONFIG_PATH)); cm.reset(); } -BOOST_AUTO_TEST_CASE(MissingConfigTest) +BOOST_AUTO_TEST_CASE(MissingConfig) { BOOST_REQUIRE_EXCEPTION(ZonesManager{MISSING_CONFIG_PATH}, ConfigException, WhatEquals("Could not load " + MISSING_CONFIG_PATH)); } -BOOST_AUTO_TEST_CASE(CreateTest) +BOOST_AUTO_TEST_CASE(Create) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); cm.createZone("zone2", SIMPLE_TEMPLATE); } -BOOST_AUTO_TEST_CASE(StartStopTest) +BOOST_AUTO_TEST_CASE(StartStop) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -514,7 +514,7 @@ BOOST_AUTO_TEST_CASE(StartStopTest) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } -BOOST_AUTO_TEST_CASE(DetachOnExitTest) +BOOST_AUTO_TEST_CASE(DetachOnExit) { { ZonesManager cm(TEST_CONFIG_PATH); @@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE(DetachOnExitTest) } } -BOOST_AUTO_TEST_CASE(FocusTest) +BOOST_AUTO_TEST_CASE(Focus) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -548,7 +548,7 @@ BOOST_AUTO_TEST_CASE(FocusTest) BOOST_CHECK(cm.getRunningForegroundZoneId() == "zone3"); } -BOOST_AUTO_TEST_CASE(NotifyActiveZoneTest) +BOOST_AUTO_TEST_CASE(NotifyActiveZone) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); @@ -618,7 +618,7 @@ BOOST_AUTO_TEST_CASE(NotifyActiveZoneTest) dbuses.clear(); } -BOOST_AUTO_TEST_CASE(DisplayOffTest) +BOOST_AUTO_TEST_CASE(DisplayOff) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); @@ -655,7 +655,7 @@ BOOST_AUTO_TEST_CASE(DisplayOffTest) } } -BOOST_AUTO_TEST_CASE(MoveFileTest) +BOOST_AUTO_TEST_CASE(MoveFile) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); @@ -757,7 +757,7 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) fs::remove_all(ZONE2PATH, ec); } -BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest) +BOOST_AUTO_TEST_CASE(AllowSwitchToDefault) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); @@ -806,7 +806,7 @@ BOOST_AUTO_TEST_CASE(AllowSwitchToDefaultTest) } } -BOOST_AUTO_TEST_CASE(ProxyCallTest) +BOOST_AUTO_TEST_CASE(ProxyCall) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); @@ -895,7 +895,7 @@ namespace { "unix:path=/tmp/ut-run/zone3/dbus/system_bus_socket"}}; } // namespace -BOOST_AUTO_TEST_CASE(GetZoneDbusesTest) +BOOST_AUTO_TEST_CASE(GetZoneDbuses) { DbusAccessory host(DbusAccessory::HOST_ID); ZonesManager cm(TEST_CONFIG_PATH); @@ -910,7 +910,7 @@ BOOST_AUTO_TEST_CASE(GetZoneDbusesTest) BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); } -BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbusTest) +BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbus) { DbusAccessory host(DbusAccessory::HOST_ID); ZonesManager cm(TEST_CONFIG_PATH); @@ -925,7 +925,7 @@ BOOST_AUTO_TEST_CASE(GetZoneDbusesNoDbusTest) BOOST_CHECK(EXPECTED_DBUSES_NONE == host.callMethodGetZoneDbuses()); } -BOOST_AUTO_TEST_CASE(ZoneDbusesSignalsTest) +BOOST_AUTO_TEST_CASE(ZoneDbusesSignals) { Latch signalLatch; DbusAccessory::Dbuses collectedDbuses; @@ -975,7 +975,7 @@ BOOST_AUTO_TEST_CASE(ZoneDbusesSignalsTest) } -BOOST_AUTO_TEST_CASE(GetZoneIdsTest) +BOOST_AUTO_TEST_CASE(GetZoneIds) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -992,7 +992,7 @@ BOOST_AUTO_TEST_CASE(GetZoneIdsTest) BOOST_CHECK(returnedIds == zoneIds);// order should be preserved } -BOOST_AUTO_TEST_CASE(GetActiveZoneIdTest) +BOOST_AUTO_TEST_CASE(GetActiveZoneId) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -1015,7 +1015,7 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneIdTest) BOOST_CHECK(dbus.callMethodGetActiveZoneId() == ""); } -BOOST_AUTO_TEST_CASE(SetActiveZoneTest) +BOOST_AUTO_TEST_CASE(SetActiveZone) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", SIMPLE_TEMPLATE); @@ -1044,7 +1044,7 @@ BOOST_AUTO_TEST_CASE(SetActiveZoneTest) WhatEquals("Could not activate stopped or paused zone")); } -BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest) +BOOST_AUTO_TEST_CASE(CreateDestroyZone) { const std::string zone1 = "test1"; const std::string zone2 = "test2"; @@ -1096,7 +1096,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZoneTest) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } -BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistenceTest) +BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistence) { const std::string zone = "test1"; @@ -1140,7 +1140,7 @@ BOOST_AUTO_TEST_CASE(CreateDestroyZonePersistenceTest) BOOST_CHECK(getZoneIds().empty()); } -BOOST_AUTO_TEST_CASE(ZoneStatePersistenceTest) +BOOST_AUTO_TEST_CASE(ZoneStatePersistence) { const std::string zone1 = "zone1"; const std::string zone2 = "zone2"; @@ -1211,7 +1211,7 @@ BOOST_AUTO_TEST_CASE(ZoneStatePersistenceTest) } } -BOOST_AUTO_TEST_CASE(StartShutdownZoneTest) +BOOST_AUTO_TEST_CASE(StartShutdownZone) { const std::string zone1 = "zone1"; const std::string zone2 = "zone2"; @@ -1251,7 +1251,7 @@ BOOST_AUTO_TEST_CASE(StartShutdownZoneTest) BOOST_CHECK_EQUAL(cm.getRunningForegroundZoneId(), ""); } -BOOST_AUTO_TEST_CASE(LockUnlockZoneTest) +BOOST_AUTO_TEST_CASE(LockUnlockZone) { ZonesManager cm(TEST_CONFIG_PATH); cm.createZone("zone1", DBUS_TEMPLATE); diff --git a/tests/unit_tests/utils/ut-callback-guard.cpp b/tests/unit_tests/utils/ut-callback-guard.cpp index 89787d5..524c7d5 100644 --- a/tests/unit_tests/utils/ut-callback-guard.cpp +++ b/tests/unit_tests/utils/ut-callback-guard.cpp @@ -39,14 +39,14 @@ using namespace vasum::utils; const int unsigned TIMEOUT = 1000; -BOOST_AUTO_TEST_CASE(EmptyTest) +BOOST_AUTO_TEST_CASE(Empty) { CallbackGuard guard; BOOST_CHECK_EQUAL(0, guard.getTrackersCount()); BOOST_CHECK(guard.waitForTrackers(TIMEOUT)); } -BOOST_AUTO_TEST_CASE(SimpleTest) +BOOST_AUTO_TEST_CASE(Simple) { CallbackGuard guard; guard.spawn(); @@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(SimpleTest) BOOST_CHECK(guard.waitForTrackers(TIMEOUT)); } -BOOST_AUTO_TEST_CASE(ThreadTest) +BOOST_AUTO_TEST_CASE(Thread) { Latch trackerCreated; Latch trackerCanBeDestroyed; diff --git a/tests/unit_tests/utils/ut-counting-map.cpp b/tests/unit_tests/utils/ut-counting-map.cpp index 702470f..04832db 100644 --- a/tests/unit_tests/utils/ut-counting-map.cpp +++ b/tests/unit_tests/utils/ut-counting-map.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_SUITE(CountingMapSuite) using namespace vasum::utils; -BOOST_AUTO_TEST_CASE(CountingTest) +BOOST_AUTO_TEST_CASE(Counting) { CountingMap map; diff --git a/tests/unit_tests/utils/ut-fs.cpp b/tests/unit_tests/utils/ut-fs.cpp index b2defba..cbbe14b 100644 --- a/tests/unit_tests/utils/ut-fs.cpp +++ b/tests/unit_tests/utils/ut-fs.cpp @@ -72,7 +72,7 @@ struct Fixture { BOOST_FIXTURE_TEST_SUITE(UtilsFSSuite, Fixture) -BOOST_AUTO_TEST_CASE(ReadFileContentTest) +BOOST_AUTO_TEST_CASE(ReadFileContent) { BOOST_CHECK_EQUAL(REFERENCE_FILE_CONTENT, readFileContent(REFERENCE_FILE_PATH)); BOOST_CHECK_EXCEPTION(readFileContent(BUGGY_FILE_PATH), @@ -80,20 +80,20 @@ BOOST_AUTO_TEST_CASE(ReadFileContentTest) WhatEquals("Read failed")); } -BOOST_AUTO_TEST_CASE(SaveFileContentTest) +BOOST_AUTO_TEST_CASE(SaveFileContent) { BOOST_REQUIRE(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT)); BOOST_CHECK_EQUAL(REFERENCE_FILE_CONTENT, readFileContent(FILE_PATH)); } -BOOST_AUTO_TEST_CASE(RemoveFileTest) +BOOST_AUTO_TEST_CASE(RemoveFile) { BOOST_REQUIRE(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT)); BOOST_REQUIRE(removeFile(FILE_PATH)); BOOST_REQUIRE(!boost::filesystem::exists(FILE_PATH)); } -BOOST_AUTO_TEST_CASE(MountPointTest) +BOOST_AUTO_TEST_CASE(MountPoint) { bool result; namespace fs = boost::filesystem; @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(MountPointTest) BOOST_REQUIRE(fs::remove(MOUNT_POINT_1, ec)); } -BOOST_AUTO_TEST_CASE(MoveFileTest) +BOOST_AUTO_TEST_CASE(MoveFile) { namespace fs = boost::filesystem; boost::system::error_code ec; @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) BOOST_REQUIRE(fs::remove(MOUNT_POINT_2, ec)); } -BOOST_AUTO_TEST_CASE(CopyDirContentsTest) +BOOST_AUTO_TEST_CASE(CopyDirContents) { namespace fs = boost::filesystem; std::string src, src_inner, src_inner2, dst, dst_inner, dst_inner2; diff --git a/tests/unit_tests/utils/ut-glib-loop.cpp b/tests/unit_tests/utils/ut-glib-loop.cpp index 7c5e318..467fbfb 100644 --- a/tests/unit_tests/utils/ut-glib-loop.cpp +++ b/tests/unit_tests/utils/ut-glib-loop.cpp @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(GlibLoopTest) ScopedGlibLoop loop; } -BOOST_AUTO_TEST_CASE(GlibTimerEventTest) +BOOST_AUTO_TEST_CASE(GlibTimerEvent) { ScopedGlibLoop loop; std::atomic_uint counter(0); diff --git a/tests/unit_tests/utils/ut-paths.cpp b/tests/unit_tests/utils/ut-paths.cpp index bb2b11f..e14da13 100644 --- a/tests/unit_tests/utils/ut-paths.cpp +++ b/tests/unit_tests/utils/ut-paths.cpp @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_SUITE(UtilsPathsSuite) using namespace vasum::utils; -BOOST_AUTO_TEST_CASE(CreateFilePathTest) +BOOST_AUTO_TEST_CASE(CreateFilePath) { BOOST_CHECK_EQUAL("", createFilePath()); @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(CreateFilePathTest) BOOST_CHECK_EQUAL("a/b/.txt", createFilePath("a", "/b/", "/.txt")); } -BOOST_AUTO_TEST_CASE(DirNameTest) +BOOST_AUTO_TEST_CASE(DirName) { BOOST_CHECK_EQUAL(".", dirName("")); BOOST_CHECK_EQUAL(".", dirName(".")); diff --git a/tests/unit_tests/utils/ut-same-thread-guard.cpp b/tests/unit_tests/utils/ut-same-thread-guard.cpp index 7dbba57..463c07d 100644 --- a/tests/unit_tests/utils/ut-same-thread-guard.cpp +++ b/tests/unit_tests/utils/ut-same-thread-guard.cpp @@ -35,7 +35,7 @@ BOOST_AUTO_TEST_SUITE(SameThreadGuardSuite) using namespace vasum::utils; -BOOST_AUTO_TEST_CASE(SimpleTest) +BOOST_AUTO_TEST_CASE(Simple) { SameThreadGuard guard; BOOST_CHECK(guard.check()); @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(SimpleTest) BOOST_CHECK(guard.check()); } -BOOST_AUTO_TEST_CASE(ThreadTest) +BOOST_AUTO_TEST_CASE(Thread) { SameThreadGuard guard; diff --git a/tests/unit_tests/utils/ut-value-latch.cpp b/tests/unit_tests/utils/ut-value-latch.cpp index 711c8e6..2b09967 100644 --- a/tests/unit_tests/utils/ut-value-latch.cpp +++ b/tests/unit_tests/utils/ut-value-latch.cpp @@ -58,7 +58,7 @@ namespace }; } // namespace -BOOST_AUTO_TEST_CASE(SimpleTypeTest) +BOOST_AUTO_TEST_CASE(SimpleValue) { ValueLatch testLatch; @@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(SimpleTypeTest) BOOST_REQUIRE_EQUAL(testLatch.get(TIMEOUT), 3); } -BOOST_AUTO_TEST_CASE(ComplexTypeTest) +BOOST_AUTO_TEST_CASE(ComplexValue) { ValueLatch testLatch; @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(ComplexTypeTest) BOOST_REQUIRE_EQUAL(test.str, TEST_STRING); } -BOOST_AUTO_TEST_CASE(ComplexMovableTypeTest) +BOOST_AUTO_TEST_CASE(ComplexMovableValue) { ValueLatch testLatch; @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(ComplexMovableTypeTest) BOOST_REQUIRE_EQUAL(test.value.str, TEST_STRING); } -BOOST_AUTO_TEST_CASE(TimeoutTest) +BOOST_AUTO_TEST_CASE(Timeout) { ValueLatch testLatch; @@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(TimeoutTest) WhatEquals("Timeout occured")); } -BOOST_AUTO_TEST_CASE(MultipleSetTest) +BOOST_AUTO_TEST_CASE(MultipleSet) { ValueLatch testLatch; @@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE(MultipleSetTest) WhatEquals("Cannot set value multiple times")); } -BOOST_AUTO_TEST_CASE(MultipleGetTest) +BOOST_AUTO_TEST_CASE(MultipleGet) { ValueLatch testLatch; diff --git a/tests/unit_tests/utils/ut-worker.cpp b/tests/unit_tests/utils/ut-worker.cpp index 91fa6b8..da2a96d 100644 --- a/tests/unit_tests/utils/ut-worker.cpp +++ b/tests/unit_tests/utils/ut-worker.cpp @@ -39,12 +39,12 @@ using namespace vasum::utils; const int unsigned TIMEOUT = 1000; -BOOST_AUTO_TEST_CASE(NoTasksTest) +BOOST_AUTO_TEST_CASE(NoTasks) { Worker::Pointer worker = Worker::create(); } -BOOST_AUTO_TEST_CASE(NoTasks2Test) +BOOST_AUTO_TEST_CASE(NoTasksWithSubWorkers) { Worker::Pointer worker = Worker::create(); Worker::Pointer sub1 = worker->createSubWorker(); @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(NoTasks2Test) worker.reset(); } -BOOST_AUTO_TEST_CASE(SimpleTest) +BOOST_AUTO_TEST_CASE(Simple) { Latch done; @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(SimpleTest) BOOST_CHECK(done.wait(TIMEOUT)); } -BOOST_AUTO_TEST_CASE(QueueTest) +BOOST_AUTO_TEST_CASE(Queue) { std::mutex mutex; std::string result; @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(QueueTest) BOOST_CHECK_EQUAL("0123456789", result); } -BOOST_AUTO_TEST_CASE(ThreadResumeTest) +BOOST_AUTO_TEST_CASE(ThreadResume) { Latch done; @@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(ThreadResumeTest) BOOST_CHECK(done.wait(TIMEOUT)); } -BOOST_AUTO_TEST_CASE(SubWorkerTest) +BOOST_AUTO_TEST_CASE(SubWorker) { std::mutex mutex; std::string result; @@ -154,7 +154,7 @@ BOOST_AUTO_TEST_CASE(SubWorkerTest) } } -BOOST_AUTO_TEST_CASE(NoCopyTest) +BOOST_AUTO_TEST_CASE(NoCopy) { typedef std::atomic_int Counter; -- 2.7.4 From b1762a1880ad20cc09a100e4c3c77aca54bfa290 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 25 Mar 2015 14:46:14 +0100 Subject: [PATCH 06/16] FIX: compile on x86_64, operator << instead + in log message. [Bug/Feature] Doesn't compile on x86_84 (conversion warning), operator << instead + in log message [Cause] N/A [Solution] N/A [Verification] compile on x86_64 (f.e. tizenorg_common_x86_64_x11) Change-Id: I51e51297eec860c65a19810ea1d4feead7c1d3a8 --- common/netlink/netlink-message.cpp | 2 +- common/netlink/netlink-message.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/netlink/netlink-message.cpp b/common/netlink/netlink-message.cpp index ac42c58..c64199a 100644 --- a/common/netlink/netlink-message.cpp +++ b/common/netlink/netlink-message.cpp @@ -232,7 +232,7 @@ const char* NetlinkResponse::get(int ifla, int len) const throw VasumException("Wrong attribute type"); } if (len >= 0 && rta->rta_len != RTA_LENGTH(len)) { - LOGE("Wrong attribute length, expected: " << rta->rta_len + ", got " << len); + LOGE("Wrong attribute length, expected: " << rta->rta_len << ", got " << len); throw VasumException("Wrong attribute length"); } return reinterpret_cast(RTA_DATA(get(rta->rta_len))); diff --git a/common/netlink/netlink-message.hpp b/common/netlink/netlink-message.hpp index 6b84de4..971e6ad 100644 --- a/common/netlink/netlink-message.hpp +++ b/common/netlink/netlink-message.hpp @@ -149,7 +149,7 @@ public: /** * Fetch attribute */ - NetlinkResponse& fetch(int ifla, std::string& value, int maxSize = std::string::npos); + NetlinkResponse& fetch(int ifla, std::string& value, int maxSize = -1); template NetlinkResponse& fetch(int ifla, T& value); ///@} -- 2.7.4 From ab211e3f6c34d20da3f1ff544cf6478490246869 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Mon, 16 Mar 2015 13:28:04 +0100 Subject: [PATCH 07/16] Using libConfig structures for input in server [Feature] Deserialization with libConfig Uint test of libConfig [Cause] N/A [Solution] N/A [Verification] Build, run tests, run tests with valgrind Change-Id: I9c9dfd32bd31ddbde60f35c9317027f41c3faaa3 Signed-off-by: Piotr Bartosiewicz Signed-off-by: Jan Olszak --- common/api/messages.hpp | 412 +++++++------------------ server/host-connection.cpp | 196 +++++------- server/host-connection.hpp | 71 ++--- server/zones-manager.cpp | 255 +++++++-------- server/zones-manager.hpp | 83 ++--- tests/unit_tests/config/testconfig-example.hpp | 8 + tests/unit_tests/config/ut-configuration.cpp | 2 + 7 files changed, 373 insertions(+), 654 deletions(-) diff --git a/common/api/messages.hpp b/common/api/messages.hpp index 6c6d4da..a567975 100644 --- a/common/api/messages.hpp +++ b/common/api/messages.hpp @@ -78,13 +78,19 @@ struct VectorOfStringPairs { typedef api::String ZoneId; typedef api::String Declaration; typedef api::String FileMoveRequestStatus; +typedef api::StringPair GetNetDevAttrsIn; +typedef api::StringPair CreateNetDevPhysIn; +typedef api::StringPair RemoveDeclarationIn; +typedef api::StringPair CreateZoneIn; +typedef api::StringPair RevokeDeviceIn; +typedef api::StringPair DestroyNetDevIn; typedef api::VectorOfStrings ZoneIds; typedef api::VectorOfStrings Declarations; typedef api::VectorOfStrings NetDevList; typedef api::VectorOfStringPairs Dbuses; -typedef api::VectorOfStringPairs NetDevAttrs; +typedef api::VectorOfStringPairs GetNetDevAttrs; -struct ZoneInfo { +struct ZoneInfoOut { std::string id; int vt; std::string state; @@ -99,304 +105,110 @@ struct ZoneInfo { ) }; -// struct MethodSetActiveZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodGetZoneDbusesConfig { -// CONFIG_REGISTER_EMPTY -// }; - -// struct MethodGetZoneIdListConfig { -// CONFIG_REGISTER_EMPTY -// }; - - -// struct MethodGetActiveZoneIdConfig { -// CONFIG_REGISTER_EMPTY -// }; - - -// struct MethodGetZoneInfoConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodSetNetDevAttrsConfig { -// std::string zone; -// std::string netdev; - -// struct Store { -// std::string key; -// std::string value; - -// CONFIG_REGISTER -// ( -// key, -// value -// ) -// }; - -// std::vector attrs; - -// CONFIG_REGISTER -// ( -// zone, -// netdev, -// attrs -// ) -// }; - -// struct MethodGetNetDevAttrsConfig { -// std::string zone; -// std::string netdev; - -// CONFIG_REGISTER -// ( -// zone, -// netdev -// ) -// }; - -// struct MethodGetNetDevListConfig { -// std::string zone; - -// CONFIG_REGISTER -// ( -// zone -// ) -// }; - -// struct MethodCreateNetDevVethConfig { -// std::string id; -// std::string zoneDev; -// std::string hostDev; - -// CONFIG_REGISTER -// ( -// id, -// zoneDev, -// hostDev -// ) -// }; - -// struct MethodCreateNetDevMacvlanConfig { -// std::string id; -// std::string zoneDev; -// std::string hostDev; - -// CONFIG_REGISTER -// ( -// id, -// zoneDev, -// hostDev -// ) -// }; - -// struct MethodCreateNetDevPhysConfig { -// std::string id; -// std::string devId; - -// CONFIG_REGISTER -// ( -// id, -// devId -// ) -// }; - -// struct MethodGetDeclareFileConfig { -// std::string zone; -// int32_t type; -// std::string path; -// int32_t flags; -// int32_t mode; - -// CONFIG_REGISTER -// ( -// zone, -// type, -// path, -// flags, -// mode -// ) -// }; - -// struct MethodGetDeclareMountConfig { -// std::string source; -// std::string zone; -// std::string target; -// uint64_t flags; -// std::string data; - -// CONFIG_REGISTER -// ( -// source, -// zone, -// target, -// flags, -// data -// ) -// }; - -// struct MethodGetDeclareLinkConfig { -// std::string source; -// std::string zone; -// std::string target; - -// CONFIG_REGISTER -// ( -// source, -// zone, -// target -// ) -// }; - -// struct MethodGetDeclarationConfig { -// std::string zone; -// std::string declarationId; - -// CONFIG_REGISTER -// ( -// zone, -// declarationId -// ) -// }; - -// struct MethodRemoveDeclarationConfig { -// std::string id; -// std::string declarationId; - -// CONFIG_REGISTER -// ( -// id, -// declarationId -// ) -// }; - -// struct MethodCreateZoneConfig { -// std::string id; -// std::string templateName; - -// CONFIG_REGISTER -// ( -// id, -// templateName -// ) -// }; - -// struct MethodDestroyZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - - -// struct MethodShutdownZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodStartZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodLockZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodUnlockZoneConfig { -// std::string id; - -// CONFIG_REGISTER -// ( -// id -// ) -// }; - -// struct MethodGrantDeviceConfig { -// std::string id; -// std::string device; -// uint32_t flags; - -// CONFIG_REGISTER -// ( -// id, -// device, -// flags -// ) -// }; - -// struct MethodRevokeDeviceConfig { -// std::string id; -// std::string device; - -// CONFIG_REGISTER -// ( -// id, -// device -// ) -// }; - -// TODO: Agregate configs if it makes sense. For example: MethodLockZoneConfig and MethodUnlockZoneConfig - - -// Zone: -// struct MethodNotifyActiveZoneConfig { -// std::string application; -// std::string message; - -// CONFIG_REGISTER -// ( -// application, -// message -// ) -// }; - -// struct MethodFileMoveRequest { -// std::string destination; -// std::string path; - -// CONFIG_REGISTER -// ( -// destination, -// path -// ) -// }; - -// struct MethodFileMoveRequestResult { -// std::string result; - -// CONFIG_REGISTER -// ( -// result -// ) -// }; +struct SetNetDevAttrsIn { + std::string id; // Zone's id + std::string netDev; + std::vector attrs; + + CONFIG_REGISTER + ( + id, + netDev, + attrs + ) +}; + +struct CreateNetDevVethIn { + std::string id; + std::string zoneDev; + std::string hostDev; + + CONFIG_REGISTER + ( + id, + zoneDev, + hostDev + ) +}; + +struct CreateNetDevMacvlanIn { + std::string id; + std::string zoneDev; + std::string hostDev; + uint32_t mode; + + CONFIG_REGISTER + ( + id, + zoneDev, + hostDev, + mode + ) +}; + +struct DeclareFileIn { + std::string zone; + int32_t type; + std::string path; + int32_t flags; + int32_t mode; + + CONFIG_REGISTER + ( + zone, + type, + path, + flags, + mode + ) +}; + +struct DeclareMountIn { + std::string source; + std::string zone; + std::string target; + std::string type; + uint64_t flags; + std::string data; + + CONFIG_REGISTER + ( + source, + zone, + target, + type, + flags, + data + ) +}; + +struct DeclareLinkIn +{ + std::string source; + std::string zone; + std::string target; + + CONFIG_REGISTER + ( + source, + zone, + target + ) +}; + +struct GrantDeviceIn +{ + std::string id; + std::string device; + uint32_t flags; + + CONFIG_REGISTER + ( + id, + device, + flags + ) +}; } // namespace api } // namespace vasum diff --git a/server/host-connection.cpp b/server/host-connection.cpp index d0b612a..993b63d 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -31,7 +31,7 @@ #include "api/messages.hpp" #include "logger/logger.hpp" - +#include "config/manager.hpp" namespace vasum { @@ -81,9 +81,9 @@ bool HostConnection::waitForName(const unsigned int timeoutMs) std::unique_lock lock(mNameMutex); mNameCondition.wait_for(lock, std::chrono::milliseconds(timeoutMs), - [this] { - return mNameAcquired || mNameLost; - }); + [this] { + return mNameAcquired || mNameLost; + }); return mNameAcquired; } @@ -249,12 +249,12 @@ void HostConnection::onMessageCall(const std::string& objectPath, } if (methodName == api::host::METHOD_SET_ACTIVE_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId zoneId; + config::loadFromGVariant(parameters, zoneId); if (mSetActiveZoneCallback) { auto rb = std::make_shared>(result); - mSetActiveZoneCallback(id, rb); + mSetActiveZoneCallback(zoneId, rb); } return; } @@ -313,261 +313,227 @@ void HostConnection::onMessageCall(const std::string& objectPath, } if (methodName == api::host::METHOD_GET_ZONE_INFO) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId zoneId; + config::loadFromGVariant(parameters, zoneId); if (mGetZoneInfoCallback) { - auto rb = std::make_shared>(result); - mGetZoneInfoCallback(id, rb); + auto rb = std::make_shared>(result); + mGetZoneInfoCallback(zoneId, rb); } return; } if (methodName == api::host::METHOD_SET_NETDEV_ATTRS) { - const gchar* zone = NULL; - const gchar* netdev = NULL; - GVariantIter* iter; - g_variant_get(parameters, "(&s&sa(ss))", &zone, &netdev, &iter); - gchar* key = NULL; - gchar* value = NULL; - std::vector> attrs; - while (g_variant_iter_loop(iter, "(&s&s)", &key, &value)) { - attrs.push_back(std::make_tuple(key, value)); - } - g_variant_iter_free(iter); + api::SetNetDevAttrsIn data; + config::loadFromGVariant(parameters, data); + if (mSetNetdevAttrsCallback) { auto rb = std::make_shared>(result); - mSetNetdevAttrsCallback(zone, netdev, attrs, rb); + mSetNetdevAttrsCallback(data, rb); } return; } if (methodName == api::host::METHOD_GET_NETDEV_ATTRS) { - const gchar* zone = NULL; - const gchar* netdev = NULL; - g_variant_get(parameters, "(&s&s)", &zone, &netdev); + api::GetNetDevAttrsIn data; + config::loadFromGVariant(parameters, data); + if (mGetNetdevAttrsCallback) { - auto rb = std::make_shared>(result); - mGetNetdevAttrsCallback(zone, netdev, rb); + auto rb = std::make_shared>(result); + mGetNetdevAttrsCallback(data, rb); } return; } if (methodName == api::host::METHOD_GET_NETDEV_LIST) { - const gchar* zone = NULL; - g_variant_get(parameters, "(&s)", &zone); + api::ZoneId data; + config::loadFromGVariant(parameters, data); + if (mGetNetdevListCallback) { - auto rb = std::make_shared>(result); - mGetNetdevListCallback(zone, rb); + auto rb = std::make_shared>(result); + mGetNetdevListCallback(data, rb); } return; } - if (methodName == api::host::METHOD_CREATE_NETDEV_VETH) { - const gchar* id = NULL; - const gchar* zoneDev = NULL; - const gchar* hostDev = NULL; - g_variant_get(parameters, "(&s&s&s)", &id, &zoneDev, &hostDev); + api::CreateNetDevVethIn data; + config::loadFromGVariant(parameters, data); + if (mCreateNetdevVethCallback) { auto rb = std::make_shared>(result); - mCreateNetdevVethCallback(id, zoneDev, hostDev, rb); + mCreateNetdevVethCallback(data, rb); } return; } if (methodName == api::host::METHOD_CREATE_NETDEV_MACVLAN) { - const gchar* id = NULL; - const gchar* zoneDev = NULL; - const gchar* hostDev = NULL; - guint32 mode; - g_variant_get(parameters, "(&s&s&su)", &id, &zoneDev, &hostDev, &mode); + api::CreateNetDevMacvlanIn data; + config::loadFromGVariant(parameters, data); + if (mCreateNetdevMacvlanCallback) { auto rb = std::make_shared>(result); - mCreateNetdevMacvlanCallback(id, zoneDev, hostDev, mode, rb); + mCreateNetdevMacvlanCallback(data, rb); } } if (methodName == api::host::METHOD_CREATE_NETDEV_PHYS) { - const gchar* id = NULL; - const gchar* devId = NULL; - g_variant_get(parameters, "(&s&s)", &id, &devId); + api::CreateNetDevPhysIn data; + config::loadFromGVariant(parameters, data); + if (mCreateNetdevPhysCallback) { auto rb = std::make_shared>(result); - mCreateNetdevPhysCallback(id, devId, rb); + mCreateNetdevPhysCallback(data, rb); } } if (methodName == api::host::METHOD_DESTROY_NETDEV) { - const gchar* id = NULL; - const gchar* devId = NULL; - g_variant_get(parameters, "(&s&s)", &id, &devId); + api::DestroyNetDevIn data; + config::loadFromGVariant(parameters, data); + if (mDestroyNetdevCallback) { auto rb = std::make_shared>(result); - mDestroyNetdevCallback(id, devId, rb); + mDestroyNetdevCallback(data, rb); } } if (methodName == api::host::METHOD_DECLARE_FILE) { - const gchar* zone; - int32_t type; - const gchar* path; - int32_t flags; - int32_t mode; - g_variant_get(parameters, "(&si&sii)", &zone, &type, &path, &flags, &mode); + api::DeclareFileIn data; + config::loadFromGVariant(parameters, data); if (mDeclareFileCallback) { auto rb = std::make_shared>(result); - mDeclareFileCallback(zone, type, path, flags, mode, rb); + mDeclareFileCallback(data, rb); } return; } if (methodName == api::host::METHOD_DECLARE_MOUNT) { - const gchar* source; - const gchar* zone; - const gchar* target; - const gchar* type; - uint64_t flags; - const gchar* data; - g_variant_get(parameters, - "(&s&s&s&st&s)", - &source, - &zone, - &target, - &type, - &flags, - &data); + api::DeclareMountIn data; + config::loadFromGVariant(parameters, data); if (mDeclareMountCallback) { auto rb = std::make_shared>(result); - mDeclareMountCallback(source, zone, target, type, flags, data, rb); + mDeclareMountCallback(data, rb); } return; } if (methodName == api::host::METHOD_DECLARE_LINK) { - const gchar* source; - const gchar* zone; - const gchar* target; - g_variant_get(parameters, "(&s&s&s)", &source, &zone, &target); + api::DeclareLinkIn data; + config::loadFromGVariant(parameters, data); if (mDeclareLinkCallback) { auto rb = std::make_shared>(result); - mDeclareLinkCallback(source, zone, target, rb); + mDeclareLinkCallback(data, rb); } return; } if (methodName == api::host::METHOD_GET_DECLARATIONS) { - const gchar* zone; - g_variant_get(parameters, "(&s)", &zone); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mGetDeclarationsCallback) { auto rb = std::make_shared>(result); - mGetDeclarationsCallback(zone, rb); + mGetDeclarationsCallback(data, rb); } return; } if (methodName == api::host::METHOD_REMOVE_DECLARATION) { - const gchar* zone; - const gchar* declarationId; - g_variant_get(parameters, "(&s&s)", &zone, &declarationId); + api::RemoveDeclarationIn data; + config::loadFromGVariant(parameters, data); if (mRemoveDeclarationCallback) { auto rb = std::make_shared>(result); - mRemoveDeclarationCallback(zone, declarationId, rb); + mRemoveDeclarationCallback(data, rb); } return; } if (methodName == api::host::METHOD_CREATE_ZONE) { - const gchar* id = NULL; - const gchar* templateName = NULL; - g_variant_get(parameters, "(&s&s)", &id, &templateName); + api::CreateZoneIn data; + config::loadFromGVariant(parameters, data); if (mCreateZoneCallback) { auto rb = std::make_shared>(result); - mCreateZoneCallback(id, templateName, rb); + mCreateZoneCallback(data, rb); } return; } if (methodName == api::host::METHOD_DESTROY_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mDestroyZoneCallback) { auto rb = std::make_shared>(result); - mDestroyZoneCallback(id, rb); + mDestroyZoneCallback(data, rb); } return; } if (methodName == api::host::METHOD_SHUTDOWN_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mShutdownZoneCallback) { auto rb = std::make_shared>(result); - mShutdownZoneCallback(id, rb); + mShutdownZoneCallback(data, rb); } } if (methodName == api::host::METHOD_START_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mStartZoneCallback) { auto rb = std::make_shared>(result); - mStartZoneCallback(id, rb); + mStartZoneCallback(data, rb); } } if (methodName == api::host::METHOD_LOCK_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mLockZoneCallback) { auto rb = std::make_shared>(result); - mLockZoneCallback(id, rb); + mLockZoneCallback(data, rb); } return; } if (methodName == api::host::METHOD_UNLOCK_ZONE) { - const gchar* id = NULL; - g_variant_get(parameters, "(&s)", &id); + api::ZoneId data; + config::loadFromGVariant(parameters, data); if (mUnlockZoneCallback) { auto rb = std::make_shared>(result); - mUnlockZoneCallback(id, rb); + mUnlockZoneCallback(data, rb); } return; } if (methodName == api::host::METHOD_GRANT_DEVICE) { - const gchar* id = NULL; - const gchar* device = NULL; - uint32_t flags; - g_variant_get(parameters, "(&s&su)", &id, &device, &flags); + api::GrantDeviceIn data; + config::loadFromGVariant(parameters, data); if (mGrantDeviceCallback) { auto rb = std::make_shared>(result); - mGrantDeviceCallback(id, device, flags, rb); + mGrantDeviceCallback(data, rb); } return; } if (methodName == api::host::METHOD_REVOKE_DEVICE) { - const gchar* id = NULL; - const gchar* device = NULL; - g_variant_get(parameters, "(&s&s)", &id, &device); + api::RevokeDeviceIn data; + config::loadFromGVariant(parameters, data); if (mRevokeDeviceCallback) { auto rb = std::make_shared>(result); - mRevokeDeviceCallback(id, device, rb); + mRevokeDeviceCallback(data, rb); } return; } @@ -590,7 +556,7 @@ void HostConnection::proxyCallAsync(const std::string& busName, } void HostConnection::signalZoneDbusState(const std::string& zoneId, - const std::string& dbusAddress) + const std::string& dbusAddress) { GVariant* parameters = g_variant_new("(ss)", zoneId.c_str(), dbusAddress.c_str()); mDbusConnection->emitSignal(api::host::OBJECT_PATH, diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 0ef9585..4cb1c8e 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -28,6 +28,7 @@ #include "dbus/connection.hpp" #include "api/method-result-builder.hpp" +#include "api/messages.hpp" #include #include @@ -60,96 +61,70 @@ public: )> GetZoneIdsCallback; typedef std::function GetActiveZoneIdCallback; - typedef std::function GetZoneInfoCallback; - typedef std::function>& attrs, + typedef std::function SetNetdevAttrsCallback; - typedef std::function GetNetdevAttrsCallback; - typedef std::function GetNetdevListCallback; - typedef std::function CreateNetdevVethCallback; - typedef std::function CreateNetdevMacvlanCallback; - typedef std::function CreateNetdevPhysCallback; - typedef std::function DestroyNetdevCallback; - typedef std::function DeclareFileCallback; - typedef std::function DeclareMountCallback; - typedef std::function DeclareLinkCallback; - typedef std::function GetDeclarationsCallback; - typedef std::function RemoveDeclarationCallback; - typedef std::function SetActiveZoneCallback; - typedef std::function CreateZoneCallback; - typedef std::function DestroyZoneCallback; - typedef std::function ShutdownZoneCallback; - typedef std::function StartZoneCallback; - typedef std::function LockZoneCallback; - typedef std::function UnlockZoneCallback; - typedef std::function GrantDeviceCallback; - typedef std::function RevokeDeviceCallback; diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 4266820..67e2b88 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -143,46 +143,46 @@ ZonesManager::ZonesManager(const std::string& configPath) this, _1, _2)); mHostConnection.setSetNetdevAttrsCallback(bind(&ZonesManager::handleSetNetdevAttrsCall, - this, _1, _2, _3, _4)); + this, _1, _2)); mHostConnection.setGetNetdevAttrsCallback(bind(&ZonesManager::handleGetNetdevAttrsCall, - this, _1, _2, _3)); + this, _1, _2)); mHostConnection.setGetNetdevListCallback(bind(&ZonesManager::handleGetNetdevListCall, this, _1, _2)); mHostConnection.setCreateNetdevVethCallback(bind(&ZonesManager::handleCreateNetdevVethCall, - this, _1, _2, _3, _4)); + this, _1, _2)); mHostConnection.setCreateNetdevMacvlanCallback(bind(&ZonesManager::handleCreateNetdevMacvlanCall, - this, _1, _2, _3, _4, _5)); + this, _1, _2)); mHostConnection.setCreateNetdevPhysCallback(bind(&ZonesManager::handleCreateNetdevPhysCall, - this, _1, _2, _3)); + this, _1, _2)); mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, - this, _1, _2, _3)); + this, _1, _2)); mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, - this, _1, _2, _3, _4, _5, _6)); + this, _1, _2)); mHostConnection.setDeclareMountCallback(bind(&ZonesManager::handleDeclareMountCall, - this, _1, _2, _3, _4, _5, _6, _7)); + this, _1, _2)); mHostConnection.setDeclareLinkCallback(bind(&ZonesManager::handleDeclareLinkCall, - this, _1, _2, _3, _4)); + this, _1, _2)); mHostConnection.setGetDeclarationsCallback(bind(&ZonesManager::handleGetDeclarationsCall, this, _1, _2)); mHostConnection.setRemoveDeclarationCallback(bind(&ZonesManager::handleRemoveDeclarationCall, - this, _1, _2, _3)); + this, _1, _2)); mHostConnection.setSetActiveZoneCallback(bind(&ZonesManager::handleSetActiveZoneCall, this, _1, _2)); mHostConnection.setCreateZoneCallback(bind(&ZonesManager::handleCreateZoneCall, - this, _1, _2, _3)); + this, _1, _2)); mHostConnection.setDestroyZoneCallback(bind(&ZonesManager::handleDestroyZoneCall, this, _1, _2)); @@ -200,10 +200,10 @@ ZonesManager::ZonesManager(const std::string& configPath) this, _1, _2)); mHostConnection.setGrantDeviceCallback(bind(&ZonesManager::handleGrantDeviceCall, - this, _1, _2, _3, _4)); + this, _1, _2)); mHostConnection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall, - this, _1, _2, _3)); + this, _1, _2)); for (const auto& zoneId : mDynamicConfig.zoneIds) { insertZone(zoneId, getTemplatePathForExistingZone(zoneId)); @@ -778,22 +778,22 @@ void ZonesManager::handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer r result->set(zoneId); } -void ZonesManager::handleGetZoneInfoCall(const std::string& id, +void ZonesManager::handleGetZoneInfoCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { LOGI("GetZoneInfo call"); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("No zone with id=" << id); + LOGE("No zone with id=" << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } Zone& zone = get(iter); - auto zoneInfo = std::make_shared(); + auto zoneInfo = std::make_shared(); if (zone.isRunning()) { zoneInfo->state = "RUNNING"; @@ -802,7 +802,7 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id, } else if (zone.isPaused()) { zoneInfo->state = "FROZEN"; } else { - LOGE("Unrecognized state of zone id=" << id); + LOGE("Unrecognized state of zone id=" << zoneId.value); result->setError(api::ERROR_INTERNAL, "Unrecognized state of zone"); return; } @@ -810,18 +810,23 @@ void ZonesManager::handleGetZoneInfoCall(const std::string& id, result->set(zoneInfo); } -void ZonesManager::handleSetNetdevAttrsCall(const std::string& zone, - const std::string& netdev, - const std::vector>& attrs, +void ZonesManager::handleSetNetdevAttrsCall(const api::SetNetDevAttrsIn& data, api::MethodResultBuilder::Pointer result) { LOGI("SetNetdevAttrs call"); try { Lock lock(mMutex); - getZone(zone).setNetdevAttrs(netdev, attrs); + + // TODO: Use vector instead of tuples + std::vector> attrsAsTuples; + for(const auto& entry: data.attrs){ + attrsAsTuples.push_back(std::make_tuple(entry.first, entry.second)); + } + + getZone(data.id).setNetdevAttrs(data.netDev, attrsAsTuples); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't set attributes: " << ex.what()); @@ -829,22 +834,21 @@ void ZonesManager::handleSetNetdevAttrsCall(const std::string& zone, } } -void ZonesManager::handleGetNetdevAttrsCall(const std::string& zone, - const std::string& netdev, +void ZonesManager::handleGetNetdevAttrsCall(const api::GetNetDevAttrsIn& data, api::MethodResultBuilder::Pointer result) { LOGI("GetNetdevAttrs call"); try { Lock lock(mMutex); - auto netDevAttrs = std::make_shared(); - const auto attrs = getZone(zone).getNetdevAttrs(netdev); + auto netDevAttrs = std::make_shared(); + const auto attrs = getZone(data.first).getNetdevAttrs(data.second); for (size_t i = 0; i < attrs.size(); ++i) { netDevAttrs->values.push_back({std::get<0>(attrs[i]), std::get<1>(attrs[i])}); } result->set(netDevAttrs); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.first); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't set attributes: " << ex.what()); @@ -852,17 +856,17 @@ void ZonesManager::handleGetNetdevAttrsCall(const std::string& zone, } } -void ZonesManager::handleGetNetdevListCall(const std::string& zone, +void ZonesManager::handleGetNetdevListCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { LOGI("GetNetdevList call"); try { Lock lock(mMutex); auto netDevList = std::make_shared(); - netDevList->values = getZone(zone).getNetdevList(); + netDevList->values = getZone(zoneId.value).getNetdevList(); result->set(netDevList); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't set attributes: " << ex.what()); @@ -870,19 +874,17 @@ void ZonesManager::handleGetNetdevListCall(const std::string& zone, } } -void ZonesManager::handleCreateNetdevVethCall(const std::string& zone, - const std::string& zoneDev, - const std::string& hostDev, +void ZonesManager::handleCreateNetdevVethCall(const api::CreateNetDevVethIn& data, api::MethodResultBuilder::Pointer result) { LOGI("CreateNetdevVeth call"); try { Lock lock(mMutex); - getZone(zone).createNetdevVeth(zoneDev, hostDev); + getZone(data.id).createNetdevVeth(data.zoneDev, data.hostDev); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't create veth: " << ex.what()); @@ -890,20 +892,16 @@ void ZonesManager::handleCreateNetdevVethCall(const std::string& zone, } } -void ZonesManager::handleCreateNetdevMacvlanCall(const std::string& zone, - const std::string& zoneDev, - const std::string& hostDev, - const uint32_t& mode, +void ZonesManager::handleCreateNetdevMacvlanCall(const api::CreateNetDevMacvlanIn& data, api::MethodResultBuilder::Pointer result) { LOGI("CreateNetdevMacvlan call"); try { Lock lock(mMutex); - - getZone(zone).createNetdevMacvlan(zoneDev, hostDev, mode); + getZone(data.id).createNetdevMacvlan(data.zoneDev, data.hostDev, data.mode); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't create macvlan: " << ex.what()); @@ -911,18 +909,17 @@ void ZonesManager::handleCreateNetdevMacvlanCall(const std::string& zone, } } -void ZonesManager::handleCreateNetdevPhysCall(const std::string& zone, - const std::string& devId, +void ZonesManager::handleCreateNetdevPhysCall(const api::CreateNetDevPhysIn& data, api::MethodResultBuilder::Pointer result) { LOGI("CreateNetdevPhys call"); try { Lock lock(mMutex); - getZone(zone).moveNetdev(devId); + getZone(data.first).moveNetdev(data.second); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.first); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't create netdev: " << ex.what()); @@ -930,18 +927,17 @@ void ZonesManager::handleCreateNetdevPhysCall(const std::string& zone, } } -void ZonesManager::handleDestroyNetdevCall(const std::string& zone, - const std::string& devId, +void ZonesManager::handleDestroyNetdevCall(const api::DestroyNetDevIn& data, api::MethodResultBuilder::Pointer result) { LOGI("DestroyNetdev call"); try { Lock lock(mMutex); - getZone(zone).destroyNetdev(devId); + getZone(data.first).destroyNetdev(data.second); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.first); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE("Can't create netdev: " << ex.what()); @@ -949,11 +945,7 @@ void ZonesManager::handleDestroyNetdevCall(const std::string& zone, } } -void ZonesManager::handleDeclareFileCall(const std::string& zone, - const int32_t& type, - const std::string& path, - const int32_t& flags, - const int32_t& mode, +void ZonesManager::handleDeclareFileCall(const api::DeclareFileIn& data, api::MethodResultBuilder::Pointer result) { LOGI("DeclareFile call"); @@ -961,10 +953,10 @@ void ZonesManager::handleDeclareFileCall(const std::string& zone, try { Lock lock(mMutex); auto declaration = std::make_shared(); - declaration->value = getZone(zone).declareFile(type, path, flags, mode); + declaration->value = getZone(data.zone).declareFile(data.type, data.path, data.flags, data.mode); result->set(declaration); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.zone); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const config::ConfigException& ex) { LOGE("Can't declare file: " << ex.what()); @@ -972,12 +964,7 @@ void ZonesManager::handleDeclareFileCall(const std::string& zone, } } -void ZonesManager::handleDeclareMountCall(const std::string& source, - const std::string& zone, - const std::string& target, - const std::string& type, - const uint64_t& flags, - const std::string& data, +void ZonesManager::handleDeclareMountCall(const api::DeclareMountIn& data, api::MethodResultBuilder::Pointer result) { LOGI("DeclareMount call"); @@ -985,10 +972,10 @@ void ZonesManager::handleDeclareMountCall(const std::string& source, try { Lock lock(mMutex); auto declaration = std::make_shared(); - declaration->value = getZone(zone).declareMount(source, target, type, flags, data); + declaration->value = getZone(data.zone).declareMount(data.source, data.target, data.type, data.flags, data.data); result->set(declaration); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.zone); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const config::ConfigException& ex) { LOGE("Can't declare mount: " << ex.what()); @@ -996,19 +983,17 @@ void ZonesManager::handleDeclareMountCall(const std::string& source, } } -void ZonesManager::handleDeclareLinkCall(const std::string& source, - const std::string& zone, - const std::string& target, +void ZonesManager::handleDeclareLinkCall(const api::DeclareLinkIn& data, api::MethodResultBuilder::Pointer result) { LOGI("DeclareLink call"); try { Lock lock(mMutex); auto declaration = std::make_shared(); - declaration->value = getZone(zone).declareLink(source, target); + declaration->value = getZone(data.zone).declareLink(data.source, data.target); result->set(declaration); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.zone); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const config::ConfigException& ex) { LOGE("Can't declare link: " << ex.what()); @@ -1016,17 +1001,17 @@ void ZonesManager::handleDeclareLinkCall(const std::string& source, } } -void ZonesManager::handleGetDeclarationsCall(const std::string& zone, +void ZonesManager::handleGetDeclarationsCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("GetDeclarations call Id=" << zone); + LOGI("GetDeclarations call Id=" << zoneId.value); try { Lock lock(mMutex); auto declarations = std::make_shared(); - declarations->values = getZone(zone).getDeclarations(); + declarations->values = getZone(zoneId.value).getDeclarations(); result->set(declarations); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE(ex.what()); @@ -1034,19 +1019,16 @@ void ZonesManager::handleGetDeclarationsCall(const std::string& zone, } } -void ZonesManager::handleRemoveDeclarationCall(const std::string& zone, - const std::string& declarationId, +void ZonesManager::handleRemoveDeclarationCall(const api::RemoveDeclarationIn& data, api::MethodResultBuilder::Pointer result) { - LOGI("RemoveDeclaration call Id=" << zone); + LOGI("RemoveDeclaration call Id=" << data.first); try { Lock lock(mMutex); - - getZone(zone).removeDeclaration(declarationId); - + getZone(data.first).removeDeclaration(data.second); result->setVoid(); } catch (const InvalidZoneIdException&) { - LOGE("No zone with id=" << zone); + LOGE("No zone with id=" << data.first); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& ex) { LOGE(ex.what()); @@ -1054,16 +1036,16 @@ void ZonesManager::handleRemoveDeclarationCall(const std::string& zone, } } -void ZonesManager::handleSetActiveZoneCall(const std::string& id, +void ZonesManager::handleSetActiveZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("SetActiveZone call; Id=" << id ); + LOGI("SetActiveZone call; Id=" << zoneId.value ); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("No zone with id=" << id ); + LOGE("No zone with id=" << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } @@ -1208,12 +1190,11 @@ void ZonesManager::createZone(const std::string& id, updateDefaultId(); } -void ZonesManager::handleCreateZoneCall(const std::string& id, - const std::string& templateName, +void ZonesManager::handleCreateZoneCall(const api::CreateZoneIn& data, api::MethodResultBuilder::Pointer result) { try { - createZone(id, templateName); + createZone(data.first, data.second); result->setVoid(); } catch (const InvalidZoneIdException& e) { result->setError(api::ERROR_INVALID_ID, "Existing or invalid zone id"); @@ -1222,16 +1203,15 @@ void ZonesManager::handleCreateZoneCall(const std::string& id, } } -void ZonesManager::handleDestroyZoneCall(const std::string& id, +void ZonesManager::handleDestroyZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - auto destroyer = [id, result, this] { + auto destroyer = [zoneId, result, this] { try { - LOGI("Destroying zone " << id); - - destroyZone(id); + LOGI("Destroying zone " << zoneId.value); + destroyZone(zoneId.value); } catch (const InvalidZoneIdException&) { - LOGE("Failed to destroy zone - no such zone id: " << id); + LOGE("Failed to destroy zone - no such zone id: " << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); } catch (const VasumException& e) { LOGE("Error during zone destruction: " << e.what()); @@ -1244,19 +1224,19 @@ void ZonesManager::handleDestroyZoneCall(const std::string& id, mWorker->addTask(destroyer); } -void ZonesManager::handleShutdownZoneCall(const std::string& id, +void ZonesManager::handleShutdownZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("ShutdownZone call; Id=" << id ); + LOGI("ShutdownZone call; Id=" << zoneId.value); - auto shutdown = [id, result, this] { + auto shutdown = [zoneId, result, this] { try { - LOGT("Shutdown zone " << id); + LOGT("Shutdown zone " << zoneId.value); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("Failed to shutdown zone - no such zone id: " << id); + LOGE("Failed to shutdown zone - no such zone id: " << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } @@ -1273,19 +1253,19 @@ void ZonesManager::handleShutdownZoneCall(const std::string& id, mWorker->addTask(shutdown); } -void ZonesManager::handleStartZoneCall(const std::string& id, +void ZonesManager::handleStartZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("StartZone call; Id=" << id ); + LOGI("StartZone call; Id=" << zoneId.value); - auto startAsync = [this, id, result]() { + auto startAsync = [this, zoneId, result]() { try { - LOGT("Start zone " << id ); + LOGT("Start zone " << zoneId.value); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("Failed to start zone - no such zone id: " << id); + LOGE("Failed to start zone - no such zone id: " << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } @@ -1293,30 +1273,30 @@ void ZonesManager::handleStartZoneCall(const std::string& id, focusInternal(iter); result->setVoid(); } catch (const std::exception& e) { - LOGE(id << ": failed to start: " << e.what()); + LOGE(zoneId.value << ": failed to start: " << e.what()); result->setError(api::ERROR_INTERNAL, "Failed to start zone"); } }; mWorker->addTask(startAsync); } -void ZonesManager::handleLockZoneCall(const std::string& id, +void ZonesManager::handleLockZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("LockZone call; Id=" << id ); + LOGI("LockZone call; Id=" << zoneId.value ); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("Failed to lock zone - no such zone id: " << id); + LOGE("Failed to lock zone - no such zone id: " << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } Zone& zone = get(iter); if (!zone.isRunning()) { - LOGE("Zone id=" << id << " is not running."); + LOGE("Zone id=" << zoneId.value << " is not running."); result->setError(api::ERROR_INVALID_STATE, "Zone is not running"); return; } @@ -1335,23 +1315,23 @@ void ZonesManager::handleLockZoneCall(const std::string& id, result->setVoid(); } -void ZonesManager::handleUnlockZoneCall(const std::string& id, +void ZonesManager::handleUnlockZoneCall(const api::ZoneId& zoneId, api::MethodResultBuilder::Pointer result) { - LOGI("UnlockZone call; Id=" << id ); + LOGI("UnlockZone call; Id=" << zoneId.value ); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(zoneId.value); if (iter == mZones.end()) { - LOGE("Failed to unlock zone - no such zone id: " << id); + LOGE("Failed to unlock zone - no such zone id: " << zoneId.value); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } Zone& zone = get(iter); if (!zone.isPaused()) { - LOGE("Zone id=" << id << " is not paused."); + LOGE("Zone id=" << zoneId.value << " is not paused."); result->setError(api::ERROR_INVALID_STATE, "Zone is not paused"); return; } @@ -1368,40 +1348,38 @@ void ZonesManager::handleUnlockZoneCall(const std::string& id, result->setVoid(); } -void ZonesManager::handleGrantDeviceCall(const std::string& id, - const std::string& device, - uint32_t flags, +void ZonesManager::handleGrantDeviceCall(const api::GrantDeviceIn& data, api::MethodResultBuilder::Pointer result) { - LOGI("GrantDevice call; id=" << id << "; dev=" << device); + LOGI("GrantDevice call; id=" << data.id << "; dev=" << data.device); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(data.id); if (iter == mZones.end()) { - LOGE("Failed to grant device - no such zone id: " << id); + LOGE("Failed to grant device - no such zone id: " << data.id); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } Zone& zone = get(iter); if (!zone.isRunning() && !zone.isPaused()) { - LOGE("Zone id=" << id << " is not running"); + LOGE("Zone id=" << data.id << " is not running"); result->setError(api::ERROR_INVALID_STATE, "Zone is not running"); return; } - std::string devicePath = "/dev/" + device; + std::string devicePath = "/dev/" + data.device; if (!lxc::isDevice(devicePath)) { - LOGE("Failed to grant device - cannot acces device: " << device); + LOGE("Failed to grant device - cannot acces device: " << data.device); result->setError(api::ERROR_FORBIDDEN, "Cannot access device"); return; } // assume device node is created inside zone - if (!lxc::setDeviceAccess(id, devicePath, true, flags)) { - LOGE("Failed to grant device: " << device << " for zone: " << id); + if (!lxc::setDeviceAccess(data.id, devicePath, true, data.flags)) { + LOGE("Failed to grant device: " << data.device << " for zone: " << data.id); result->setError(api::ERROR_INTERNAL, "Cannot grant device"); return; } @@ -1409,37 +1387,36 @@ void ZonesManager::handleGrantDeviceCall(const std::string& id, result->setVoid(); } -void ZonesManager::handleRevokeDeviceCall(const std::string& id, - const std::string& device, +void ZonesManager::handleRevokeDeviceCall(const api::RevokeDeviceIn& data, api::MethodResultBuilder::Pointer result) { - LOGI("RevokeDevice call; id=" << id << "; dev=" << device); + LOGI("RevokeDevice call; id=" << data.first << "; dev=" << data.second); Lock lock(mMutex); - auto iter = findZone(id); + auto iter = findZone(data.first); if (iter == mZones.end()) { - LOGE("Failed to revoke device - no such zone id: " << id); + LOGE("Failed to revoke device - no such zone id: " << data.first); result->setError(api::ERROR_INVALID_ID, "No such zone id"); return; } Zone& zone = get(iter); if (!zone.isRunning() && !zone.isPaused()) { - LOGE("Zone id=" << id << " is not running"); + LOGE("Zone id=" << data.first << " is not running"); result->setError(api::ERROR_INVALID_STATE, "Zone is not running"); return; } - std::string devicePath = "/dev/" + device; + std::string devicePath = "/dev/" + data.second; if (!lxc::isDevice(devicePath)) { - LOGE("Failed to revoke device - cannot acces device: " << device); + LOGE("Failed to revoke device - cannot acces device: " << data.second); result->setError(api::ERROR_FORBIDDEN, "Cannot access device"); return; } - if (!lxc::setDeviceAccess(id, devicePath, false, 0)) { - LOGE("Failed to revoke device: " << device << " for zone: " << id); + if (!lxc::setDeviceAccess(data.first, devicePath, false, 0)) { + LOGE("Failed to revoke device: " << data.second << " for zone: " << data.first); result->setError(api::ERROR_INTERNAL, "Cannot revoke device"); return; } diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index deb9b9d..ae89566 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -146,15 +146,16 @@ private: int getVTForNewZone(); void insertZone(const std::string& zoneId, const std::string& templatePath); + // Zone's handlers--------------------------------------------------------- void handleNotifyActiveZoneCall(const std::string& caller, const std::string& appliaction, const std::string& message, api::MethodResultBuilder::Pointer result); void handleDisplayOffCall(const std::string& caller); void handleFileMoveCall(const std::string& srcZoneId, - const std::string& dstZoneId, - const std::string& path, - api::MethodResultBuilder::Pointer result); + const std::string& dstZoneId, + const std::string& path, + api::MethodResultBuilder::Pointer result); void handleProxyCall(const std::string& caller, const std::string& target, const std::string& targetBusName, @@ -164,77 +165,55 @@ private: GVariant* parameters, dbus::MethodResultBuilder::Pointer result); void handleGetZoneDbusesCall(api::MethodResultBuilder::Pointer result); - void handleDbusStateChanged(const std::string& zoneId, const std::string& dbusAddress); + + void handleDbusStateChanged(const std::string& zoneId, + const std::string& dbusAddress); + // Host's handlers -------------------------------------------------------- void handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result); void handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer result); - void handleGetZoneInfoCall(const std::string& id, api::MethodResultBuilder::Pointer result); - void handleSetNetdevAttrsCall(const std::string& zone, - const std::string& netdev, - const std::vector>& attrs, + void handleGetZoneInfoCall(const api::ZoneId& data, + api::MethodResultBuilder::Pointer result); + void handleSetNetdevAttrsCall(const api::SetNetDevAttrsIn& data, api::MethodResultBuilder::Pointer result); - void handleGetNetdevAttrsCall(const std::string& zone, - const std::string& netdev, + void handleGetNetdevAttrsCall(const api::GetNetDevAttrsIn& data, api::MethodResultBuilder::Pointer result); - void handleGetNetdevListCall(const std::string& zone, + void handleGetNetdevListCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleCreateNetdevVethCall(const std::string& zone, - const std::string& zoneDev, - const std::string& hostDev, + void handleCreateNetdevVethCall(const api::CreateNetDevVethIn& data, api::MethodResultBuilder::Pointer result); - void handleCreateNetdevMacvlanCall(const std::string& zone, - const std::string& zoneDev, - const std::string& hostDev, - const uint32_t& mode, + void handleCreateNetdevMacvlanCall(const api::CreateNetDevMacvlanIn& data, api::MethodResultBuilder::Pointer result); - void handleCreateNetdevPhysCall(const std::string& zone, - const std::string& devId, + void handleCreateNetdevPhysCall(const api::CreateNetDevPhysIn& data, api::MethodResultBuilder::Pointer result); - void handleDestroyNetdevCall(const std::string& zone, - const std::string& devId, + void handleDestroyNetdevCall(const api::DestroyNetDevIn& data, api::MethodResultBuilder::Pointer result); - void handleDeclareFileCall(const std::string& zone, - const int32_t& type, - const std::string& path, - const int32_t& flags, - const int32_t& mode, + void handleDeclareFileCall(const api::DeclareFileIn& data, api::MethodResultBuilder::Pointer result); - void handleDeclareMountCall(const std::string& source, - const std::string& zone, - const std::string& target, - const std::string& type, - const uint64_t& flags, - const std::string& data, + void handleDeclareMountCall(const api::DeclareMountIn& data, api::MethodResultBuilder::Pointer result); - void handleDeclareLinkCall(const std::string& source, - const std::string& zone, - const std::string& target, + void handleDeclareLinkCall(const api::DeclareLinkIn& data, api::MethodResultBuilder::Pointer result); - void handleGetDeclarationsCall(const std::string& zone, + void handleGetDeclarationsCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleRemoveDeclarationCall(const std::string& zone, - const std::string& declarationId, + void handleRemoveDeclarationCall(const api::RemoveDeclarationIn& data, api::MethodResultBuilder::Pointer result); - void handleSetActiveZoneCall(const std::string& id, + void handleSetActiveZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleCreateZoneCall(const std::string& id, - const std::string& templateName, + void handleCreateZoneCall(const api::CreateZoneIn& data, api::MethodResultBuilder::Pointer result); - void handleDestroyZoneCall(const std::string& id, + void handleDestroyZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleShutdownZoneCall(const std::string& id, + void handleShutdownZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleStartZoneCall(const std::string& id, + void handleStartZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleLockZoneCall(const std::string& id, + void handleLockZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleUnlockZoneCall(const std::string& id, + void handleUnlockZoneCall(const api::ZoneId& data, api::MethodResultBuilder::Pointer result); - void handleGrantDeviceCall(const std::string& id, - const std::string& device, - uint32_t flags, + void handleGrantDeviceCall(const api::GrantDeviceIn& data, api::MethodResultBuilder::Pointer result); - void handleRevokeDeviceCall(const std::string& id, - const std::string& device, + void handleRevokeDeviceCall(const api::RevokeDeviceIn& data, api::MethodResultBuilder::Pointer result); }; diff --git a/tests/unit_tests/config/testconfig-example.hpp b/tests/unit_tests/config/testconfig-example.hpp index 6c14719..ff5c2ef 100644 --- a/tests/unit_tests/config/testconfig-example.hpp +++ b/tests/unit_tests/config/testconfig-example.hpp @@ -84,6 +84,8 @@ struct TestConfig { int intVal; std::int64_t int64Val; + std::uint32_t uint32Val; + std::uint64_t uint64Val; std::string stringVal; double doubleVal; bool boolVal; @@ -104,6 +106,8 @@ struct TestConfig { ( intVal, int64Val, + uint32Val, + uint64Val, stringVal, doubleVal, boolVal, @@ -142,6 +146,8 @@ struct PartialTestConfig { const std::string jsonTestString = "{ \"intVal\": 12345, " "\"int64Val\": -1234567890123456789, " + "\"uint32Val\": 123456, " + "\"uint64Val\": 1234567890123456789, " "\"stringVal\": \"blah\", " "\"doubleVal\": -1.234000, " "\"boolVal\": true, " @@ -163,6 +169,8 @@ const std::string jsonTestString = const std::string jsonEmptyTestString = "{ \"intVal\": 0, " "\"int64Val\": 0, " + "\"uint32Val\": 0, " + "\"uint64Val\": 0, " "\"stringVal\": \"\", " "\"boolVal\": false, " "\"emptyIntVector\": [ ], " diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index a9a5332..1334966 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -60,6 +60,8 @@ BOOST_AUTO_TEST_CASE(FromJsonString) BOOST_CHECK_EQUAL(12345, testConfig.intVal); BOOST_CHECK_EQUAL(-1234567890123456789ll, testConfig.int64Val); + BOOST_CHECK_EQUAL(123456, testConfig.uint32Val); + BOOST_CHECK_EQUAL(1234567890123456789ll, testConfig.uint64Val); BOOST_CHECK_EQUAL("blah", testConfig.stringVal); BOOST_CHECK_CLOSE(-1.234, testConfig.doubleVal, TOLERANCE); BOOST_CHECK_EQUAL(true, testConfig.boolVal); -- 2.7.4 From 70a84ae9b6a4d2f7288cfce840b5b536fa917e2c Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 17 Mar 2015 15:55:16 +0100 Subject: [PATCH 08/16] Possibility to remove ipv4/ipv6 addresses from interface [Feature] Possibility to remove ipv4/ipv6 addresses from interface [Cause] N/A [Solution] Implemented: vsm_netdev_del_ipv4_addr, vsm_netdev_del_ipv6_addr [Verification] Build, run test Change-Id: If1e43c73f443e5480e5f1794a1d1f29fa78c3dd3 --- client/vasum-client-impl.cpp | 38 +++++++++++++++++++++ client/vasum-client-impl.hpp | 16 +++++++++ client/vasum-client.cpp | 18 ++++++++++ client/vasum-client.h | 38 +++++++++++++++++++-- common/api/messages.hpp | 13 ++++++++ server/host-connection.cpp | 14 ++++++++ server/host-connection.hpp | 9 +++++ server/host-dbus-definitions.hpp | 66 ++++++++++++++++++++----------------- server/netdev.cpp | 56 +++++++++++++++++++++++++++++++ server/netdev.hpp | 5 +++ server/zone-admin.cpp | 5 +++ server/zone-admin.hpp | 5 +++ server/zone.cpp | 6 ++++ server/zone.hpp | 5 +++ server/zones-manager.cpp | 20 +++++++++++ server/zones-manager.hpp | 2 ++ tests/unit_tests/server/ut-zone.cpp | 47 +++++++++++++++++++++++--- 17 files changed, 325 insertions(+), 38 deletions(-) diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 1de4de0..0c5482a 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -744,6 +744,44 @@ VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone, } } +VsmStatus Client::vsm_netdev_del_ipv4_addr(const char* zone, + 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(); + } + + 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); +} + +VsmStatus Client::vsm_netdev_del_ipv6_addr(const char* zone, + const char* netdevId, + struct in6_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(); + } + + 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); +} + + VsmStatus Client::vsm_netdev_up(const char* zone, const char* netdevId) noexcept { try { diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 1493a00..4e01966 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -235,6 +235,22 @@ public: int prefix) noexcept; /** + * @see ::vsm_netdev_del_ipv4_addr + */ + VsmStatus vsm_netdev_del_ipv4_addr(const char* zone, + const char* netdevId, + struct in_addr* addr, + int prefix) noexcept; + + /** + * @see ::vsm_netdev_del_ipv6_addr + */ + VsmStatus vsm_netdev_del_ipv6_addr(const char* zone, + const char* netdevId, + struct in6_addr* addr, + int prefix) noexcept; + + /** * @see ::vsm_netdev_up */ VsmStatus vsm_netdev_up(const char* zone, const char* netdevId) noexcept; diff --git a/client/vasum-client.cpp b/client/vasum-client.cpp index 9c0ca60..c12e8c6 100644 --- a/client/vasum-client.cpp +++ b/client/vasum-client.cpp @@ -250,6 +250,24 @@ API VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, return getClient(client).vsm_netdev_set_ipv6_addr(zone, netdevId, addr, prefix); } +API VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client, + const char* zone, + const char* netdevId, + struct in_addr* addr, + int prefix) +{ + return getClient(client).vsm_netdev_del_ipv4_addr(zone, netdevId, addr, prefix); +} + +API VsmStatus vsm_netdev_del_ipv6_addr(VsmClient client, + const char* zone, + const char* netdevId, + struct in6_addr* addr, + int prefix) +{ + return getClient(client).vsm_netdev_del_ipv6_addr(zone, netdevId, addr, prefix); +} + API VsmStatus vsm_netdev_up(VsmClient client, const char* zone, const char* netdevId) diff --git a/client/vasum-client.h b/client/vasum-client.h index 18af990..c252b32 100644 --- a/client/vasum-client.h +++ b/client/vasum-client.h @@ -552,6 +552,38 @@ VsmStatus vsm_netdev_set_ipv6_addr(VsmClient client, int prefix); /** + * Remove ipv4 address from netdev + * + * @param[in] client vasum-server's client + * @param[in] zone zone name + * @param[in] netdevId network device id + * @param[in] addr ipv4 address + * @param[in] prefix bit-length of the network prefix + * @return status of this function call + */ +VsmStatus vsm_netdev_del_ipv4_addr(VsmClient client, + const char* zone, + const char* netdevId, + struct in_addr* addr, + int prefix); + +/** + * Remove ipv6 address from netdev + * + * @param[in] client vasum-server's client + * @param[in] zone zone name + * @param[in] netdevId network device id + * @param[in] addr ipv6 address + * @param[in] prefix bit-length of the network prefix + * @return status of this function call + */ +VsmStatus vsm_netdev_del_ipv6_addr(VsmClient client, + const char* zone, + const char* netdevId, + struct in6_addr* addr, + int prefix); + +/** * Turn up a network device in the zone * * @param[in] client vasum-server's client @@ -750,9 +782,9 @@ VsmStatus vsm_remove_declaration(VsmClient client, * @param data custom user's data pointer passed to vsm_add_notification_callback() */ typedef void (*VsmNotificationCallback)(const char* zone, - const char* application, - const char* message, - void* data); + const char* application, + const char* message, + void* data); /** * Send message to active zone. * diff --git a/common/api/messages.hpp b/common/api/messages.hpp index a567975..de193bd 100644 --- a/common/api/messages.hpp +++ b/common/api/messages.hpp @@ -146,6 +146,19 @@ struct CreateNetDevMacvlanIn { ) }; +struct DeleteNetdevIpAddressIn { + std::string zone; + std::string netdev; + std::string ip; + + CONFIG_REGISTER + ( + zone, + netdev, + ip + ) +}; + struct DeclareFileIn { std::string zone; int32_t type; diff --git a/server/host-connection.cpp b/server/host-connection.cpp index 993b63d..f3cbfa0 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -167,6 +167,11 @@ void HostConnection::setDestroyNetdevCallback(const DestroyNetdevCallback& callb mDestroyNetdevCallback = callback; } +void HostConnection::setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback) +{ + mDeleteNetdevIpAddressCallback = callback; +} + void HostConnection::setDeclareFileCallback(const DeclareFileCallback& callback) { mDeclareFileCallback = callback; @@ -397,6 +402,15 @@ void HostConnection::onMessageCall(const std::string& objectPath, } } + if (methodName == api::host::METHOD_DELETE_NETDEV_IP_ADDRESS) { + api::DeleteNetdevIpAddressIn data; + config::loadFromGVariant(parameters, data); + if (mDeleteNetdevIpAddressCallback) { + auto rb = std::make_shared>(result); + mDeleteNetdevIpAddressCallback(data, rb); + } + } + if (methodName == api::host::METHOD_DECLARE_FILE) { api::DeclareFileIn data; config::loadFromGVariant(parameters, data); diff --git a/server/host-connection.hpp b/server/host-connection.hpp index 4cb1c8e..4ad07c8 100644 --- a/server/host-connection.hpp +++ b/server/host-connection.hpp @@ -82,6 +82,9 @@ public: typedef std::function CreateNetdevPhysCallback; + typedef std::function DeleteNetdevIpAddressCallback; typedef std::function DestroyNetdevCallback; @@ -194,6 +197,11 @@ public: void setDestroyNetdevCallback(const DestroyNetdevCallback& callback); /** + * Register a callback called to remove ip address from netdev + */ + void setDeleleNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback); + + /** * Register a callback called to declare file */ void setDeclareFileCallback(const DeclareFileCallback& callback); @@ -291,6 +299,7 @@ private: CreateNetdevMacvlanCallback mCreateNetdevMacvlanCallback; CreateNetdevPhysCallback mCreateNetdevPhysCallback; DestroyNetdevCallback mDestroyNetdevCallback; + DeleteNetdevIpAddressCallback mDeleteNetdevIpAddressCallback; DeclareFileCallback mDeclareFileCallback; DeclareMountCallback mDeclareMountCallback; DeclareLinkCallback mDeclareLinkCallback; diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index 2ac5745..1e6fecc 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -32,39 +32,40 @@ 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 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 ERROR_ZONE_NOT_RUNNING = "org.tizen.vasum.host.Error.ZonesNotRunning"; -const std::string METHOD_GET_ZONE_DBUSES = "GetZoneDbuses"; -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"; -const std::string METHOD_SET_NETDEV_ATTRS = "SetNetdevAttrs"; -const std::string METHOD_GET_NETDEV_ATTRS = "GetNetdevAttrs"; -const std::string METHOD_GET_NETDEV_LIST = "GetNetdevList"; -const std::string METHOD_CREATE_NETDEV_VETH = "CreateNetdevVeth"; -const std::string METHOD_CREATE_NETDEV_MACVLAN = "CreateNetdevMacvlan"; -const std::string METHOD_CREATE_NETDEV_PHYS = "CreateNetdevPhys"; -const std::string METHOD_DESTROY_NETDEV = "DestroyNetdev"; -const std::string METHOD_DECLARE_FILE = "DeclareFile"; -const std::string METHOD_DECLARE_MOUNT = "DeclareMount"; -const std::string METHOD_DECLARE_LINK = "DeclareLink"; -const std::string METHOD_GET_DECLARATIONS = "GetDeclarations"; -const std::string METHOD_REMOVE_DECLARATION = "RemoveDeclaration"; -const std::string METHOD_SET_ACTIVE_ZONE = "SetActiveZone"; -const std::string METHOD_CREATE_ZONE = "CreateZone"; -const std::string METHOD_DESTROY_ZONE = "DestroyZone"; -const std::string METHOD_SHUTDOWN_ZONE = "ShutdownZone"; -const std::string METHOD_START_ZONE = "StartZone"; -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_GET_ZONE_DBUSES = "GetZoneDbuses"; +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"; +const std::string METHOD_SET_NETDEV_ATTRS = "SetNetdevAttrs"; +const std::string METHOD_GET_NETDEV_ATTRS = "GetNetdevAttrs"; +const std::string METHOD_GET_NETDEV_LIST = "GetNetdevList"; +const std::string METHOD_CREATE_NETDEV_VETH = "CreateNetdevVeth"; +const std::string METHOD_CREATE_NETDEV_MACVLAN = "CreateNetdevMacvlan"; +const std::string METHOD_CREATE_NETDEV_PHYS = "CreateNetdevPhys"; +const std::string METHOD_DESTROY_NETDEV = "DestroyNetdev"; +const std::string METHOD_DELETE_NETDEV_IP_ADDRESS = "DeleteNetdevIpAddress"; +const std::string METHOD_DECLARE_FILE = "DeclareFile"; +const std::string METHOD_DECLARE_MOUNT = "DeclareMount"; +const std::string METHOD_DECLARE_LINK = "DeclareLink"; +const std::string METHOD_GET_DECLARATIONS = "GetDeclarations"; +const std::string METHOD_REMOVE_DECLARATION = "RemoveDeclaration"; +const std::string METHOD_SET_ACTIVE_ZONE = "SetActiveZone"; +const std::string METHOD_CREATE_ZONE = "CreateZone"; +const std::string METHOD_DESTROY_ZONE = "DestroyZone"; +const std::string METHOD_SHUTDOWN_ZONE = "ShutdownZone"; +const std::string METHOD_START_ZONE = "StartZone"; +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 SIGNAL_ZONE_DBUS_STATE = "ZoneDbusState"; +const std::string SIGNAL_ZONE_DBUS_STATE = "ZoneDbusState"; const std::string DEFINITION = @@ -125,6 +126,11 @@ const std::string DEFINITION = " " " " " " + " " + " " + " " + " " + " " " " " " " " diff --git a/server/netdev.cpp b/server/netdev.cpp index da58641..38ccb88 100644 --- a/server/netdev.cpp +++ b/server/netdev.cpp @@ -120,6 +120,11 @@ uint32_t getInterfaceIndex(const string& name, pid_t nsPid) { return infoPeer.ifi_index; } +int getIpFamily(const std::string& ip) +{ + return ip.find(':') == std::string::npos ? AF_INET : AF_INET6; +} + void validateNetdevName(const string& name) { if (name.size() <= 1 || name.size() >= IFNAMSIZ) { @@ -331,6 +336,36 @@ void setIpAddresses(const pid_t nsPid, send(nlm, nsPid); } +void deleteIpAddress(const pid_t nsPid, + const uint32_t index, + const std::string& ip, + int prefixlen, + int family) +{ + NetlinkMessage nlm(RTM_DELADDR, NLM_F_REQUEST | NLM_F_ACK); + ifaddrmsg infoAddr = utils::make_clean(); + infoAddr.ifa_family = family; + infoAddr.ifa_index = index; + infoAddr.ifa_prefixlen = prefixlen; + nlm.put(infoAddr); + if (family == AF_INET6) { + in6_addr addr6; + if (inet_pton(AF_INET6, ip.c_str(), &addr6) != 1) { + throw VasumException("Can't delete ipv6 address"); + }; + nlm.put(IFA_ADDRESS, addr6); + nlm.put(IFA_LOCAL, addr6); + } else { + assert(family == AF_INET); + in_addr addr4; + if (inet_pton(AF_INET, ip.c_str(), &addr4) != 1) { + throw VasumException("Can't delete ipv4 address"); + }; + nlm.put(IFA_LOCAL, addr4); + } + send(nlm, nsPid); +} + } // namespace void createVeth(const pid_t& nsPid, const string& nsDev, const string& hostDev) @@ -565,6 +600,27 @@ void setAttrs(const pid_t nsPid, const std::string& netdev, const Attrs& attrs) setIp(ipv6, infoPeer.ifi_index, AF_INET6); } +void deleteIpAddress(const pid_t nsPid, + const std::string& netdev, + const std::string& ip) +{ + uint32_t index = getInterfaceIndex(netdev, nsPid); + size_t slash = ip.find('/'); + if (slash == string::npos) { + LOGE("Wrong address format: it is not CIDR notation: can't find '/'"); + throw VasumException("Wrong address format"); + } + int prefixlen = 0; + try { + prefixlen = stoi(ip.substr(slash + 1)); + } catch (const std::exception& ex) { + LOGE("Wrong address format: invalid prefixlen"); + throw VasumException("Wrong address format: invalid prefixlen"); + } + deleteIpAddress(nsPid, index, ip.substr(0, slash), prefixlen, getIpFamily(ip)); +} + + } //namespace netdev } //namespace vasum diff --git a/server/netdev.hpp b/server/netdev.hpp index 5e5821d..b3c574d 100644 --- a/server/netdev.hpp +++ b/server/netdev.hpp @@ -57,6 +57,11 @@ void createBridge(const std::string& netdev); Attrs getAttrs(const pid_t nsPid, const std::string& netdev); void setAttrs(const pid_t nsPid, const std::string& netdev, const Attrs& attrs); +/** + * Remove ipv4/ipv6 address from interface + */ +void deleteIpAddress(const pid_t nsPid, const std::string& netdev, const std::string& ip); + } //namespace netdev } //namespace vasum diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index b584279..3098f29 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -322,4 +322,9 @@ std::vector ZoneAdmin::getNetdevList() return netdev::listNetdev(mZone.getInitPid()); } +void ZoneAdmin::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip) +{ + netdev::deleteIpAddress(mZone.getInitPid(), netdev, ip); +} + } // namespace vasum diff --git a/server/zone-admin.hpp b/server/zone-admin.hpp index db2b0f2..d1b179d 100644 --- a/server/zone-admin.hpp +++ b/server/zone-admin.hpp @@ -169,6 +169,11 @@ public: */ std::vector getNetdevList(); + /** + * Remove ipv4/ipv6 address from network device + */ + void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip); + private: const ZoneConfig& mConfig; const ZoneDynamicConfig& mDynamicConfig; diff --git a/server/zone.cpp b/server/zone.cpp index b0c3c28..e26da52 100644 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -513,4 +513,10 @@ std::vector Zone::getNetdevList() return mAdmin->getNetdevList(); } +void Zone::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip) +{ + Lock lock(mReconnectMutex); + mAdmin->deleteNetdevIpAddress(netdev, ip); +} + } // namespace vasum diff --git a/server/zone.hpp b/server/zone.hpp index b981e9a..687077f 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -311,6 +311,11 @@ public: */ std::vector getNetdevList(); + /** + * Remove ipv4/ipv6 address from network device + */ + void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip); + private: utils::Worker::Pointer mWorker; ZoneConfig mConfig; diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 67e2b88..4f34a76 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -163,6 +163,9 @@ ZonesManager::ZonesManager(const std::string& configPath) mHostConnection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, this, _1, _2)); + mHostConnection.setDeleleNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, + this, _1, _2)); + mHostConnection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, this, _1, _2)); @@ -945,6 +948,23 @@ void ZonesManager::handleDestroyNetdevCall(const api::DestroyNetDevIn& data, } } +void ZonesManager::handleDeleteNetdevIpAddressCall(const api::DeleteNetdevIpAddressIn& data, + api::MethodResultBuilder::Pointer result) +{ + LOGI("DelNetdevIpAddress call"); + try { + Lock lock(mMutex); + getZone(data.zone).deleteNetdevIpAddress(data.netdev, data.ip); + result->setVoid(); + } catch (const InvalidZoneIdException&) { + LOGE("No zone with id=" << data.zone); + result->setError(api::ERROR_INVALID_ID, "No such zone id"); + } catch (const VasumException& ex) { + LOGE("Can't delete address: " << ex.what()); + result->setError(api::ERROR_INTERNAL, ex.what()); + } +} + void ZonesManager::handleDeclareFileCall(const api::DeclareFileIn& data, api::MethodResultBuilder::Pointer result) { diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index ae89566..f789595 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -187,6 +187,8 @@ private: api::MethodResultBuilder::Pointer result); void handleDestroyNetdevCall(const api::DestroyNetDevIn& data, api::MethodResultBuilder::Pointer result); + void handleDeleteNetdevIpAddressCall(const api::DeleteNetdevIpAddressIn& data, + api::MethodResultBuilder::Pointer result); void handleDeclareFileCall(const api::DeclareFileIn& data, api::MethodResultBuilder::Pointer result); void handleDeclareMountCall(const api::DeclareMountIn& data, diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index 722f32c..dc66753 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(DbusConnection) c->stop(true); } -// TODO: DbusReconnectionTest +// TODO: DbusReconnection BOOST_AUTO_TEST_CASE(ListNetdev) { @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(CreateNetdevMacvlan) BOOST_CHECK(find(netdevs.begin(), netdevs.end(), ZONE_NETDEV) != netdevs.end()); } -BOOST_AUTO_TEST_CASE(GetNetdevAttrsTest) +BOOST_AUTO_TEST_CASE(GetNetdevAttrs) { setupBridge(BRIDGE_NAME); auto c = create(TEST_CONFIG_PATH); @@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(GetNetdevAttrsTest) BOOST_CHECK(gotType); } -BOOST_AUTO_TEST_CASE(SetNetdevAttrsTest) +BOOST_AUTO_TEST_CASE(SetNetdevAttrs) { setupBridge(BRIDGE_NAME); auto c = create(TEST_CONFIG_PATH); @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(SetNetdevAttrsTest) WhatEquals("Unsupported attribute: does_not_exists")); } -BOOST_AUTO_TEST_CASE(SetNetdevIpv4Test) +BOOST_AUTO_TEST_CASE(SetNetdevIpv4) { setupBridge(BRIDGE_NAME); auto c = create(TEST_CONFIG_PATH); @@ -309,7 +309,7 @@ BOOST_AUTO_TEST_CASE(SetNetdevIpv4Test) BOOST_CHECK_EQUAL(gotIp, 3); } -BOOST_AUTO_TEST_CASE(SetNetdevIpv6Test) +BOOST_AUTO_TEST_CASE(SetNetdevIpv6) { setupBridge(BRIDGE_NAME); auto c = create(TEST_CONFIG_PATH); @@ -349,4 +349,41 @@ BOOST_AUTO_TEST_CASE(SetNetdevIpv6Test) BOOST_CHECK_EQUAL(gotIp, 3); } +BOOST_AUTO_TEST_CASE(DelNetdevIpAddress) +{ + auto contain = [](const ZoneAdmin::NetdevAttrs& container, const std::string& key) { + return container.end() != find_if(container.begin(), + container.end(), + [&](const ZoneAdmin::NetdevAttrs::value_type& value) { + return std::get<0>(value) == key; + }); + }; + + setupBridge(BRIDGE_NAME); + auto c = create(TEST_CONFIG_PATH); + c->start(); + ensureStarted(); + c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); + ZoneAdmin::NetdevAttrs attrs; + attrs.push_back(std::make_tuple("ipv6", "ip:2001:db8::1,prefixlen:64")); + attrs.push_back(std::make_tuple("ipv4", "ip:192.168.4.1,prefixlen:24")); + c->setNetdevAttrs(ZONE_NETDEV, attrs); + attrs = c->getNetdevAttrs(ZONE_NETDEV); + BOOST_REQUIRE(contain(attrs, "ipv4")); + BOOST_REQUIRE(contain(attrs, "ipv6")); + + c->deleteNetdevIpAddress(ZONE_NETDEV, "192.168.4.1/24"); + attrs = c->getNetdevAttrs(ZONE_NETDEV); + BOOST_CHECK(!contain(attrs, "ipv4")); + BOOST_CHECK(contain(attrs, "ipv6")); + + c->deleteNetdevIpAddress(ZONE_NETDEV, "2001:db8::1/64"); + attrs = c->getNetdevAttrs(ZONE_NETDEV); + BOOST_REQUIRE(!contain(attrs, "ipv4")); + BOOST_REQUIRE(!contain(attrs, "ipv6")); + + BOOST_CHECK_THROW(c->deleteNetdevIpAddress(ZONE_NETDEV, "192.168.4.1/24"), VasumException); + BOOST_CHECK_THROW(c->deleteNetdevIpAddress(ZONE_NETDEV, "2001:db8::1/64"), VasumException); +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 04fbbc8a8324a2025d268d83036fbd39092f0438 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 25 Mar 2015 16:22:29 +0100 Subject: [PATCH 09/16] Added netdev_down to cli and made some code cleanup (cli/client) [Bug/Feature] Added netdev_down to cli and made some code cleanup (cli/client) [Cause] N/A [Solution] N/A [Verification] Create netdev, turn it up and turn it down Change-Id: I698de7ccd181d0d8adbb892facddb5d552d6aee4 --- cli/main.cpp | 31 ++++++++++++++++++++----------- client/vasum-client-impl.cpp | 8 ++++---- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/cli/main.cpp b/cli/main.cpp index 2431313..6c10945 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -145,40 +145,40 @@ std::map commands = { { "create_netdev_veth", { create_netdev_veth, - "create_netdev_veth zone_id zoneDev hostDev", + "create_netdev_veth zone_id zone_netdev_id host_netdev_id", "Create netdev in zone", {{"zone_id", "id zone name"}, - {"zoneDev", "network device id"}, - {"hostDev", "host bridge id"}} + {"zone_netdev_id", "network device id"}, + {"host_netdev_id", "host bridge id"}} } }, { "create_netdev_macvlan", { create_netdev_macvlan, - "create_netdev_macvlan zone_id zoneDev hostDev mode", + "create_netdev_macvlan zone_id zone_netdev_id host_netdev_id mode", "Create netdev in zone", {{"zone_id", "id zone name"}, - {"zoneDev", "network device id"}, - {"hostDev", "host bridge id"}, + {"zone_netdev_id", "network device id"}, + {"host_netdev_id", "host bridge id"}, {"mode", "macvlan mode (private, vepa, bridge, passthru)"}} } }, { "create_netdev_phys", { create_netdev_phys, - "create_netdev_phys zone_id devId", + "create_netdev_phys zone_id netdev_id", "Create/move netdev to zone", {{"zone_id", "id zone name"}, - {"devId", "network device id"}} + {"netdev_id", "network device name"}} } }, { "lookup_netdev_by_name", { lookup_netdev_by_name, - "lookup_netdev_by_name zone_id devId", + "lookup_netdev_by_name zone_id netdev_id", "Get netdev flags", {{"zone_id", "id zone name"}, - {"devId", "network device id"}} + {"netdev_id", "network device name"}} } }, { @@ -187,7 +187,7 @@ std::map commands = { "destroy_netdev zone_id devId", "Destroy netdev in zone", {{"zone_id", "id zone name"}, - {"devId", "network device id"}} + {"netdev_id", "network device name"}} } }, { @@ -248,6 +248,15 @@ std::map commands = { } }, { + "netdev_down", { + netdev_down, + "netdev_down zone_id netdev_id", + "Turn down a network device in the zone", + {{"zone_id", "id zone name"}, + {"netdev_id", "network device id"}} + } + }, + { "zone_get_netdevs", { zone_get_netdevs, "zone_get_netdevs zone_id", diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 0c5482a..f4d8580 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -713,12 +713,12 @@ VsmStatus Client::vsm_netdev_get_ipv6_addr(const char* zone, VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* zone, const char* netdevId, struct in_addr* addr, - int mask) noexcept + int prefix) noexcept { try { GVariant* dict = createTupleArray({make_tuple("ipv4", "ip:" + toString(addr) + "," - "prefixlen:" + to_string(mask))}); + "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) { @@ -730,12 +730,12 @@ VsmStatus Client::vsm_netdev_set_ipv4_addr(const char* zone, VsmStatus Client::vsm_netdev_set_ipv6_addr(const char* zone, const char* netdevId, struct in6_addr* addr, - int mask) noexcept + int prefix) noexcept { try { GVariant* dict = createTupleArray({make_tuple("ipv6", "ip:" + toString(addr) + "," - "prefixlen:" + to_string(mask))}); + "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) { -- 2.7.4 From 1161465dffe73552e9996c9934ae73b285f2493b Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 30 Mar 2015 15:37:40 +0200 Subject: [PATCH 10/16] FIX: vsm_lookup_zone_by_id, vsm_zone_get_netdevs; test added [BUG] Can't get return parameters from vsm_lookup_zone_by_id. Segfault when calling zone_get_netdevs. [Cause] Return type should by (siss) not ((siss)); parameters aren't set properly. Wrong return type in vsm_zone_get_netdevs (NetDevList instead GetNetDevAttrs). [Solution] Return type changed. Added ClientSuite/LookupZoneById, ClientSuite/ZoneGetNetdevs tests. [Verification] Run ClientSuite test Change-Id: I56365571aef20ecf445b5a89b6edf94abd567a35 --- client/vasum-client-impl.cpp | 7 ++---- server/host-connection.cpp | 2 +- server/host-dbus-definitions.hpp | 5 +++- server/zones-manager.cpp | 3 +++ tests/unit_tests/client/ut-client.cpp | 43 +++++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index f4d8580..4f3a05c 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -491,15 +491,12 @@ VsmStatus Client::vsm_lookup_zone_by_id(const char* id, VsmZone* zone) noexcept VsmStatus ret = callMethod(HOST_INTERFACE, api::host::METHOD_GET_ZONE_INFO, args_in, - "((siss))", + "(siss)", &out); if (ret != VSMCLIENT_SUCCESS) { return ret; } - GVariant* unpacked; - g_variant_get(out, "(*)", &unpacked); - toBasic(unpacked, zone); - g_variant_unref(unpacked); + toBasic(out, zone); g_variant_unref(out); return ret; } diff --git a/server/host-connection.cpp b/server/host-connection.cpp index f3cbfa0..1bdd790 100644 --- a/server/host-connection.cpp +++ b/server/host-connection.cpp @@ -355,7 +355,7 @@ void HostConnection::onMessageCall(const std::string& objectPath, config::loadFromGVariant(parameters, data); if (mGetNetdevListCallback) { - auto rb = std::make_shared>(result); + auto rb = std::make_shared>(result); mGetNetdevListCallback(data, rb); } return; diff --git a/server/host-dbus-definitions.hpp b/server/host-dbus-definitions.hpp index 1e6fecc..7476bb5 100644 --- a/server/host-dbus-definitions.hpp +++ b/server/host-dbus-definitions.hpp @@ -91,7 +91,10 @@ const std::string DEFINITION = " " " " " " - " " + " " + " " + " " + " " " " " " " " diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 4f34a76..d3e802b 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -810,6 +810,9 @@ void ZonesManager::handleGetZoneInfoCall(const api::ZoneId& zoneId, return; } + zoneInfo->id = zone.getId(); + zoneInfo->vt = zone.getVT(); + zoneInfo->rootPath = zone.getRootPath(); result->set(zoneInfo); } diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 197da5e..40372f4 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -221,6 +221,26 @@ BOOST_AUTO_TEST_CASE(GetActiveZoneId) vsm_client_free(client); } +BOOST_AUTO_TEST_CASE(LookupZoneById) +{ + const std::string activeZoneId = "zone1"; + + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + VsmZone info; + status = vsm_lookup_zone_by_id(client, activeZoneId.c_str(), &info); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + + BOOST_CHECK_EQUAL(info->id, activeZoneId); + BOOST_CHECK_EQUAL(info->state, RUNNING); + BOOST_CHECK_EQUAL(info->terminal, -1); + BOOST_CHECK_EQUAL(info->rootfs_path, "/tmp/ut-zones/" + activeZoneId + "/rootfs"); + + vsm_zone_free(info); + vsm_client_free(client); +} + BOOST_AUTO_TEST_CASE(SetActiveZone) { const std::string newActiveZoneId = "zone2"; @@ -425,4 +445,27 @@ BOOST_AUTO_TEST_CASE(Provision) vsm_client_free(client); } +BOOST_AUTO_TEST_CASE(ZoneGetNetdevs) +{ + const std::string activeZoneId = "zone1"; + + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + VsmArrayString netdevs; + status = vsm_zone_get_netdevs(client, activeZoneId.c_str(), &netdevs); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + BOOST_REQUIRE(netdevs != NULL); + vsm_array_string_free(netdevs); + vsm_client_free(client); +} + +//TODO: We need createBridge from vasum::netdev +//BOOST_AUTO_TEST_CASE(CreateDestroyNetdev) +//BOOST_AUTO_TEST_CASE(LookupNetdev) +//BOOST_AUTO_TEST_CASE(GetSetDeleteIpAddr) +//BOOST_AUTO_TEST_CASE(NetdevUpDown) + + + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 2c75d62ba8dd17cbc33a159451d9b86c2109e4dc Mon Sep 17 00:00:00 2001 From: Krzysztof Dynowski Date: Mon, 16 Feb 2015 19:43:29 +0100 Subject: [PATCH 11/16] Cleaned integration tests, load daemon.conf as json [Bug/Feature] Integration tests neglected, fix launchProc [Cause] tests outdated [Solution] update test scripts [Verification] Build, install, run integrataion tests Change-Id: I4c911d7e7842e96e0fe0716ecab0b03331032f06 --- tests/integration_tests/common/vsm_test_utils.py | 7 +- .../image_tests/config_checker.py | 77 +-------- .../network_tests/network_common.py | 188 +++------------------ .../network_tests/network_tests.py | 17 +- 4 files changed, 39 insertions(+), 250 deletions(-) diff --git a/tests/integration_tests/common/vsm_test_utils.py b/tests/integration_tests/common/vsm_test_utils.py index bb84f99..30e0ac8 100644 --- a/tests/integration_tests/common/vsm_test_utils.py +++ b/tests/integration_tests/common/vsm_test_utils.py @@ -5,7 +5,6 @@ import subprocess import os - def launchProc(cmd): '''! Launch specified command as a subprocess. @@ -13,12 +12,12 @@ def launchProc(cmd): stderr. @param cmd Command to be launched - @return Tuple containing output provided by specified command and return code. + @return Tuple containing subprocess exit code and text output received ''' p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - ret = p.wait() + rc = p.wait() output = p.stdout.read() - return (output, ret) + return (rc,output) def mount(dir, opts=[]): diff --git a/tests/integration_tests/image_tests/config_checker.py b/tests/integration_tests/image_tests/config_checker.py index 0d47b8e..ce16403 100644 --- a/tests/integration_tests/image_tests/config_checker.py +++ b/tests/integration_tests/image_tests/config_checker.py @@ -14,76 +14,13 @@ class ConfigChecker: zones existing in the system (name and rootfs path). ''' - def __parseLibvirtXML(self, path): - '''! Parses libvirt's configuration in order to extract zone name and path. + def __init__(self, confpath): + print "ConfigChecker", confpath + with open(confpath) as jf: + self.conf = json.load(jf) - @param path Libvirt's zone configuration path - ''' - tree = ET.parse(path) - root = tree.getroot() - name = root.find("name").text - rootFound = False + # TODO: extract data for tests from json object - # extract directory mountings - for elem in root.iterfind('devices/filesystem'): - if "type" not in elem.attrib: - raise Exception("'type' attribute not found for 'filesystem' node in file: " + path) - - nodeSource = elem.find("source") - if nodeSource is None: - raise Exception("'source' not found in 'filesystem' node in file: " + path) - - nodeTarget = elem.find("target") - if nodeTarget is None: - raise Exception("'target' not found in 'filesystem' node in file: " + path) - - source = nodeSource.attrib["dir"] - target = nodeTarget.attrib["dir"] - if target == "/": - if rootFound: - raise Exception("Multiple root fs mounts found in file: " + path) - else: - self.zones[name] = source - print " Zone '" + name + "' found at: " + source - rootFound = True - - if not rootFound: - raise Exception("Root directory of '" + name + "' zone not specified in XML") - - def __init__(self, mainConfigPath): - '''! Parses daemon's JSON configuration files. - - @param mainConfigPath Path to the main config "daemon.conf" - ''' self.zones = {} - print "Looking for zone IDs..." - - # load main daemon JSON config file - if not os.path.isfile(mainConfigPath): - raise Exception(mainConfigPath + " not found. " + - "Please verify that vasum is properly installed.") - with open(mainConfigPath) as daemonConfigStr: - daemonConfigData = json.load(daemonConfigStr) - daemonConfigDir = os.path.dirname(os.path.abspath(mainConfigPath)) - - # get dictionary with zones - zoneConfigPaths = daemonConfigData["zoneConfigs"] - for configPath in zoneConfigPaths: - - # open zone config file - zoneConfigPath = os.path.join(daemonConfigDir, configPath) - if not os.path.isfile(zoneConfigPath): - raise Exception(zoneConfigPath + " not found. " + - "Please verify that vasum is properly installed.") - with open(zoneConfigPath) as zoneConfigStr: - zoneConfigData = json.load(zoneConfigStr) - - # extract XML config path for libvirt - libvirtConfigPath = os.path.join(daemonConfigDir, "zones", - zoneConfigData["config"]) - - output, ret = vsm_test_utils.launchProc("virt-xml-validate " + libvirtConfigPath) - if ret == 0: - self.__parseLibvirtXML(libvirtConfigPath) - else: - raise Exception(output) + #TODO prepate zones config into list of (zone_name,zone_roofs_path) + # self.conf["zoneConfigs"] -> (zone, self.conf["zonesPath"]+"/"+zone) diff --git a/tests/integration_tests/network_tests/network_common.py b/tests/integration_tests/network_tests/network_common.py index 945b255..acb120c 100755 --- a/tests/integration_tests/network_tests/network_common.py +++ b/tests/integration_tests/network_tests/network_common.py @@ -21,6 +21,7 @@ import subprocess import string import sys import os +import traceback # Debug command on/off DEBUG_COMMAND=False @@ -28,18 +29,18 @@ DEBUG_COMMAND=False # Test urls TEST_URL_INTERNET=["www.samsung.com", "www.google.com", "www.oracle.com"] +#TODO read path from config (daemon.conf) # Path to test zone -TEST_ZONE_PATH="/opt/usr/zones/private" +TEST_ZONE_PATH="/usr/share/.zones" # Device Ethernet device ETHERNET_DEVICE="usb0" ETHERNET_DEVICE_DETECT=False # Test zones -ZONE_T1="business" -ZONE_T2="private" - -zones=[ZONE_T1, ZONE_T2] +TEST_ZONE="test" +TEST_ZONE_ROOTFS=TEST_ZONE_PATH+"/"+TEST_ZONE +ZONES=[ TEST_ZONE ] # Null device OUTPUT_TO_NULL_DEVICE=" >/dev/null 2>&1 " @@ -47,18 +48,25 @@ OUTPUT_TO_NULL_DEVICE=" >/dev/null 2>&1 " # Ping timeout PING_TIME_OUT=3 -# The calss store test cases results -class TestNetworkInfo: +# The class store test cases results +class TestInfo: testName = "" - testItemType = [] - testItemName = [] - testItemStatus = [] - testItemResult = [] - testItemDescription = [] + testItems = [] def __init__(self, tn): self.testName = tn +class TestItem: + itype = "" + name = "" + description = "" + status = 0 + result = "" + + def __init__(self, tn, n): + self.itype = tn + self.name = n + # ---------------------------------------------------------- # Functions print info/error/warning message # @@ -95,7 +103,9 @@ def runCommand(cmd, blockDebug=False): rc=0 try: out=vsm_test_utils.launchProc(run_cmd) + rc=out[0] except Exception: + traceback.print_exc() rc=1 if(DEBUG_COMMAND and not blockDebug): @@ -125,10 +135,10 @@ def runCommandAndReadOutput(cmd): break # ---------------------------------------------------------- -# The function checks whether test zone image is present in system +# The function checks whether zone path is present in system # -def test_guest_image(): - rc = runCommand("/usr/bin/chroot " + TEST_ZONE_PATH + " /bin/true") +def test_zone_path(): + rc = runCommand("ls " + TEST_ZONE_PATH) if( rc != 0 ): return 1 return 0 @@ -147,151 +157,3 @@ def getActiveEthernetDevice(): return 0 -# ---------------------------------------------------------- -# The function checks whether mandatory tools are present in -# the system -# -def test_mandatory_toos(): - - tools =["/usr/bin/ping"] - root_tools=[TEST_ZONE_PATH] - - for i in range(len(tools)): - rc = runCommand("/usr/bin/ls " + root_tools[i] + tools[i]) - if( rc != 0 ): - if( root_tools[i] != "" ): - LOG_ERROR("No " + tools[i] + " command in guest") - else: - LOG_ERROR("No " + tools[i] + " command in host") - return 1 - return 0 - -def virshCmd(args): - return runCommand("/usr/bin/virsh -c lxc:/// " + args) - -# ---------------------------------------------------------- -# The function tests single test case result -# -def test_result(expected_result, result): - if((expected_result >= 0 and result == expected_result) or (expected_result < 0 and result != 0)): - return 0 - return 1 - -# ---------------------------------------------------------- -# The function performs single internet access test -# -def internetAccessTest(zone): - count=0 - for item in TEST_URL_INTERNET: - LOG_INFO(" Test for URL : " + item); - rc = virshCmd("lxc-enter-namespace " + zone + \ - " --noseclabel -- /usr/bin/ping -c 3 -W " + \ - str(PING_TIME_OUT) + " " + item) - if(rc != 0): - count = count + 1 - - if(count != 0): - return 1 - - return 0; - -# ---------------------------------------------------------- -# The function performs single internet access test -# -def networkVisibiltyTest(zone, dest_ip): - return virshCmd("lxc-enter-namespace " + zone + \ - " --noseclabel -- /usr/bin/ping -c 3 -W " + \ - str(PING_TIME_OUT) + " " + dest_ip) - -def printInternetAccessTestStatus(zone, testInfo1): - - text = " Internet access for zone: " + zone + \ - "; TCS = " + testInfo1.testItemResult[len(testInfo1.testItemResult)-1] - - if(testInfo1.testItemResult[len(testInfo1.testItemResult)-1] == "Success"): - LOG_INFO(text) - else: - LOG_ERROR(text) - -def networkVisibiltyTestStatus(src, dest, ip, testInfo2): - - text = " Zone access: " + src + \ - " -> " + dest + \ - " [" + ip + "]" + \ - "; TCS = " + testInfo2.testItemResult[len(testInfo2.testItemResult)-1] - - if(testInfo2.testItemResult[len(testInfo2.testItemResult)-1] == "Success"): - LOG_INFO(text) - else: - LOG_ERROR(text) - -# ---------------------------------------------------------- -# The function performs test case for two zones - Business and Private. -# Both zones are mutually isolated and have access to the Internet. -# -def twoNetworks(): - ltestInfo = TestNetworkInfo("Two networks tests") - - # 0. Test data - zones_list = [ZONE_T1, ZONE_T2] - dest_zones_list = [ZONE_T2, ZONE_T1] - test_ip_list = [["10.0.101.2"], ["10.0.102.2"]] - test_1_expected_res = [ 0, 0] - test_2_expected_res = [-1, -1] - - # 1. Enable internet access for both networks - LOG_INFO(" - Setup device") - - # 2. Internet access - LOG_INFO(" - Two zones environment network test case execution") - LOG_INFO(" - Internet access test") - for i in range(len(zones_list)): - - # - Test case info - ltestInfo.testItemType.append("[Two nets] Internet access") - ltestInfo.testItemName.append(zones_list[i]) - ltestInfo.testItemDescription.append("Internet access test for : " + zones_list[i]) - - # - Perform test - rc = internetAccessTest(zones_list[i]) - - # - Test status store - if(test_result(test_1_expected_res[i], rc) == 0): - ltestInfo.testItemStatus.append(0) - ltestInfo.testItemResult.append("Success") - else: - ltestInfo.testItemStatus.append(1) - ltestInfo.testItemResult.append("Error") - - # - Print status - printInternetAccessTestStatus(zones_list[i], ltestInfo) - - # 3. Mutual zones visibility - LOG_INFO(" - Zones isolation") - for i in range(len(zones_list)): - # Interate over destynation ips - dest_ips = test_ip_list[i] - - for j in range(len(dest_ips)): - # - Test case info - ltestInfo.testItemType.append("[Two nets] Visibility") - ltestInfo.testItemName.append(zones_list[i] + "->" + dest_zones_list[i]) - ltestInfo.testItemDescription.append("Zone access for : " + zones_list[i]) - - # Perform test - rc = networkVisibiltyTest(zones_list[i], dest_ips[j]) - - # - Test status store - if(test_result(test_2_expected_res[i], rc) == 0): - ltestInfo.testItemStatus.append(0) - ltestInfo.testItemResult.append("Success") - else: - ltestInfo.testItemStatus.append(1) - ltestInfo.testItemResult.append("Error") - - # - Print status - networkVisibiltyTestStatus(zones_list[i], dest_zones_list[i], dest_ips[j], ltestInfo) - - LOG_INFO(" - Clean environment") - - return ltestInfo diff --git a/tests/integration_tests/network_tests/network_tests.py b/tests/integration_tests/network_tests/network_tests.py index 980830e..f5fe734 100644 --- a/tests/integration_tests/network_tests/network_tests.py +++ b/tests/integration_tests/network_tests/network_tests.py @@ -35,17 +35,12 @@ class NetworkTestCase(unittest.TestCase): self.assertTrue(False, "ROOT user is required to run the test") return - # 2. Test zone images - if(test_guest_image() == 1): - self.assertTrue(False, "No test zone in path :" + TEST_ZONE_PATH) + # 2. Test zone path + if(test_zone_path() == 1): + self.assertTrue(False, "No test zone path :" + TEST_ZONE_PATH) return - # 3. Test mandatory tools - if(test_mandatory_toos() == 1): - self.assertTrue(False, "No mandatory tools on host or in guest") - return - - # 4. Ethernet device obtaning + # 3. Ethernet device obtaning if(ETHERNET_DEVICE_DETECT and getActiveEthernetDevice() == 1): self.assertTrue(False, "Cannot obtain ethernet device") return @@ -53,10 +48,6 @@ class NetworkTestCase(unittest.TestCase): def test_01twoNetworks(self): '''! Checks networks configuration ''' - print("\n") - ret=twoNetworks() - for item in ret.testItemStatus: - self.assertTrue(item == 0) def main(): unittest.main(verbosity=2) -- 2.7.4 From d14412064cb787309d2a91c77025ae7e1e025b4e Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Tue, 7 Apr 2015 08:25:21 +0200 Subject: [PATCH 12/16] Move shutdown timeout to Zone config [Feature] Shutdown timeout is moved to Zone configuration file [Cause] Shutdown timeout was a constant hardcoded into Zone Admin [Solution] Move timeout for shutdown to Zone config file [Verification] Build, install, run tests Change-Id: Ie8dd1f81d6fd21d7685923c31361a86dde5c9a3d --- server/configs/templates/default.conf | 1 + server/zone-admin.cpp | 9 +-------- server/zone-config.hpp | 11 ++++++++++- .../client/configs/ut-client/templates/console-dbus.conf.in | 1 + .../server/configs/ut-server/templates/default.conf | 1 + .../server/configs/ut-zone-admin/templates/buggy.conf | 1 + .../server/configs/ut-zone-admin/templates/missing.conf | 1 + .../configs/ut-zone-admin/templates/test-no-shutdown.conf | 1 + .../server/configs/ut-zone-admin/templates/test.conf | 1 + tests/unit_tests/server/configs/ut-zone/templates/buggy.conf | 1 + .../server/configs/ut-zone/templates/test-dbus.conf.in | 1 + tests/unit_tests/server/configs/ut-zone/templates/test.conf | 1 + .../configs/ut-zones-manager/templates/console-dbus.conf.in | 1 + .../server/configs/ut-zones-manager/templates/console.conf | 1 + 14 files changed, 23 insertions(+), 9 deletions(-) diff --git a/server/configs/templates/default.conf b/server/configs/templates/default.conf index 42f587b..697be47 100644 --- a/server/configs/templates/default.conf +++ b/server/configs/templates/default.conf @@ -8,6 +8,7 @@ "cpuQuotaBackground" : 1000, "privilege" : 10, "vt" : 0, + "shutdownTimeout" : 10, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "runMountPoint" : "~NAME~/run", diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp index 3098f29..0f831d7 100644 --- a/server/zone-admin.cpp +++ b/server/zone-admin.cpp @@ -41,13 +41,6 @@ namespace vasum { -namespace { - -// TODO: this should be in zone's configuration file -const int SHUTDOWN_WAIT = 10; - -} // namespace - const std::uint64_t DEFAULT_CPU_SHARES = 1024; const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000; @@ -163,7 +156,7 @@ void ZoneAdmin::stop() return; } - if (!mZone.shutdown(SHUTDOWN_WAIT)) { + if (!mZone.shutdown(mConfig.shutdownTimeout)) { // force stop if (!mZone.stop()) { throw ZoneOperationException("Could not stop zone"); diff --git a/server/zone-config.hpp b/server/zone-config.hpp index f5d81e5..8d92800 100644 --- a/server/zone-config.hpp +++ b/server/zone-config.hpp @@ -92,6 +92,14 @@ struct ZoneConfig { */ std::vector validLinkPrefixes; + /** + * Timeout in seconds for zone to gracefully shut down. + * After given time, if Zone is not off, forced shutdown occurs. + * + * To wait forever, set -1 timeout. To skip waiting, set 0 timeout. + */ + int shutdownTimeout; + CONFIG_REGISTER ( lxcTemplate, @@ -103,7 +111,8 @@ struct ZoneConfig { cpuQuotaBackground, permittedToSend, // TODO move to dynamic and add an API to change permittedToRecv, // TODO move to dynamic and add an API to change - validLinkPrefixes + validLinkPrefixes, + shutdownTimeout ) }; 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 7778208..7df03e4 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "/tmp/ut-run/~NAME~", "provisions" : [], "permittedToSend" : [ "/tmp/.*" ], 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 a2f703e..b637d72 100644 --- a/tests/unit_tests/server/configs/ut-server/templates/default.conf +++ b/tests/unit_tests/server/configs/ut-server/templates/default.conf @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 f585ae8..c40ab33 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 a3f305b..99e893d 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 98e95ab..363c7df 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 a16b3fa..df787df 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 79436c0..91a9f7f 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/buggy.conf @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 5d76429..7d71f2d 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "/tmp/ut-run/zoneId", "provisions" : [], "permittedToSend" : [], 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 168aa21..a58f932 100644 --- a/tests/unit_tests/server/configs/ut-zone/templates/test.conf +++ b/tests/unit_tests/server/configs/ut-zone/templates/test.conf @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [], 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 7778208..7df03e4 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : true, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "/tmp/ut-run/~NAME~", "provisions" : [], "permittedToSend" : [ "/tmp/.*" ], 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 6e49c5b..5d5509b 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 @@ -10,6 +10,7 @@ "enableDbusIntegration" : false, "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, + "shutdownTimeout" : 10, "runMountPoint" : "", "provisions" : [], "permittedToSend" : [ "/tmp/.*" ], -- 2.7.4 From 3479483f4debddc67aca0c3edec2a8d06ed03911 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Tue, 7 Apr 2015 10:54:00 +0200 Subject: [PATCH 13/16] Optimize launchAsRoot when UID is 0 [Feature] Optimization in launchAsRoot function [Cause] There is no need to fork when we are already launched as root [Solution] Call func directly when UID is 0 [Verification] Build, install, run tests Change-Id: I25453b18329d1c5f353e4303d82836943d19528b --- common/utils/environment.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index fc45321..511fcda 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -177,18 +177,22 @@ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps) bool launchAsRoot(const std::function& func) { - // TODO optimize if getuid() == 0 - return executeAndWait([&func]() { - if (::setuid(0) < 0) { - LOGW("Failed to become root: " << getSystemErrorMessage()); - _exit(EXIT_FAILURE); - } - - if (!func()) { - LOGE("Failed to successfully execute func"); - _exit(EXIT_FAILURE); - } - }); + if (::getuid() == 0) { + // we are already root, no need to fork + return func(); + } else { + return executeAndWait([&func]() { + if (::setuid(0) < 0) { + LOGW("Failed to become root: " << getSystemErrorMessage()); + _exit(EXIT_FAILURE); + } + + if (!func()) { + LOGE("Failed to successfully execute func"); + _exit(EXIT_FAILURE); + } + }); + } } bool joinToNs(int nsPid, int ns) -- 2.7.4 From d230629cdf0a8c0df1747b7d0bc4f1ffeee01623 Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Wed, 8 Apr 2015 13:36:17 +0200 Subject: [PATCH 14/16] Update tizen common (with wayland) lxc template [Bug/Feature] Adjust template to new platform image [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: If2771b8f39ca1422885fb241a7d7f0958b965065 Signed-off-by: Dariusz Michaluk --- server/configs/lxc-templates/tizen-common-wayland.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/server/configs/lxc-templates/tizen-common-wayland.sh b/server/configs/lxc-templates/tizen-common-wayland.sh index 5c572b7..48a2ff9 100755 --- a/server/configs/lxc-templates/tizen-common-wayland.sh +++ b/server/configs/lxc-templates/tizen-common-wayland.sh @@ -152,6 +152,20 @@ WantedBy=graphical.target EOF chmod 644 ${path}/systemd/system/display-manager-run.service +# TODO temporary solution to set proper access rights +cat <>${path}/systemd/system/ptmx-fix.service +[Unit] +Description=Temporary fix access rights + +[Service] +ExecStart=/bin/sh -c '/bin/chmod 666 /dev/ptmx; /bin/chown root:tty /dev/ptmx; /bin/chsmack -a "*" /dev/ptmx' + +[Install] +WantedBy=multi-user.target +EOF +chmod 644 ${path}/systemd/system/ptmx-fix.service +/bin/ln -s ${path}/systemd/system/ptmx-fix.service ${path}/systemd/system/multi-user.target.wants/ptmx-fix.service + sed -e 's/run\/display/tmp/g' /usr/lib/systemd/system/display-manager.path >> ${path}/systemd/system/display-manager.path chmod 644 ${path}/systemd/system/display-manager.path sed -e 's/run\/display/tmp/g' /usr/lib/systemd/system/display-manager.service >> ${path}/systemd/system/display-manager.service -- 2.7.4 From f3e8d507082928520ee9d876ec466cf159ee38fe Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 7 Apr 2015 15:41:58 +0200 Subject: [PATCH 15/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 16/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