From 8118a30e23585d04c92e30aa67b8b716a51400f5 Mon Sep 17 00:00:00 2001 From: Krzysztof Dynowski Date: Wed, 20 May 2015 17:41:52 +0200 Subject: [PATCH 01/16] Vasum wrapper #7, add functions introduced in last vasum old API, link to Ipc [Bug/Feature] latest image not works with wrapper [Cause] last vasum old API introduced new functions [Solution] #7 implement those new functions [Verification] Build, install on target, check journal Change-Id: I95d46157d419e0886beb00574bc94a1bfe316677 --- wrapper/CMakeLists.txt | 2 +- wrapper/wrapper-compatibility.cpp | 235 +++++++++++++--------------------- wrapper/wrapper.cpp | 257 ++++++++++++++++++++++++-------------- 3 files changed, 249 insertions(+), 245 deletions(-) diff --git a/wrapper/CMakeLists.txt b/wrapper/CMakeLists.txt index 7f5ea46..a75bfa9 100644 --- a/wrapper/CMakeLists.txt +++ b/wrapper/CMakeLists.txt @@ -58,7 +58,7 @@ INCLUDE_DIRECTORIES(${LIBS_FOLDER}) INCLUDE_DIRECTORIES(${SERVER_FOLDER}) INCLUDE_DIRECTORIES(${CLIENT_FOLDER}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES} - Config SimpleDbus) + Config SimpleDbus Ipc) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/wrapper/wrapper-compatibility.cpp b/wrapper/wrapper-compatibility.cpp index adb1edd..303fcfe 100644 --- a/wrapper/wrapper-compatibility.cpp +++ b/wrapper/wrapper-compatibility.cpp @@ -39,167 +39,66 @@ #include #include #include +#include #include #include +#include "logger/logger.hpp" +#include "logger/logger-scope.hpp" + #define UNUSED(x) ((void)(x)) extern "C" { // find_container_by_pid API char *find_container_by_pid(pid_t /*pid*/) { + LOGS(""); return NULL; } // get_domain_pid API pid_t get_domain_pid(const char * /*name*/, const char * /*target*/) { + LOGS(""); return -1; } -// mainloop_add_watch -int mainloop_add_watch(struct mainloop * /*mainloop*/, int /*fd*/, mainloop_event /*event*/, mainloop_callback /*callback*/, void * /*data*/) { - return 0; -} -// mainloop_cleanup -int mainloop_cleanup(struct mainloop * /*mainloop*/) { - return 0; -} -// mainloop_create -struct mainloop *mainloop_create(void) { - struct mainloop *mainloop = (struct mainloop *)malloc(sizeof(struct mainloop)); - mainloop->epfd = -1; // epoll_create(2); - pthread_mutex_init(&mainloop->ml_mutex, NULL); - pthread_rwlock_init(&mainloop->lock, NULL); - adt_init_list(&mainloop->watches); - return mainloop; -} -// mainloop_dispatch -int mainloop_dispatch(struct mainloop * /*mainloop*/, int /*timeout*/) { - return 0; -} -// mainloop_remove_watch -int mainloop_remove_watch(struct mainloop * /*mainloop*/, int /*fd*/) { - return 0; -} -// mainloop_run -int mainloop_run(struct mainloop * /*mainloop*/, int /*timeout*/) { - return 0; -} -// mxe_alloc_endpoint -struct mxe_endpoint *mxe_alloc_endpoint(struct mxe_engine * /*engine*/, int /*fd*/, mainloop_callback /*callback*/, int /*type*/) { - return NULL; -} -// mxe_broadcast -int mxe_broadcast(struct mxe_engine * /*engine*/, struct mxe_emple * /*emple*/, ...) { - return 0; -} -// mxe_create_client -struct mxe_endpoint *mxe_create_client(struct mxe_engine *engine, const char * /*addr*/) { - struct mxe_endpoint *ep = (struct mxe_endpoint *)malloc(sizeof(struct mxe_endpoint)); - ep->type = 1; //MXE_EPT_SLAVE - ep->fd = -1; //sock_connect(addr); - ep->engine = engine; - pthread_rwlock_init(&ep->queue_lock, NULL); - pthread_mutex_init(&ep->rd_mutex, NULL); - pthread_mutex_init(&ep->wr_mutex, NULL); - adt_init_list(&ep->queue); - adt_init_list(&ep->list); - return ep; -} -// mxe_create_server -struct mxe_endpoint *mxe_create_server(struct mxe_engine * /*engine*/, const char * /*addr*/) { - return NULL; -} -// mxe_emple_factory -struct mxe_emple *mxe_emple_factory(struct mxe_proxy * /*proxy*/) { - return NULL; -} -// mxe_finalize_engine -int mxe_finalize_engine(struct mxe_engine * /*engine*/) { - return 0; -} -// mxe_free_endpoint -int mxe_free_endpoint(struct mxe_endpoint * /*ep*/) { - return 0; -} -// mxe_invoke -int mxe_invoke(struct mxe_endpoint * /*ep*/, struct mxe_emple * /*emple*/, ...) { - return 0; -} -// mxe_lookup_emple -struct mxe_emple *mxe_lookup_emple(struct mxe_endpoint * /*ep*/, int /*signature*/) { - return NULL; -} -// mxe_lookup_proxy -struct mxe_proxy *mxe_lookup_proxy(struct mxe_engine * /*engine*/, int /*id*/) { - return NULL; -} -// mxe_pop_integer -int mxe_pop_integer(struct mxe_message * /*msg*/) { - return 0; -} -// mxe_pop_string -char *mxe_pop_string(struct mxe_message * /*msg*/) { - return NULL; -} -// mxe_prepare_engine -struct mxe_engine *mxe_prepare_engine(struct mainloop *mainloop, void *data) { - struct mxe_engine *engine = (struct mxe_engine *)malloc(sizeof(struct mxe_engine)); - engine->data = data; - engine->mainloop = mainloop; - pthread_rwlock_init(&engine->endpoint_lock, NULL); - adt_init_list(&engine->endpoints); - - return engine; -} -// mxe_push_integer -int mxe_push_integer(struct mxe_message * /*msg*/, int /*value*/) { - return 0; -} -// mxe_push_string -int mxe_push_string(struct mxe_message * /*msg*/, const char * /*str*/) { - return 0; -} -// mxe_register_proxy -int mxe_register_proxy(struct mxe_engine * /*engine*/, struct mxe_proxy * /*proxy*/) { - return 0; -} -// mxe_reply_message (intenal) -int mxe_reply_message(struct mxe_endpoint * /*ep*/, struct mxe_message * /*origin*/, ...) { - return 0; -} -// mxe_reset_payload -void mxe_reset_payload(struct mxe_message * /*msg*/) { -} -// mxe_wait_for_event -int mxe_wait_for_event(struct mxe_endpoint * /*ep*/, struct mxe_emple * /*emple*/) { - return 0; -} -// sock_close_socket (intern) -int sock_close_socket(int /*fd*/) { +// sock_close_socket +API int sock_close_socket(int /*fd*/) { + LOGS(""); return 0; } // sock_connect API int sock_connect(const char * /*path*/) { - return 0; + LOGS(""); + return -1; } // sock_create_socket API int sock_create_socket(const char * /*path*/, int /*type*/, int /*flags*/) { - return 0; + LOGS(""); + return -1; } // sock_monitor_address API int sock_monitor_address(char * /*buffer*/, int /*len*/, const char * /*lxcpath*/) { + LOGS(""); return 0; } // sock_recv_fd (intern) API int sock_recv_fd(int /*fd*/, int * /*recvfd*/, void * /*data*/, size_t /*size*/) { + LOGS(""); return 0; } // sock_send_fd API int sock_send_fd(int /*fd*/, int /*sendfd*/, void * /*data*/, size_t /*size*/) { + LOGS(""); return 0; } // vasum_log -API void vasum_log(int /*type*/, const char * /*tag*/, const char * /*fmt*/ , ...) { +API void vasum_log(int type, const char *tag, const char *fmt, ...) { + va_list arg_ptr; + char buf[100]; + va_start(arg_ptr, fmt); + vsnprintf(buf, sizeof(buf), fmt, arg_ptr); + va_end(arg_ptr); + LOGS("type=" << type << " tag=" << tag << " msg=" << buf); } #define MAX_ERROR_MSG 0x1000 @@ -222,6 +121,7 @@ const char *const fso_type_strtab[] = { API const char *fso_type_to_string(vsm_fso_type_t fso) { + LOGS(""); if (fso < 0 || fso > VSM_FSO_MAX_TYPE) { return NULL; } @@ -231,6 +131,7 @@ API const char *fso_type_to_string(vsm_fso_type_t fso) API int wait_for_pid_status(pid_t pid) { + LOGS(""); int status, ret; again: @@ -239,8 +140,7 @@ API int wait_for_pid_status(pid_t pid) if (errno == EINTR) { goto again; } else { - ERROR("waitpid- pid : %d error : %s", pid, - strerror(errno)); + ERROR("waitpid pid : %d error : %s", pid, strerror(errno)); return -1; } } @@ -251,6 +151,7 @@ API int wait_for_pid_status(pid_t pid) API vsm_fso_type_t fso_string_to_type(char *str) { + LOGS(""); int len; int i; for (i = 0; i <= VSM_FSO_MAX_TYPE; i++) { @@ -264,6 +165,7 @@ API vsm_fso_type_t fso_string_to_type(char *str) API int mkdir_p(const char *dir, mode_t mode) { + LOGS(""); const char *tmp = dir; const char *orig = dir; char *makeme; @@ -286,6 +188,7 @@ API int mkdir_p(const char *dir, mode_t mode) API int lock_fd(int fd, int wait) { + LOGS(""); int ret; struct flock f; @@ -309,6 +212,7 @@ API int lock_fd(int fd, int wait) API int unlock_fd(int fd) { + LOGS(""); struct flock f; f.l_type = F_UNLCK; f.l_whence = SEEK_SET; @@ -319,11 +223,13 @@ API int unlock_fd(int fd) API int copy_smacklabel(const char * /*source*/, const char * /*dest*/) { + LOGS(""); return 0; } API int remove_file(char *path) { + LOGS(""); struct stat path_stat; DIR *dp; struct dirent *d; @@ -376,6 +282,7 @@ API int remove_file(char *path) API int copy_file(const char *source, const char *dest, int /*flags*/) { + LOGS(""); int ret; FILE *sfp, *dfp; size_t nread, nwritten, size = BUF_SIZE; @@ -426,6 +333,7 @@ API int copy_file(const char *source, const char *dest, int /*flags*/) API int regex_compile(regex_t * r, const char *regex_text) { + LOGS(""); int status = regcomp(r, regex_text, REG_EXTENDED | REG_NEWLINE); if (status != 0) { @@ -442,6 +350,7 @@ API int regex_compile(regex_t * r, const char *regex_text) API int regex_match(regex_t * r, const char *to_match) { + LOGS(""); const char *p = to_match; const int n_matches = 10; regmatch_t m[n_matches]; @@ -485,6 +394,7 @@ API int regex_match(regex_t * r, const char *to_match) API int get_peer_pid(int fd) { + LOGS(""); struct ucred cred; socklen_t cr_len = sizeof(cred); if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &cr_len) < 0) { @@ -495,23 +405,25 @@ API int get_peer_pid(int fd) API pid_t gettid(void) { + LOGS(""); return syscall(__NR_gettid); } API int set_smacklabel_fd(int fd, const char *xattr_name, const char *label) { + LOGS(""); size_t len; int ret; - if(fd < 0) + if (fd < 0) return -1; len = strnlen(label, SMACK_LABEL_LEN + 1); if (len > SMACK_LABEL_LEN) return -1; - ret = fsetxattr(fd, xattr_name, label, len+1, 0); - if(ret != 0) { + ret = fsetxattr(fd, xattr_name, label, len + 1, 0); + if (ret != 0) { ERROR("Set Smack lable error : %s", strerror(errno)); } return ret; @@ -519,52 +431,55 @@ API int set_smacklabel_fd(int fd, const char *xattr_name, const char *label) API int set_smacklabel(const char *path, const char *xattr_name, const char *label) { + LOGS(""); size_t len; int ret; - if(path == NULL) + if (path == NULL) return -1; len = strnlen(label, SMACK_LABEL_LEN + 1); if (len > SMACK_LABEL_LEN) return -1; - ret = lsetxattr(path, xattr_name, label, len+1, 0); - if(ret != 0) { + ret = lsetxattr(path, xattr_name, label, len + 1, 0); + if (ret != 0) { ERROR("Set Smack lable error : %s", strerror(errno)); } return ret; } API char *get_self_smacklabel(void) { + LOGS(""); int ret; int fd; const char *attr_path = "/proc/self/attr/current"; - char buffer[SMACK_LABEL_LEN+1]; + char buffer[SMACK_LABEL_LEN + 1]; - bzero(buffer, SMACK_LABEL_LEN+1); + bzero(buffer, SMACK_LABEL_LEN + 1); fd = open(attr_path, O_RDONLY); - if( fd < 0) { + if (fd < 0) { return NULL; } - ret = read(fd, buffer, SMACK_LABEL_LEN+1); + ret = read(fd, buffer, SMACK_LABEL_LEN + 1); close(fd); if (ret < 0) { return NULL; } - if( ret > SMACK_LABEL_LEN) { + if (ret > SMACK_LABEL_LEN) { //return NULL; } - buffer[SMACK_LABEL_LEN]=0; + buffer[SMACK_LABEL_LEN] = 0; return strdup(buffer); } API int get_self_cpuset(char *name, int buf_sz) { + LOGS(""); int fd; int lxc_len, ret; char cpuset_path[] = "/proc/self/cpuset"; @@ -585,7 +500,7 @@ API int get_self_cpuset(char *name, int buf_sz) close(fd); lxc_len = sizeof("/lxc"); - if( ret < lxc_len) { + if (ret < lxc_len) { name[0] = '/'; name[1] = 0; return 1; @@ -593,14 +508,14 @@ API int get_self_cpuset(char *name, int buf_sz) char *p; p = current_name + lxc_len; - while(*p != '\0') { - if(*p == '/') { + while (*p != '\0') { + if (*p == '/') { *p = '\0'; break; } p++; } - snprintf(name, buf_sz, "%s", current_name+lxc_len); + snprintf(name, buf_sz, "%s", current_name + lxc_len); } return ret - lxc_len; @@ -609,6 +524,7 @@ API int get_self_cpuset(char *name, int buf_sz) API char * get_pid_cpuset(int pid) { + LOGS(""); int fd; int ret; char cpuset_path[PATH_MAX]; @@ -617,7 +533,7 @@ API char * get_pid_cpuset(int pid) snprintf(cpuset_path, PATH_MAX, "/proc/%d/cpuset", pid); ret = access(cpuset_path, F_OK | R_OK); - if( ret != 0 ) + if (ret != 0) return NULL; fd = open(cpuset_path, O_RDONLY); @@ -641,6 +557,7 @@ API char * get_pid_cpuset(int pid) API char * read_namespace_link(const char *ns, int pid) { + LOGS(""); char ns_path[PATH_MAX]; char buf[NAME_MAX]; int ret; @@ -648,11 +565,11 @@ API char * read_namespace_link(const char *ns, int pid) snprintf(ns_path, PATH_MAX, "/proc/%d/ns/%s", pid, ns); ret = access(ns_path, F_OK); - if(ret != 0) + if (ret != 0) return NULL; ret = readlink(ns_path, buf, NAME_MAX); - if( ret == -1 ) { + if (ret == -1) { ERROR("Failed to readlink ns file - [%s]", ns_path); return NULL; } @@ -669,6 +586,7 @@ API char * read_namespace_link(const char *ns, int pid) API int dev_enumerate_nodes(const char *cname, dev_enumerator enumerator, void *data) { + LOGS(""); int ret; FILE *fp;; char path[PATH_MAX], entry[64]; @@ -706,6 +624,7 @@ API int dev_enumerate_nodes(const char *cname, dev_enumerator enumerator, API int dev_terminal_enumerator(int type, int major, int minor, void *data) { + LOGS(""); int *dev = (int*)data; *dev = minor; @@ -720,6 +639,7 @@ API int dev_terminal_enumerator(int type, int major, int minor, void *data) // libs/namespace.c API pid_t get_init_pid(const char *name) { + LOGS(""); char filename[PATH_MAX]; FILE *fp; pid_t ret = -1; @@ -746,6 +666,7 @@ API pid_t get_init_pid(const char *name) API pid_t get_zone_pid(const char *name, const char *target) { + LOGS(""); char path[PATH_MAX]; char cmd[PATH_MAX]; int res = 0, len; @@ -823,6 +744,7 @@ API pid_t get_zone_pid(const char *name, const char *target) API int open_ns(pid_t pid, const char *name) { + LOGS(""); int fd, ret; char path[PATH_MAX]; @@ -846,6 +768,7 @@ API int open_ns(pid_t pid, const char *name) #include static int is_console(int fd) { + LOGS(""); char arg; return (isatty(fd) && @@ -873,6 +796,7 @@ static int open_console(const char *path) API int get_console_fd(const char *path) { + LOGS(""); int fd; if (path) { @@ -905,6 +829,7 @@ API int get_console_fd(const char *path) API int vt_switch_terminal(int id) { + LOGS(""); int fd, ret = -1; fd = get_console_fd(NULL); @@ -928,6 +853,7 @@ API int vt_switch_terminal(int id) API int vt_find_unused_terminal(void) { + LOGS(""); int fd, nr = -1; fd = get_console_fd(NULL); @@ -949,6 +875,7 @@ API int vt_find_unused_terminal(void) API int vt_query_active_terminal(void) { + LOGS(""); int fd, ret = -1; struct vt_stat vtstat; @@ -1189,6 +1116,7 @@ static int parse_statement(struct parser_context *ctx, int argc, char **argv, API int parse_stream_core(struct parser_context *ctx, char *s) { + LOGS(""); struct unit_keyword_callback *kw; struct parser_state state; char *args[PARSER_MAXARGS]; @@ -1270,6 +1198,7 @@ static char *open_stream(const char *name, unsigned int *_sz) API int parse_stream(const char *name, struct unit_parser *parser) { + LOGS(""); char *stream; struct parser_context *ctx; @@ -1294,6 +1223,13 @@ API int parse_stream(const char *name, struct unit_parser *parser) return 0; } +API struct vsm_netdev *alloc_netdev(struct vsm_zone * /*zone*/, vsm_netdev_type_t /*type*/, const char * /*netdev_name*/) { + LOGS(""); + return NULL; +} +API void enter_to_ns(pid_t /*pid*/, char * /*name*/) { + LOGS(""); +} // dummy-ops static int dummy_create_zone(vsm_context_h /*ctx*/, const char * /*zone_name*/, @@ -1350,7 +1286,7 @@ static vsm_zone_h dummy_get_foreground(vsm_context_h ctx) static int dummy_iterate_zone(vsm_context_h ctx, vsm_zone_iter_cb callback, void *user_data) { - if( callback) { + if (callback) { callback(ctx->root_zone, user_data); } return VSM_ERROR_NONE; @@ -1440,7 +1376,7 @@ static int dummy_attach_zone_wait(vsm_context_h ctx, const char *zone_name, vsm_attach_command_s * command, vsm_attach_options_s * opts) { - pid_t pid=0; + pid_t pid = 0; int ret, status; ret = dummy_attach_zone(ctx, zone_name, command, opts, &pid); @@ -1482,7 +1418,7 @@ static int dummy_is_equivalent_zone(vsm_context_h /*ctx*/, pid_t /*pid*/) static int dummy_get_host_pid(vsm_zone_h zone, pid_t pid) { - if(zone == zone->parent) + if (zone == zone->parent) return pid; return -VSM_ERROR_NO_OBJECT; @@ -1517,7 +1453,7 @@ static int dummy_declare_link(vsm_context_h /*ctx*/, const char *source, } struct vasum_ops dummy_ops; -static int dummy_ops_init(){ +static int dummy_ops_init() { dummy_ops.create_zone = dummy_create_zone; dummy_ops.destroy_zone = dummy_destroy_zone; dummy_ops.start_zone = dummy_start_zone; @@ -1542,4 +1478,5 @@ static int dummy_ops_init(){ } int dummy_ops_init_i = dummy_ops_init(); + } //extern "C" diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp index 9483a87..4fc0c60 100644 --- a/wrapper/wrapper.cpp +++ b/wrapper/wrapper.cpp @@ -57,10 +57,6 @@ static struct int glib_stop; } wrap; -extern "C" { -API void vsm_string_free(VsmString string); -API void vsm_array_string_free(VsmArrayString astring); -} #ifndef offsetof #define offsetof(type, memb) ((size_t)&((type *)0)->memb) @@ -77,7 +73,6 @@ API void vsm_array_string_free(VsmArrayString astring); #define vsm_attach_command_t vsm_attach_command_s #define vsm_attach_options_t vsm_attach_options_s -#define vsm_zone_state_cb vsm_zone_state_changed_cb void __attribute__ ((constructor)) wrapper_load(void); void __attribute__ ((destructor)) wrapper_unload(void); @@ -108,9 +103,9 @@ static void callcheck() void init_wrapper() { if (wrap.done) return ; - memset(&wrap,0,sizeof(wrap)); + memset(&wrap, 0, sizeof(wrap)); wrap.done = 1; - LOGS("WRAP:"); + LOGS(""); } static struct vsm_zone* wrap_vsm_zone(WrappedContext *w, VsmZone zone, bool create = false) @@ -129,6 +124,7 @@ static struct vsm_zone* wrap_vsm_zone(WrappedContext *w, VsmZone zone, bool crea zw.client = w->client; zw.zone = zone; zw.vz.name = zone->id; + zw.vz.id = 0; zw.vz.type = NULL; zw.vz.user_data = NULL; zw.vz.rootfs_path = zone->rootfs_path; @@ -143,7 +139,7 @@ static struct vsm_zone* wrap_vsm_zone(WrappedContext *w, VsmZone zone, bool crea static int wrap_error(VsmStatus st, const Client *c) { if (st == VSMCLIENT_SUCCESS) LOGI("return success " << st); - else LOGE("return error " << st << "m=" << (c ? c->vsm_get_status_message() : "n/a")); + else LOGE("return error=" << st << ", msg=" << (c ? c->vsm_get_status_message() : "n/a")); switch (st) { case VSMCLIENT_SUCCESS: return VSM_ERROR_NONE; case VSMCLIENT_CUSTOM_ERROR: return -VSM_ERROR_GENERIC; @@ -171,7 +167,7 @@ static void init_context_wrap(WrappedContext *w) //init root_zone ctx->root_zone = &w->hq_root; ctx->root_zone->name = (char*)""; - ctx->root_zone->id=0; + ctx->root_zone->id = 0; ctx->root_zone->rootfs_path = (char*)"/"; ctx->root_zone->terminal = -1; @@ -201,9 +197,13 @@ static void init_context_wrap(WrappedContext *w) //ctx->data = ep; } +extern "C" { +API void vsm_string_free(VsmString string); +API void vsm_array_string_free(VsmArrayString astring); + API vsm_context_h vsm_create_context(void) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = new WrappedContext(); init_context_wrap(w); @@ -214,7 +214,7 @@ API vsm_context_h vsm_create_context(void) API int vsm_cleanup_context(vsm_context_h ctx) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); if (w->client != NULL) { @@ -225,6 +225,7 @@ API int vsm_cleanup_context(vsm_context_h ctx) zw.netdevs.clear(); } w->zones.clear(); + pthread_rwlock_destroy(&ctx->lock); delete w; return VSM_ERROR_NONE; } @@ -260,7 +261,7 @@ API vsm_error_e vsm_last_error(struct vsm_context *ctx) API int vsm_get_poll_fd(struct vsm_context *ctx) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); UNUSED(w); @@ -271,7 +272,7 @@ API int vsm_get_poll_fd(struct vsm_context *ctx) } API int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout) { - LOGS("WRAP:"); + LOGS(""); callcheck(); UNUSED(flags); UNUSED(timeout); @@ -285,7 +286,7 @@ API int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout) API int vsm_create_zone(struct vsm_context *ctx, const char *zone_name, const char *template_name, int flag) { - LOGS("WRAP:create_zone " << zone_name); + LOGS("create_zone " << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); UNUSED(flag); @@ -300,7 +301,7 @@ API int vsm_create_zone(struct vsm_context *ctx, const char *zone_name, const ch API int vsm_destroy_zone(struct vsm_context *ctx, const char *zone_name, int force) { - LOGS("WRAP:zone=" << zone_name); + LOGS("zone=" << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); UNUSED(force); @@ -316,7 +317,7 @@ API int vsm_destroy_zone(struct vsm_context *ctx, const char *zone_name, int for API int vsm_start_zone(struct vsm_context *ctx, const char *zone_name) { - LOGS("WRAP:zone=" << zone_name); + LOGS("zone=" << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); if (!w->client) return VSM_ERROR_GENERIC; @@ -326,7 +327,7 @@ API int vsm_start_zone(struct vsm_context *ctx, const char *zone_name) API int vsm_shutdown_zone(struct vsm_context *ctx, const char *zone_name, int force) { - LOGS("WRAP:zone=" << zone_name); + LOGS("zone=" << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); UNUSED(force); @@ -337,7 +338,7 @@ API int vsm_shutdown_zone(struct vsm_context *ctx, const char *zone_name, int fo API int vsm_lock_zone(struct vsm_context *ctx, const char *zone_name, int shutdown) { - LOGS("WRAP:zone=" << zone_name); + LOGS("zone=" << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); UNUSED(shutdown); @@ -348,7 +349,7 @@ API int vsm_lock_zone(struct vsm_context *ctx, const char *zone_name, int shutdo API int vsm_unlock_zone(struct vsm_context *ctx, const char *zone_name) { - LOGS("WRAP:zone=" << zone_name); + LOGS("zone=" << zone_name); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); if (!w->client) return VSM_ERROR_GENERIC; @@ -358,7 +359,7 @@ API int vsm_unlock_zone(struct vsm_context *ctx, const char *zone_name) API int vsm_set_foreground(struct vsm_zone *zone) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedZone *w = container_of(zone, WrappedZone, vz); if (!w->client) return VSM_ERROR_GENERIC; @@ -388,12 +389,13 @@ API int vsm_attach_zone_wait(struct vsm_context *ctx, API int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); if (!w->client) return -VSM_ERROR_GENERIC; callback(ctx->root_zone, user_data); for (auto& z : w->zones) { + LOGI("iterate callback zone: " << z.zone->id); callback(&z.vz, user_data); } return 0; @@ -401,7 +403,7 @@ API int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zo API struct vsm_zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path) { - LOGS("WRAP:name=" << path); + LOGS("name=" << path); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); VsmZone zone; @@ -415,16 +417,18 @@ API struct vsm_zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char //supposed return ref to internal struct API struct vsm_zone *vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid) { - LOGS("WRAP: pid=" << pid); + LOGS("pid=" << pid); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); VsmZone zone; VsmString id; + VsmStatus st; if (!w->client) return NULL; - if (w->client->vsm_lookup_zone_by_pid(pid, &id) != VSMCLIENT_SUCCESS) { - LOGE("vsm_lookup_zone_by_pid(" << pid << ") error"); + if ((st = w->client->vsm_lookup_zone_by_pid(pid, &id)) != VSMCLIENT_SUCCESS) { + wrap_error(st, w->client); return NULL; } + LOGI("found zone(pid=" << pid << ")='" << id << "'"); if (::strcmp(id, "host") == 0) { return w->hq_ctx.root_zone; } @@ -432,9 +436,9 @@ API struct vsm_zone *vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid) return wrap_vsm_zone(w, zone); } -API int vsm_add_state_changed_callback(struct vsm_context *ctx, vsm_zone_state_cb callback, void *user_data) +API int vsm_add_state_changed_callback(struct vsm_context *ctx, vsm_zone_state_changed_cb callback, void *user_data) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); VsmSubscriptionId subscriptionId; @@ -443,7 +447,7 @@ API int vsm_add_state_changed_callback(struct vsm_context *ctx, vsm_zone_state_c void { VsmZone zone; //TODO what are valid state, event - vsm_zone_state_t t=VSM_ZONE_STATE_RUNNING; + vsm_zone_state_t t = VSM_ZONE_STATE_RUNNING; UNUSED(dbusAddress); w->client->vsm_lookup_zone_by_id(id, &zone); callback(wrap_vsm_zone(w, zone), t, data); @@ -454,7 +458,7 @@ API int vsm_add_state_changed_callback(struct vsm_context *ctx, vsm_zone_state_c API int vsm_del_state_changed_callback(struct vsm_context *ctx, int handle) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); VsmSubscriptionId subscriptionId = (VsmSubscriptionId)handle; @@ -464,7 +468,7 @@ API int vsm_del_state_changed_callback(struct vsm_context *ctx, int handle) API int vsm_grant_device(struct vsm_zone *dom, const char *name, uint32_t flags) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedZone *w = container_of(dom, WrappedZone, vz); const char *id = dom->name; @@ -476,7 +480,7 @@ API int vsm_grant_device(struct vsm_zone *dom, const char *name, uint32_t flags) API int vsm_revoke_device(struct vsm_zone *dom, const char *name) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedZone *w = container_of(dom, WrappedZone, vz); const char *id = dom->name; @@ -486,7 +490,7 @@ API int vsm_revoke_device(struct vsm_zone *dom, const char *name) API struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev) { - LOGS("WRAP:"); + LOGS(""); callcheck(); UNUSED(zone); UNUSED(type); @@ -521,26 +525,15 @@ API struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_ return &w->netdevs.back(); //pointer to struct on vector } -API int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev) +API int vsm_destroy_netdev(vsm_netdev_h) { - LOGS("WRAP:"); - callcheck(); - WrappedZone *w = container_of(zone, WrappedZone, vz); - - VsmStatus st = w->client->vsm_destroy_netdev(zone->name, netdev->name); - if (st == VSMCLIENT_SUCCESS) { - auto devbyname = [netdev](const vsm_netdev& v) {return ::strcmp(v.name, netdev->name) == 0;}; - auto devlist = std::find_if(w->netdevs.begin(), w->netdevs.end(), devbyname); - if (devlist != w->netdevs.end()) { - w->netdevs.erase(devlist); - } - } - return wrap_error(st, w->client); + LOGS(""); + return 0; } API int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedZone *w = container_of(zone, WrappedZone, vz); for (auto nd : w->netdevs) { @@ -551,7 +544,7 @@ API int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_ne API struct vsm_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name) { - LOGS("WRAP:"); + LOGS(""); callcheck(); WrappedZone *w = container_of(zone, WrappedZone, vz); VsmNetdev nd; @@ -568,7 +561,7 @@ API struct vsm_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const ch API int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode) { - LOGS("WRAP:"); + LOGS(""); callcheck(); /* Old implementation is following: (but implemented in server) args.oldpath = oldpath; @@ -610,7 +603,7 @@ API int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const ch API int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target) { - LOGS("WRAP:src=" << source << ", dst=" << target); + LOGS("src=" << source << ", dst=" << target); callcheck(); /* Old implementation is following: (but implemented in server) args.oldpath = oldpath; @@ -637,7 +630,7 @@ API int vsm_declare_mount(struct vsm_context *ctx, unsigned long flags, const void *data) { - LOGS("WRAP:"); + LOGS(""); callcheck(); /* Old implementation is following: (but implemented in server) args.oldpath = oldpath; @@ -659,72 +652,53 @@ API int vsm_declare_mount(struct vsm_context *ctx, return VSM_ERROR_NONE; } -API const char * vsm_get_zone_rootpath(vsm_zone_h /*zone*/) +API const char * vsm_get_zone_rootpath(vsm_zone_h zone) { - LOGS("WRAP:"); - return NULL; + LOGS(""); + return zone == NULL ? NULL : zone->rootfs_path; } -API const char * vsm_get_zone_name(vsm_zone_h /*zone*/) +API const char * vsm_get_zone_name(vsm_zone_h zone) { - LOGS("WRAP:"); - return NULL; + LOGS(""); + return zone == NULL ? NULL : zone->name; } -API int vsm_is_host_zone(vsm_zone_h /*zone*/) +API int vsm_is_host_zone(vsm_zone_h zone) { - LOGS("WRAP:"); - return VSM_ERROR_NONE; + LOGS(""); + if (zone == NULL) + return -VSM_ERROR_INVALID; + + return zone->parent == zone ? 1 : 0; } API vsm_zone_h vsm_join_zone(vsm_zone_h /*zone*/) { - LOGS("WRAP:"); + LOGS(""); return NULL; } -API int vsm_canonicalize_path(const char * /*input_path*/, char ** /*output_path*/) -{ - LOGS("WRAP:"); - return VSM_ERROR_NONE; -} - -static int is_valid_context(void * /*v*/) -{ - return 1; -} -static const char *vsm_error_string_v0_34(struct vsm_context *ctx) -{ - vsm_error_e error = ctx->error; - if (error < 0 || error > VSM_MAX_ERROR) { - return NULL; - } - return vsm_error_strtab[error]; -} -static const char *vsm_error_string_v0_3_1(vsm_error_e error) +API int vsm_canonicalize_path(const char *input_path, char **output_path) { - if (error < 0 || error > VSM_MAX_ERROR) { - return NULL; - } - return vsm_error_strtab[error]; + LOGS(""< VSM_MAX_ERROR) { + return NULL; } + return vsm_error_strtab[error]; } API struct vsm_zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal) { - LOGS("WRAP:terminal=" << terminal); + LOGS("terminal=" << terminal); callcheck(); WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx); VsmZone zone; @@ -752,4 +726,97 @@ API void vsm_string_free(VsmString string) free(string); } +API int vsm_add_event_callback(vsm_context_h, vsm_zone_event_cb, void*) { + LOGS(""); + return 0; +} +API int vsm_del_event_callback(vsm_context_h, int) { + LOGS(""); + return 0; +} +API int vsm_add_state_callback(vsm_context_h , vsm_zone_state_cb , void *) { + LOGS(""); + return 0; +} +API int vsm_del_state_callback(vsm_context_h , int ) { + LOGS(""); + return 0; +} +API int vsm_down_netdev(vsm_netdev_h) { + LOGS(""); + return 0; +} +API vsm_zone* vsm_get_foreground(vsm_context_h ctx) { + LOGS(""); + //return ((struct vasum_ops *)(ctx->vsm_ops))->get_foreground(ctx); + return dummy_ops.get_foreground(ctx); +} +API int vsm_get_host_pid(vsm_zone_h, pid_t) { + LOGS(""); + return 0; +} +API int vsm_get_ip_addr_netdev(vsm_netdev_h, vsm_netdev_addr_t, char*, int) { + LOGS(""); + return 0; +} +API void* vsm_get_userdata(vsm_zone_h) { + LOGS(""); + return NULL; +} +API int vsm_get_zone_id(vsm_zone_h zone) { + LOGS(""); + if (zone == NULL) + return -VSM_ERROR_INVALID; + return zone->id; +} +API vsm_zone_state_t vsm_get_zone_state(vsm_zone_h zone) { + LOGS(""); + if (zone == NULL) + return static_cast(-VSM_ERROR_INVALID); + return zone->state; +} +API int vsm_get_zone_terminal(vsm_zone_h) { + LOGS(""); + return -VSM_ERROR_NOT_SUPPORTED; +} +API const char *vsm_get_zone_type(vsm_zone_h zone) { + LOGS(""); + return zone == NULL ? NULL : zone->type; +} +API int vsm_is_equivalent_zone(vsm_context_h, pid_t) { + LOGS(""); + return 0; +} +API int vsm_is_virtualized() { + LOGS(""); + return 0; /* Running in Host */ +} +// libs/network.c +API int vsm_set_ip_addr_netdev(vsm_netdev_h, vsm_netdev_addr_t, const char*, int) { + LOGS(""); + return 0; +} +API int vsm_up_netdev(vsm_netdev_h) { + LOGS(""); + return 0; +} +// libs/zone.c +API int vsm_set_userdata(vsm_zone_h, void*) { + LOGS(""); + return 0; +} +API int vsm_state_change_watch_callback(struct vsm_context * /*ctx*/, char * /*name*/, + int /*state*/, int /*event*/) { + LOGS(""); + return 0; +} +// libs/vsm_signal.c +API int vsm_signal_state_broadcast(struct mxe_engine * /*engine*/, const char * /*zone_name*/, int /*state*/) { + LOGS(""); + return 0; +} +API int vsm_signal_event_broadcast(struct mxe_engine * /*engine*/, const char * /*zone_name*/, int /*event*/) { + LOGS(""); + return 0; +} } // extern "C" -- 2.7.4 From a8e270d21722cb019cb6ccdf46926921c3e2e53d Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 21 May 2015 17:25:22 +0200 Subject: [PATCH 02/16] Fix SocketSuite/SystemdSocket [Bug] Prevent from run vasum-socket-test.service in qemu [Cause] N/A [Solution] Remove ConditionVirtualization=no [Verification] Build, install on emulator, run SocketSuite/SystemdSocket test Change-Id: I4fc0c9da2a4ca55878acec6203caab3674d94d02 --- tests/unit_tests/configs/systemd/vasum-socket-test.service | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit_tests/configs/systemd/vasum-socket-test.service b/tests/unit_tests/configs/systemd/vasum-socket-test.service index 1d43529..23c6d3a 100644 --- a/tests/unit_tests/configs/systemd/vasum-socket-test.service +++ b/tests/unit_tests/configs/systemd/vasum-socket-test.service @@ -1,6 +1,5 @@ [Unit] Description=Vasum Socket tests mini-service -ConditionVirtualization=no [Service] Type=simple -- 2.7.4 From aa1f5f7317a73b7063b7ca4cc4872cc6271c79d2 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Tue, 19 May 2015 18:38:11 +0200 Subject: [PATCH 03/16] Fix GetZoneIdByPidTestMultiple, GrantRevoke [Feature] GetZoneIdByPidTestMultiple, GrantRevoke some times fails [Cause] Timeout was too small [Solution] Increase timeout [Verification] Build, install, run tests Change-Id: Id191c1a6443e19f729dfc90c9a3c8c34dc4166e3 --- common/utils/fd-utils.hpp | 4 ++-- libs/config/fdstore.hpp | 4 ++-- libs/ipc/client.hpp | 2 +- libs/ipc/internals/processor.hpp | 2 +- libs/ipc/service.hpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/utils/fd-utils.hpp b/common/utils/fd-utils.hpp index 151eb1c..209de2c 100644 --- a/common/utils/fd-utils.hpp +++ b/common/utils/fd-utils.hpp @@ -42,7 +42,7 @@ void close(int fd); * @param size size of data to write * @param timeoutMS timeout in milliseconds */ -void write(int fd, const void* bufferPtr, const size_t size, int timeoutMS = 500); +void write(int fd, const void* bufferPtr, const size_t size, int timeoutMS = 5000); /** * Read from a file descriptor, throw on error. @@ -52,7 +52,7 @@ void write(int fd, const void* bufferPtr, const size_t size, int timeoutMS = 500 * @param size size of the data to read * @param timeoutMS timeout in milliseconds */ -void read(int fd, void* bufferPtr, const size_t size, int timeoutMS = 500); +void read(int fd, void* bufferPtr, const size_t size, int timeoutMS = 5000); /** * @return the max number of file descriptors for this process. diff --git a/libs/config/fdstore.hpp b/libs/config/fdstore.hpp index d34ea14..d76fc5f 100644 --- a/libs/config/fdstore.hpp +++ b/libs/config/fdstore.hpp @@ -50,7 +50,7 @@ public: * @param size size of the buffer * @param timeoutMS timeout in milliseconds */ - void write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS = 500); + void write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS = 5000); /** * Reads a value of the given type. @@ -59,7 +59,7 @@ public: * @param size size of the buffer * @param timeoutMS timeout in milliseconds */ - void read(void* bufferPtr, const size_t size, const unsigned int timeoutMS = 500); + void read(void* bufferPtr, const size_t size, const unsigned int timeoutMS = 5000); private: int mFD; diff --git a/libs/ipc/client.hpp b/libs/ipc/client.hpp index c76a817..fe3345a 100644 --- a/libs/ipc/client.hpp +++ b/libs/ipc/client.hpp @@ -125,7 +125,7 @@ public: template std::shared_ptr callSync(const MethodID methodID, const std::shared_ptr& data, - unsigned int timeoutMS = 500); + unsigned int timeoutMS = 5000); /** * Asynchronous method call. The return callback will be called on diff --git a/libs/ipc/internals/processor.hpp b/libs/ipc/internals/processor.hpp index b1b0a5f..121978c 100644 --- a/libs/ipc/internals/processor.hpp +++ b/libs/ipc/internals/processor.hpp @@ -262,7 +262,7 @@ public: std::shared_ptr callSync(const MethodID methodID, const PeerID peerID, const std::shared_ptr& data, - unsigned int timeoutMS = 500); + unsigned int timeoutMS = 5000); /** * Asynchronous method call diff --git a/libs/ipc/service.hpp b/libs/ipc/service.hpp index 8f6f62b..5b6297c 100644 --- a/libs/ipc/service.hpp +++ b/libs/ipc/service.hpp @@ -130,7 +130,7 @@ public: std::shared_ptr callSync(const MethodID methodID, const PeerID peerID, const std::shared_ptr& data, - unsigned int timeoutMS = 500); + unsigned int timeoutMS = 5000); /** * Asynchronous method call. The return callback will be called on -- 2.7.4 From 8de79321e3f62336cf2cdbd72ee355ae0af4bf22 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Wed, 6 May 2015 12:16:49 +0200 Subject: [PATCH 04/16] Remove libcap_ng and replace it with syscalls [Feature] libcap_ng is removed [Cause] N/A [Solution] Replace libcap_ng with syscalls [Verification] Build, install, run vasum-server without root and check if all needed capabilities were kept by the process. Change-Id: Idab4c7b579c6541d941e8c9e9c792427428f8fe5 --- client/CMakeLists.txt | 2 +- common/utils/environment.cpp | 206 ++++++++++++++++++++++++++++++++++++++-- common/utils/environment.hpp | 2 +- packaging/vasum.spec | 1 - server/CMakeLists.txt | 2 +- server/server.cpp | 2 +- tests/unit_tests/CMakeLists.txt | 2 +- zone-daemon/CMakeLists.txt | 2 +- 8 files changed, 202 insertions(+), 17 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c1fdd19..c9f4c17 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -44,7 +44,7 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS system filesystem) -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libcap-ng) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0) INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${LIBS_FOLDER}) diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index 57b6e2a..9614cfa 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -31,7 +31,6 @@ #include "base-exception.hpp" #include "logger/logger.hpp" -#include #include #include #include @@ -42,12 +41,15 @@ #include #include #include +#include #include #include +#include +#include +#include -#if !__GLIBC_PREREQ(2, 14) -#include +#if !__GLIBC_PREREQ(2, 14) #ifdef __NR_setns static inline int setns(int fd, int nstype) @@ -61,10 +63,37 @@ static inline int setns(int fd, int nstype) #endif +#ifdef __NR_capset +static inline int capset(cap_user_header_t header, const cap_user_data_t data) +{ + return syscall(__NR_capset, header, data); +} +#else +#error "capset syscall isn't available" +#endif + +#ifdef __NR_capget +static inline int capget(cap_user_header_t header, cap_user_data_t data) +{ + return syscall(__NR_capget, header, data); +} +#else +#error "capget syscall isn't available" +#endif + using namespace utils; namespace { +#define CAP_SET_INHERITABLE (1 << 0) +#define CAP_SET_PERMITTED (1 << 1) +#define CAP_SET_EFFECTIVE (1 << 2) + +// number of __user_cap_data_struct elements needed +#define CAP_DATA_ELEMENT_COUNT 2 + +typedef unsigned int CapSet; + const std::map NAMESPACES = { {CLONE_NEWIPC, "ipc"}, {CLONE_NEWNET, "net"}, @@ -125,6 +154,75 @@ bool fdSend(int socket, int fd) return true; } +inline bool isValidCap(unsigned int cap) +{ + return cap <= CAP_LAST_CAP; +} + +// hasCap assumes that "set" variable will refer to only one set of capabilities +inline bool hasCap(unsigned int cap, const cap_user_data_t data, CapSet set) +{ + // calculate which half of data we need to update + int dataInd = 0; + if (cap > 31) { + dataInd = cap >> 5; + cap %= 32; + } + + switch (set) { + case CAP_SET_INHERITABLE: + return CAP_TO_MASK(cap) & data[dataInd].inheritable ? true : false; + case CAP_SET_PERMITTED: + return CAP_TO_MASK(cap) & data[dataInd].permitted ? true : false; + case CAP_SET_EFFECTIVE: + return CAP_TO_MASK(cap) & data[dataInd].effective ? true : false; + default: + return false; + }; +} + +// these inlines work in-place and update provided "data" array +// in these inlines, "set" can refer to mulitple sets of capabilities +inline void addCap(unsigned int cap, cap_user_data_t data, CapSet set) +{ + // calculate which half of data we need to update + int dataInd = 0; + if (cap > 31) { + dataInd = cap >> 5; + cap %= 32; + } + + if ((set & CAP_SET_INHERITABLE) == CAP_SET_INHERITABLE) { + data[dataInd].inheritable |= CAP_TO_MASK(cap); + } + if ((set & CAP_SET_PERMITTED) == CAP_SET_PERMITTED) { + data[dataInd].permitted |= CAP_TO_MASK(cap); + } + if ((set & CAP_SET_EFFECTIVE) == CAP_SET_EFFECTIVE) { + data[dataInd].effective |= CAP_TO_MASK(cap); + } +} + +inline void removeCap(unsigned int cap, cap_user_data_t data, CapSet set) +{ + // calculate which half of data we need to update + int dataInd = 0; + if (cap > 31) { + dataInd = cap >> 5; + cap %= 32; + } + + if ((set & CAP_SET_INHERITABLE) == CAP_SET_INHERITABLE) { + data[dataInd].inheritable &= ~(CAP_TO_MASK(cap)); + } + if ((set & CAP_SET_PERMITTED) == CAP_SET_PERMITTED) { + data[dataInd].permitted &= ~(CAP_TO_MASK(cap)); + } + if ((set & CAP_SET_EFFECTIVE) == CAP_SET_EFFECTIVE) { + data[dataInd].effective &= ~(CAP_TO_MASK(cap)); + } +} + } // namespace namespace utils { @@ -156,19 +254,107 @@ bool setSuppGroups(const std::vector& groups) bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps) { - ::capng_clear(CAPNG_SELECT_BOTH); + ::__user_cap_header_struct header; + ::__user_cap_data_struct data[CAP_DATA_ELEMENT_COUNT]; + + // initial setup - equivalent to capng_clear + header.version = _LINUX_CAPABILITY_VERSION_3; + header.pid = ::getpid(); + memset(data, 0, CAP_DATA_ELEMENT_COUNT*sizeof(__user_cap_data_struct)); + // update cap sets - equivalent to capng_update for (const auto cap : caps) { - if (::capng_update(CAPNG_ADD, static_cast(CAPNG_EFFECTIVE | - CAPNG_PERMITTED | - CAPNG_INHERITABLE), cap)) { - LOGE("Failed to set capability: " << ::capng_capability_to_name(cap)); + if (!isValidCap(cap)) { + LOGE("Capability " << cap << " is invalid."); return false; } + + addCap(cap, data, CAP_SET_INHERITABLE | CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); } - if (::capng_change_id(uid, gid, static_cast(CAPNG_CLEAR_BOUNDING))) { - LOGE("Failed to change process user"); + // perform some checks and cap updates + bool updatedSetUid, updatedSetGid; + // check if we are capable of switching our UID + if (hasCap(CAP_SETUID, data, CAP_SET_EFFECTIVE)) { + // we want to keep CAP_SETUID after change + updatedSetUid = false; + } else { + // we don't have CAP_SETUID and switch is needed - add SETUID to effective and permitted set + updatedSetUid = true; + addCap(CAP_SETUID, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + } + + // do the same routine for CAP_SETGID + if (hasCap(CAP_SETGID, data, CAP_SET_EFFECTIVE)) { + updatedSetGid = false; + } else { + updatedSetGid = true; + addCap(CAP_SETGID, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + } + + // we need CAP_SETPCAP as well to clear bounding caps + if (!hasCap(CAP_SETPCAP, data, CAP_SET_EFFECTIVE)) { + addCap(CAP_SETPCAP, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + } + + // now we can work - first, use prctl to tell system we want to keep our caps when changing UID + if (::prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { + LOGE("prctl failed while trying to enable keepcaps: " << strerror(errno)); + return false; + } + + LOGD("Setting temporary caps to process -" << std::hex << std::setfill('0') + << " inh:" << std::setw(8) << data[1].inheritable << std::setw(8) << data[0].inheritable + << " prm:" << std::setw(8) << data[1].permitted << std::setw(8) << data[0].permitted + << " eff:" << std::setw(8) << data[1].effective << std::setw(8) << data[0].effective); + + // set our modified caps before UID/GID change + if (::capset(&header, data)) { + LOGE("capset failed: " << strerror(errno)); + return false; + } + + // CAP_SETPCAP is available, drop bounding caps + for (int i = 0; i <= CAP_LAST_CAP; ++i) { + if (::prctl(PR_CAPBSET_DROP, i, 0, 0, 0)) { + LOGE("prctl failed while dropping bounding caps: " << strerror(errno)); + return false; + } + } + + // set up GID and UID + if (::setresgid(gid, gid, gid)) { + LOGE("setresgid failed: " << strerror(errno)); + return false; + } + if (::setresuid(uid, uid, uid)) { + LOGE("setresuid failed: " << strerror(errno)); + return false; + } + + // we are after switch now - disable PR_SET_KEEPCAPS + if (::prctl(PR_SET_KEEPCAPS, 0, 0, 0, 0)) { + LOGE("prctl failed while trying to disable keepcaps: " << strerror(errno)); + return false; + } + + // disable rendundant caps + if (updatedSetUid) { + removeCap(CAP_SETUID, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + } + if (updatedSetGid) { + removeCap(CAP_SETGID, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + } + removeCap(CAP_SETPCAP, data, CAP_SET_PERMITTED | CAP_SET_EFFECTIVE); + + LOGD("Setting final caps to process -" << std::hex << std::setfill('0') + << " inh:" << std::setw(8) << data[1].inheritable << std::setw(8) << data[0].inheritable + << " prm:" << std::setw(8) << data[1].permitted << std::setw(8) << data[0].permitted + << " eff:" << std::setw(8) << data[1].effective << std::setw(8) << data[0].effective); + + // finally, apply correct caps + if (::capset(&header, data)) { + LOGE("capset failed: " << strerror(errno)); return false; } diff --git a/common/utils/environment.hpp b/common/utils/environment.hpp index 9039239..8c99dd4 100644 --- a/common/utils/environment.hpp +++ b/common/utils/environment.hpp @@ -40,7 +40,7 @@ namespace utils { bool setSuppGroups(const std::vector& groups); /** - * Set effective and permited capabilities on the current process and drop root privileges. + * Set effective and permitted capabilities on the current process and drop root privileges. */ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps); diff --git a/packaging/vasum.spec b/packaging/vasum.spec index 3b241df..82a859e 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -20,7 +20,6 @@ Summary: Daemon for managing zones BuildRequires: cmake BuildRequires: boost-devel BuildRequires: libjson-devel >= 0.10 -BuildRequires: libcap-ng-devel BuildRequires: lxc-devel BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(sqlite3) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index f9ce867..9a1985c 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -30,7 +30,7 @@ ADD_EXECUTABLE(${SERVER_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS program_options system filesystem regex) -PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0 libcap-ng) +PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${LIBS_FOLDER}) diff --git a/server/server.cpp b/server/server.cpp index 95f22a0..936db28 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -42,10 +42,10 @@ #include #include #include -#include #include #include #include +#include #ifndef VASUM_USER diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 2b5a09e..484e810 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -47,7 +47,7 @@ ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS} ${clie ## Link libraries ############################################################## FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) -PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc json gio-2.0 libcap-ng) +PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc json gio-2.0) INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER} ${CLIENT_FOLDER} ${LIBS_FOLDER} ${SOCKET_TEST_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) diff --git a/zone-daemon/CMakeLists.txt b/zone-daemon/CMakeLists.txt index 4d48141..4944dfb 100644 --- a/zone-daemon/CMakeLists.txt +++ b/zone-daemon/CMakeLists.txt @@ -31,7 +31,7 @@ ADD_EXECUTABLE(${ZONE_DAEMON_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE (Boost COMPONENTS program_options system filesystem) -PKG_CHECK_MODULES(ZONE_DAEMON_DEPS REQUIRED gio-2.0 libcap-ng) +PKG_CHECK_MODULES(ZONE_DAEMON_DEPS REQUIRED gio-2.0) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${LIBS_FOLDER}) -- 2.7.4 From 9bc344d7c4b3e6b73aeabef1488393c409796490 Mon Sep 17 00:00:00 2001 From: Krzysztof Dynowski Date: Mon, 25 May 2015 13:13:32 +0200 Subject: [PATCH 05/16] Vasum wrapper #8: implement socket related functions, obsolete vasum-daemon [Bug/Feature] socket not opens, rpm install conflict [Cause] N/A [Solution] #8 implement socket creation, etc. [Verification] Build, install on target, check journal Change-Id: I2c6dd5e40a08bda3722167c4e1f06b60bb53e7dc --- packaging/vasum.spec | 1 + wrapper/CMakeLists.txt | 3 +- wrapper/wrapper-compatibility.cpp | 216 +++++++++++++++++++++++++++++++++++--- wrapper/wrapper.cpp | 5 +- 4 files changed, 206 insertions(+), 19 deletions(-) diff --git a/packaging/vasum.spec b/packaging/vasum.spec index 82a859e..8f10a1c 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -26,6 +26,7 @@ BuildRequires: pkgconfig(sqlite3) Requires(post): libcap-tools Requires: iproute2 Requires: libjson >= 0.10 +Obsoletes: vasum-daemon < 1:0 %description This package provides a daemon used to manage zones - start, stop and switch diff --git a/wrapper/CMakeLists.txt b/wrapper/CMakeLists.txt index a75bfa9..a8aa173 100644 --- a/wrapper/CMakeLists.txt +++ b/wrapper/CMakeLists.txt @@ -42,6 +42,7 @@ SET(PC_FILE "${PROJECT_NAME}.pc") ## libraries, produce more optimized code, provide near-perfect API export ## and prevent symbol clashes ADD_DEFINITIONS(-fvisibility=hidden) +ADD_DEFINITIONS(-D__STDC_FORMAT_MACROS) ADD_LIBRARY(${PROJECT_NAME} SHARED ${wrapper_SRCS} ${common_SRCS}) SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES @@ -51,7 +52,7 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS system filesystem) -PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0 libcap-ng) +PKG_CHECK_MODULES(LIB_DEPS REQUIRED gio-2.0) INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${LIBS_FOLDER}) diff --git a/wrapper/wrapper-compatibility.cpp b/wrapper/wrapper-compatibility.cpp index 303fcfe..942c5f6 100644 --- a/wrapper/wrapper-compatibility.cpp +++ b/wrapper/wrapper-compatibility.cpp @@ -32,16 +32,18 @@ #include #include #include +#include +#include +#include +#include //PRIx64 #include #include #include #include #include -#include -#include -#include #include #include +#include #include "logger/logger.hpp" #include "logger/logger-scope.hpp" @@ -62,43 +64,227 @@ API pid_t get_domain_pid(const char * /*name*/, const char * /*target*/) { } // sock_close_socket -API int sock_close_socket(int /*fd*/) { +API int sock_close_socket(int fd) { LOGS(""); + struct sockaddr_un addr; + socklen_t addrlen = sizeof(addr); + + if (!getsockname(fd, (struct sockaddr *)&addr, &addrlen) && addr.sun_path[0]) { + unlink(addr.sun_path); + } + + close(fd); + return 0; } // sock_connect -API int sock_connect(const char * /*path*/) { +API int sock_connect(const char *path) { LOGS(""); - return -1; + size_t len; + int fd, idx = 0; + struct sockaddr_un addr; + + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + + addr.sun_family = AF_UNIX; + + /* Is it abstract address */ + if (path[0] == '\0') { + idx++; + } + LOGD("socket path=" << &path[idx]); + len = strlen(&path[idx]) + idx; + if (len >= sizeof(addr.sun_path)) { + close(fd); + errno = ENAMETOOLONG; + return -1; + } + + strncpy(&addr.sun_path[idx], &path[idx], strlen(&path[idx])); + if (connect + (fd, (struct sockaddr *)&addr, + offsetof(struct sockaddr_un, sun_path) + len)) { + close(fd); + return -1; + } + + return fd; } + // sock_create_socket -API int sock_create_socket(const char * /*path*/, int /*type*/, int /*flags*/) { +API int sock_create_socket(const char *path, int type, int flags) { LOGS(""); - return -1; + size_t len; + int fd, idx = 0; + struct sockaddr_un addr; + + if (!path) + return -1; + + if (flags & O_TRUNC) + unlink(path); + + fd = socket(PF_UNIX, type, 0); + if (fd < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + + addr.sun_family = AF_UNIX; + + /* Is it abstract address */ + if (path[0] == '\0') { + idx++; + } + LOGD("socket path=" << &path[idx]); + len = strlen(&path[idx]) + idx; + if (len >= sizeof(addr.sun_path)) { + close(fd); + errno = ENAMETOOLONG; + return -1; + } + + strncpy(&addr.sun_path[idx], &path[idx], strlen(&path[idx])); + + if (bind (fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len)) { + close(fd); + return -1; + } + + if (type == SOCK_STREAM && listen(fd, 100)) { + close(fd); + return -1; + } + + return fd; } + +// "Fowler–Noll–Vo hash function" implementation (taken from old API source) +#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL) +static uint64_t hash_fnv_64a(void *buf, size_t len, uint64_t hval) +{ + unsigned char *bp; + + for (bp = (unsigned char *)buf; bp < (unsigned char *)buf + len; bp++) { + hval ^= (uint64_t) * bp; + hval += (hval << 1) + (hval << 4) + (hval << 5) + + (hval << 7) + (hval << 8) + (hval << 40); + } + + return hval; +} + // sock_monitor_address -API int sock_monitor_address(char * /*buffer*/, int /*len*/, const char * /*lxcpath*/) { +API int sock_monitor_address(char *buffer, int len, const char *lxcpath) { LOGS(""); + int ret; + uint64_t hash; + char *sockname; + char path[PATH_MAX]; + + memset(buffer, 0, len); + sockname = &buffer[1]; + + ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath); + if (ret < 0) { + errno = ENAMETOOLONG; + return -1; + } + + hash = hash_fnv_64a(path, ret, FNV1A_64_INIT); + ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath); + if (ret < 0) { + errno = ENAMETOOLONG; + return -1; + } + return 0; } // sock_recv_fd (intern) -API int sock_recv_fd(int /*fd*/, int * /*recvfd*/, void * /*data*/, size_t /*size*/) { +API int sock_recv_fd(int fd, int *recvfd, void *data, size_t size) { LOGS(""); - return 0; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + char buf[1]; + int ret, *val; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + iov.iov_base = data ? data : buf; + iov.iov_len = data ? size : sizeof(buf); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + ret = recvmsg(fd, &msg, 0); + if (ret <= 0) + goto out; + + cmsg = CMSG_FIRSTHDR(&msg); + + *recvfd = -1; + + if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && + cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { + val = (int *)CMSG_DATA(cmsg); + *recvfd = *val; + } + out: + return ret; + } // sock_send_fd -API int sock_send_fd(int /*fd*/, int /*sendfd*/, void * /*data*/, size_t /*size*/) { +API int sock_send_fd(int fd, int sendfd, void *data, size_t size) { LOGS(""); - return 0; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + char cmsgbuf[CMSG_SPACE(sizeof(int))]; + char buf[1]; + int *val; + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + val = (int *)(CMSG_DATA(cmsg)); + *val = sendfd; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov.iov_base = data ? data : buf; + iov.iov_len = data ? size : sizeof(buf); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + return sendmsg(fd, &msg, MSG_NOSIGNAL); } // vasum_log API void vasum_log(int type, const char *tag, const char *fmt, ...) { va_list arg_ptr; - char buf[100]; + char buf[255]; + LOGS("type=" << type << " tag=" << tag); va_start(arg_ptr, fmt); vsnprintf(buf, sizeof(buf), fmt, arg_ptr); va_end(arg_ptr); - LOGS("type=" << type << " tag=" << tag << " msg=" << buf); + buf[sizeof(buf)-1]=0; + LOGD("msg=" << buf); } #define MAX_ERROR_MSG 0x1000 diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp index 4fc0c60..5623263 100644 --- a/wrapper/wrapper.cpp +++ b/wrapper/wrapper.cpp @@ -668,6 +668,7 @@ API int vsm_is_host_zone(vsm_zone_h zone) if (zone == NULL) return -VSM_ERROR_INVALID; + LOGI("zone->parent == zone is " << (zone->parent == zone ? 1 : 0)); return zone->parent == zone ? 1 : 0; } API vsm_zone_h vsm_join_zone(vsm_zone_h /*zone*/) @@ -683,9 +684,7 @@ API int vsm_canonicalize_path(const char *input_path, char **output_path) return len; } -// Note: incomaptible API, support newer -// API(v0.34) const char *vsm_error_string(struct vsm_context *ctx) -// API(v0.3.1) const char *vsm_error_string(vsm_error_e error) +// Note: support the newer API (incomaptible with older) API const char *vsm_error_string(vsm_error_e error) { LOGS(""); -- 2.7.4 From 8312cde30ab9a4aa689d34fce39f573cdeca8712 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Wed, 27 May 2015 15:30:33 +0200 Subject: [PATCH 06/16] Fix configuration script permissions [Feature] N/A [Cause] N/A [Solution] LXC templates have x permission [Verification] Build, run all tests Change-Id: I6a2486a588f8a28dfe84f187a4889f0f9500e2a6 --- server/configs/CMakeLists.txt | 9 ++++++--- tests/unit_tests/configs/CMakeLists.txt | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/server/configs/CMakeLists.txt b/server/configs/CMakeLists.txt index 0e7be41..278a9fc 100644 --- a/server/configs/CMakeLists.txt +++ b/server/configs/CMakeLists.txt @@ -19,8 +19,8 @@ MESSAGE(STATUS "Installing configs to " ${VSM_CONFIG_INSTALL_DIR}) -FILE(GLOB template_CONF templates/*.conf - templates/*.sh) +FILE(GLOB zone_templates_CONF templates/*.conf) +FILE(GLOB lxc_templates_CONF templates/*.sh) ## Generate #################################################################### CONFIGURE_FILE(systemd/vasum.service.in @@ -43,7 +43,10 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/dbus-1/system.d/org.tizen.vasum.host.con INSTALL(DIRECTORY DESTINATION ${VSM_CONFIG_INSTALL_DIR}/zones) #TODO temporary solution -INSTALL(PROGRAMS ${template_CONF} +INSTALL(FILES ${zone_templates_CONF} + DESTINATION ${VSM_CONFIG_INSTALL_DIR}/templates) + +INSTALL(PROGRAMS ${lxc_templates_CONF} DESTINATION ${VSM_CONFIG_INSTALL_DIR}/templates) INSTALL(FILES diff --git a/tests/unit_tests/configs/CMakeLists.txt b/tests/unit_tests/configs/CMakeLists.txt index 04aabda..a18914e 100644 --- a/tests/unit_tests/configs/CMakeLists.txt +++ b/tests/unit_tests/configs/CMakeLists.txt @@ -20,8 +20,8 @@ MESSAGE(STATUS "Installing configs for the Unit Tests to " ${VSM_TEST_CONFIG_INSTALL_DIR}) FILE(GLOB ut_zone_CONF *.conf) -FILE(GLOB ut_zone_templates_CONF templates/*.conf - templates/*.sh) +FILE(GLOB ut_zone_templates_CONF templates/*.conf) +FILE(GLOB ut_lxc_templates_CONF templates/*.sh) ## Generate #################################################################### CONFIGURE_FILE(test-daemon.conf.in @@ -44,6 +44,9 @@ INSTALL(FILES ${ut_zone_templates_CONF} ${ut_zone_templates_CONF_GEN} DESTINATION ${VSM_TEST_TEMPLATES_INSTALL_DIR}) +INSTALL(PROGRAMS ${ut_lxc_templates_CONF} + DESTINATION ${VSM_TEST_TEMPLATES_INSTALL_DIR}) + INSTALL(FILES dbus/ut-dbus.conf dbus/ut-dbus-system.conf DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/dbus) -- 2.7.4 From bdad02ae0c2da1eeeabbd3f96185a09aa964d8ce Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Wed, 27 May 2015 18:48:47 +0200 Subject: [PATCH 07/16] Small documentation for github [Feature] N/A [Cause] N/A [Solution] N/A [Verification] N/A Change-Id: Ia7beba020ae92619e3639ee70af65794d2b662a1 --- README | 18 ------------------ README.md | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index d194922..0000000 --- a/README +++ /dev/null @@ -1,18 +0,0 @@ -# Documentation - -Generate documentation by executing command generate_documentation.sh -from doc directory. Documentation will be generated in doc/html directory. -There is also GUI tool named doxywizard. - - cd ./doc - ./generate_documentation.sh - - -# Code formatting - -We use astyle for code formatting. -Get the latest version from http://sourceforge.net/projects/astyle/files/astyle/ -(at least v2.04). You can find the options file in the root of the project. -For example to format all .cpp and .hpp files run in the project directory: - - astyle --options=./astylerc --recursive ./*.cpp ./*.hpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ccd43c --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Vasum +[Vasum](https://wiki.tizen.org/wiki/Security:Vasum) is a Linux daemon and a set of utilities used for managing para-virtualization. It uses Linux Containers to create separate, graphical environments called *zones*. One can concurrently run several zones on one physical device. Vasum exports a rich C/Dbus API that the application frameworks can use to interact with zones. + +For now Vasum uses [LXC](https://linuxcontainers.org/lxc/introduction/) for Linux Containers management. The project is mostly written in modern C++, is [well tested](https://wiki.tizen.org/wiki/Weekly_test_results_for_Tizen_3.X_security_framework). + +Vasum's development takes place on [review.tizen.org/gerrit/](http://review.tizen.org/gerrit/) (registration on [tizen.org](http://tizen.org) is required). + +## Installation and usage +The installation process and simple verification is described [here](https://wiki.tizen.org/wiki/Security:Vasum:Usage). + +## Client interface +Vasum daemon can be accessed via C API or Dbus. You can find the API documentation [here](https://wiki.tizen.org/wiki/Security:Vasum:API). Be aware that the API will most likely change in the near future. + +## Documentation +More comprehensive documentation is kept [here](https://wiki.tizen.org/wiki/Security:Vasum). You can generate the code documentation by executing *generate_documentation.sh* script from *doc* directory. Documentation will be generated in doc/html directory. + + cd ./doc + ./generate_documentation.sh + + +## Code formatting +We use [astyle](http://astyle.sourceforge.net/) for code formatting (Use the latest version) +You can find the options file in the root of the project. + +For example to format all .cpp and .hpp files run in the project directory: + + astyle --options=./astylerc --recursive ./*.cpp ./*.hpp \ No newline at end of file -- 2.7.4 From 7c6e79b69e1a39c1c033ffb4891ec3ca21e4f309 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Tue, 2 Jun 2015 14:16:43 +0200 Subject: [PATCH 08/16] Removed Glib connected functions from API [Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, run all tests Change-Id: I3fe5e789535fcb53ee5d223172cb63bd44fb962c --- cli/command-line-interface.cpp | 6 ------ client/vasum-client-impl.cpp | 12 ------------ client/vasum-client-impl.hpp | 9 --------- client/vasum-client.cpp | 11 ----------- client/vasum-client.h | 25 ------------------------- wrapper/wrapper.cpp | 5 ----- 6 files changed, 68 deletions(-) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index 2ae3778..2393ce1 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -58,11 +58,6 @@ void one_shot(const function& fun) VsmStatus status; VsmClient client; - status = vsm_start_glib_loop(); - if (VSMCLIENT_SUCCESS != status) { - throw runtime_error("Can't start glib loop"); - } - client = vsm_client_create(); if (NULL == client) { msg = "Can't create client"; @@ -83,7 +78,6 @@ void one_shot(const function& fun) finish: vsm_client_free(client); - vsm_stop_glib_loop(); if (! msg.empty()) { throw runtime_error(msg); } diff --git a/client/vasum-client-impl.cpp b/client/vasum-client-impl.cpp index 38e4c5a..f87e9a0 100644 --- a/client/vasum-client-impl.cpp +++ b/client/vasum-client-impl.cpp @@ -127,18 +127,6 @@ bool readFirstLineOfFile(const string& path, string& ret) } //namespace -VsmStatus Client::vsm_start_glib_loop() noexcept -{ - // TPDP: Remove vsm_start_glib_loop from API - return VSMCLIENT_SUCCESS; -} - -VsmStatus Client::vsm_stop_glib_loop() noexcept -{ - // TPDP: Remove vsm_stop_glib_loop from API - return VSMCLIENT_SUCCESS; -} - Client::Status::Status() : mVsmStatus(VSMCLIENT_SUCCESS), mMsg() { diff --git a/client/vasum-client-impl.hpp b/client/vasum-client-impl.hpp index 86f7a5e..5a1d2fd 100644 --- a/client/vasum-client-impl.hpp +++ b/client/vasum-client-impl.hpp @@ -336,15 +336,6 @@ public: */ VsmStatus vsm_del_notification_callback(VsmSubscriptionId subscriptionId) noexcept; - /** - * @see ::vsm_start_glib_loop - */ - static VsmStatus vsm_start_glib_loop() noexcept; - - /** - * @see ::vsm_stop_glib_loop - */ - static VsmStatus vsm_stop_glib_loop() noexcept; private: typedef vasum::client::HostIPCConnection HostConnection; struct Status { diff --git a/client/vasum-client.cpp b/client/vasum-client.cpp index b1028e2..1d5664c 100644 --- a/client/vasum-client.cpp +++ b/client/vasum-client.cpp @@ -45,17 +45,6 @@ Client& getClient(VsmClient client) } // namespace -/* external */ -API VsmStatus vsm_start_glib_loop() -{ - return Client::vsm_start_glib_loop(); -} - -API VsmStatus vsm_stop_glib_loop() -{ - return Client::vsm_stop_glib_loop(); -} - API VsmClient vsm_client_create() { Client* clientPtr = new(nothrow) Client(); diff --git a/client/vasum-client.h b/client/vasum-client.h index 6c68fe2..7a98fa7 100644 --- a/client/vasum-client.h +++ b/client/vasum-client.h @@ -34,12 +34,6 @@ int main(int argc, char** argv) VsmArrayString values = NULL; int ret = 0; - status = vsm_start_glib_loop(); // start glib loop (if not started any yet) - if (VSMCLIENT_SUCCESS != status) { - // error! - return 1; - } - client = vsm_client_create(); // create client handle if (NULL == client) { // error! @@ -69,7 +63,6 @@ int main(int argc, char** argv) finish: vsm_array_string_free(values); // free memory vsm_client_free(client); // destroy client handle - vsm_stop_glib_loop(); // stop the glib loop (use only with vsm_start_glib_loop) return ret; } @endcode @@ -188,24 +181,6 @@ typedef enum { } VsmFileType; #ifndef __VASUM_WRAPPER_SOURCE__ -/** - * Start glib loop. - * - * Do not call this function if an application creates a glib loop itself. - * Otherwise, call it before any other function from this library. - * - * @return status of this function call - */ -VsmStatus vsm_start_glib_loop(); - -/** - * Stop glib loop. - * - * Call only if vsm_start_glib_loop() was called. - * - * @return status of this function call - */ -VsmStatus vsm_stop_glib_loop(); /** * Create a new vasum-server's client. diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp index 5623263..8b890cf 100644 --- a/wrapper/wrapper.cpp +++ b/wrapper/wrapper.cpp @@ -54,7 +54,6 @@ struct WrappedContext static struct { int done; - int glib_stop; } wrap; @@ -90,8 +89,6 @@ void wrapper_load(void) void wrapper_unload(void) { - if (wrap.glib_stop) Client::vsm_stop_glib_loop(); - wrap.glib_stop = 0; LOGI("wrapper_unload"); } @@ -153,8 +150,6 @@ static int wrap_error(VsmStatus st, const Client *c) static void init_context_wrap(WrappedContext *w) { - Client::vsm_start_glib_loop(); - wrap.glib_stop = 1; w->client = new Client(); VsmStatus st = w->client->createSystem(); wrap_error(st, w->client); -- 2.7.4 From 1c1c682dacd05c0824d4fcf7d18b95eeff20cfc4 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Mon, 1 Jun 2015 16:11:54 +0200 Subject: [PATCH 09/16] File descriptor passing via IPC [Feature] FD passing via Unix socket [Cause] N/A [Solution] N/A [Verification] Build, run all tests Change-Id: I1683a7e99a104d5dbdd5c0c56913753c9bdd3cf2 --- libs/config/fdstore.cpp | 178 +++++++++++++++++++++++++++++++---- libs/config/fdstore.hpp | 12 ++- libs/config/fields.hpp | 2 + libs/config/from-fdstore-visitor.hpp | 6 ++ libs/config/to-fdstore-visitor.hpp | 6 ++ libs/config/types.hpp | 44 +++++++++ libs/ipc/internals/socket.cpp | 10 +- libs/ipc/internals/socket.hpp | 4 +- tests/unit_tests/ipc/ut-ipc.cpp | 60 +++++++++++- 9 files changed, 291 insertions(+), 31 deletions(-) create mode 100644 libs/config/types.hpp diff --git a/libs/config/fdstore.cpp b/libs/config/fdstore.cpp index c0b7d08..cc0b903 100644 --- a/libs/config/fdstore.cpp +++ b/libs/config/fdstore.cpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace config { @@ -102,24 +103,28 @@ FDStore::~FDStore() void FDStore::write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS) { - std::chrono::high_resolution_clock::time_point deadline = std::chrono::high_resolution_clock::now() + - std::chrono::milliseconds(timeoutMS); + std::chrono::high_resolution_clock::time_point deadline = + std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); size_t nTotal = 0; for (;;) { - int n = ::write(mFD, - reinterpret_cast(bufferPtr) + nTotal, - size - nTotal); - if (n >= 0) { + ssize_t n = ::write(mFD, + reinterpret_cast(bufferPtr) + nTotal, + size - nTotal); + if (n < 0) { + // Handle errors + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors + } else { + throw ConfigException("Error during writing: " + getSystemErrorMessage()); + } + } else { nTotal += n; if (nTotal == size) { - // All data is written, break loop + // All data is read, break loop break; } - } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { - // Neglected errors - } else { - throw ConfigException("Error during writing: " + getSystemErrorMessage()); } waitForEvent(mFD, POLLOUT, deadline); @@ -128,15 +133,23 @@ void FDStore::write(const void* bufferPtr, const size_t size, const unsigned int void FDStore::read(void* bufferPtr, const size_t size, const unsigned int timeoutMS) { - std::chrono::high_resolution_clock::time_point deadline = std::chrono::high_resolution_clock::now() + - std::chrono::milliseconds(timeoutMS); + std::chrono::high_resolution_clock::time_point deadline = + std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); size_t nTotal = 0; for (;;) { - int n = ::read(mFD, - reinterpret_cast(bufferPtr) + nTotal, - size - nTotal); - if (n >= 0) { + ssize_t n = ::read(mFD, + reinterpret_cast(bufferPtr) + nTotal, + size - nTotal); + if (n < 0) { + // Handle errors + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors + } else { + throw ConfigException("Error during reading: " + getSystemErrorMessage()); + } + } else { nTotal += n; if (nTotal == size) { // All data is read, break loop @@ -145,13 +158,138 @@ void FDStore::read(void* bufferPtr, const size_t size, const unsigned int timeou if (n == 0) { throw ConfigException("Peer disconnected"); } - } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { - // Neglected errors + } + + waitForEvent(mFD, POLLIN, deadline); + } +} + + +void FDStore::sendFD(int fd, const unsigned int timeoutMS) +{ + std::chrono::high_resolution_clock::time_point deadline = + std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); + + // Space for the file descriptor + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(int))]; + } controlUnion; + + // Ensure at least 1 byte is transmited via the socket + struct iovec iov; + char buf = '!'; + iov.iov_base = &buf; + iov.iov_len = sizeof(char); + + // Fill the message to send: + // The socket has to be connected, so we don't need to specify the name + struct msghdr msgh; + ::memset(&msgh, 0, sizeof(msgh)); + + // Only iovec to transmit one element + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + + // Ancillary data buffer + msgh.msg_control = controlUnion.control; + msgh.msg_controllen = sizeof(controlUnion.control); + + // Describe the data that we want to send + struct cmsghdr *cmhp; + cmhp = CMSG_FIRSTHDR(&msgh); + cmhp->cmsg_len = CMSG_LEN(sizeof(int)); + cmhp->cmsg_level = SOL_SOCKET; + cmhp->cmsg_type = SCM_RIGHTS; + *(reinterpret_cast(CMSG_DATA(cmhp))) = fd; + + // Send + for(;;) { + ssize_t ret = ::sendmsg(mFD, &msgh, MSG_NOSIGNAL); + if (ret < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors, retry + } else { + throw ConfigException("Error during sendmsg: " + getSystemErrorMessage()); + } + } else if (ret == 0) { + // Retry the sending } else { - throw ConfigException("Error during reading: " + getSystemErrorMessage()); + // We send only 1 byte of data. No need to repeat + break; + } + + waitForEvent(mFD, POLLOUT, deadline); + } +} + + +int FDStore::receiveFD(const unsigned int timeoutMS) +{ + std::chrono::high_resolution_clock::time_point deadline = + std::chrono::high_resolution_clock::now() + + std::chrono::milliseconds(timeoutMS); + + // Space for the file descriptor + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(int))]; + } controlUnion; + + // Describe the data that we want to recive + controlUnion.cmh.cmsg_len = CMSG_LEN(sizeof(int)); + controlUnion.cmh.cmsg_level = SOL_SOCKET; + controlUnion.cmh.cmsg_type = SCM_RIGHTS; + + // Setup the input buffer + // Ensure at least 1 byte is transmited via the socket + char buf; + struct iovec iov; + iov.iov_base = &buf; + iov.iov_len = sizeof(char); + + // Set the ancillary data buffer + // The socket has to be connected, so we don't need to specify the name + struct msghdr msgh; + ::memset(&msgh, 0, sizeof(msgh)); + + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + + msgh.msg_control = controlUnion.control; + msgh.msg_controllen = sizeof(controlUnion.control); + + // Receive + for(;;) { + ssize_t ret = ::recvmsg(mFD, &msgh, MSG_WAITALL); + if (ret < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { + // Neglected errors, retry + } else { + throw ConfigException("Error during recvmsg: " + getSystemErrorMessage()); + } + } else if (ret == 0) { + throw ConfigException("Peer disconnected"); + } else { + // We receive only 1 byte of data. No need to repeat + break; } waitForEvent(mFD, POLLIN, deadline); } + + struct cmsghdr *cmhp; + cmhp = CMSG_FIRSTHDR(&msgh); + if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(int))) { + throw ConfigException("Bad cmsg length"); + } else if (cmhp->cmsg_level != SOL_SOCKET) { + throw ConfigException("cmsg_level != SOL_SOCKET"); + } else if (cmhp->cmsg_type != SCM_RIGHTS) { + throw ConfigException("cmsg_type != SCM_RIGHTS"); + } + + return *(reinterpret_cast(CMSG_DATA(cmhp))); } + } // namespace config diff --git a/libs/config/fdstore.hpp b/libs/config/fdstore.hpp index d76fc5f..d6e30aa 100644 --- a/libs/config/fdstore.hpp +++ b/libs/config/fdstore.hpp @@ -27,6 +27,10 @@ #include +namespace { +const unsigned int maxTimeout = 5000; +} // namespace + namespace config { class FDStore { @@ -50,7 +54,7 @@ public: * @param size size of the buffer * @param timeoutMS timeout in milliseconds */ - void write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS = 5000); + void write(const void* bufferPtr, const size_t size, const unsigned int timeoutMS = maxTimeout); /** * Reads a value of the given type. @@ -59,7 +63,11 @@ public: * @param size size of the buffer * @param timeoutMS timeout in milliseconds */ - void read(void* bufferPtr, const size_t size, const unsigned int timeoutMS = 5000); + void read(void* bufferPtr, const size_t size, const unsigned int timeoutMS = maxTimeout); + + void sendFD(int fd, const unsigned int timeoutMS = maxTimeout); + + int receiveFD(const unsigned int timeoutMS = maxTimeout); private: int mFD; diff --git a/libs/config/fields.hpp b/libs/config/fields.hpp index cba5a67..8169cb4 100644 --- a/libs/config/fields.hpp +++ b/libs/config/fields.hpp @@ -28,6 +28,8 @@ #include #include +#include "config/types.hpp" + #if BOOST_PP_VARIADICS != 1 #error variadic macros not supported #endif diff --git a/libs/config/from-fdstore-visitor.hpp b/libs/config/from-fdstore-visitor.hpp index 9b9df42..3863f7f 100644 --- a/libs/config/from-fdstore-visitor.hpp +++ b/libs/config/from-fdstore-visitor.hpp @@ -27,6 +27,7 @@ #include "config/is-visitable.hpp" #include "config/fdstore.hpp" +#include "config/types.hpp" #include @@ -60,6 +61,11 @@ private: mStore.read(&value.front(), size); } + void readInternal(config::FileDescriptor& fd) + { + fd = mStore.receiveFD(); + } + template::value, int>::type = 0> void readInternal(T& value) { diff --git a/libs/config/to-fdstore-visitor.hpp b/libs/config/to-fdstore-visitor.hpp index 50756c1..1eedddb 100644 --- a/libs/config/to-fdstore-visitor.hpp +++ b/libs/config/to-fdstore-visitor.hpp @@ -27,6 +27,7 @@ #include "config/is-visitable.hpp" #include "config/fdstore.hpp" +#include "config/types.hpp" #include @@ -59,6 +60,11 @@ private: mStore.write(value.c_str(), value.size()); } + void writeInternal(const config::FileDescriptor& fd) + { + mStore.sendFD(fd.value); + } + template::value, int>::type = 0> void writeInternal(const T& value) { diff --git a/libs/config/types.hpp b/libs/config/types.hpp new file mode 100644 index 0000000..3355f8f --- /dev/null +++ b/libs/config/types.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Jan Olszak + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +/** + * @file + * @author Jan Olszak (j.olszak@samsung.com) + * @brief Types declarations + */ + +#ifndef COMMON_CONFIG_TYPES_HPP +#define COMMON_CONFIG_TYPES_HPP + +namespace config { + +/** + * Whenever possible, this type will be serialized using Linux file descriptor passing. + */ +struct FileDescriptor { + int value; + FileDescriptor(int fd = -1): value(fd) {} + FileDescriptor& operator=(const int fd) { + value = fd; + return *this; + } +}; + +}// config + +#endif //COMMON_CONFIG_TYPES_HPP \ No newline at end of file diff --git a/libs/ipc/internals/socket.cpp b/libs/ipc/internals/socket.cpp index 0654a4e..690bd43 100644 --- a/libs/ipc/internals/socket.cpp +++ b/libs/ipc/internals/socket.cpp @@ -56,7 +56,7 @@ void setFdOptions(int fd) } } -} +} // namespace Socket::Socket(int socketFD) : mFD(socketFD) @@ -112,7 +112,7 @@ void Socket::read(void* bufferPtr, const size_t size) const utils::read(mFD, bufferPtr, size); } -int Socket::getSystemdSocket(const std::string& path) +int Socket::getSystemdSocketInternal(const std::string& path) { int n = ::sd_listen_fds(-1 /*Block further calls to sd_listen_fds*/); if (n < 0) { @@ -132,7 +132,7 @@ int Socket::getSystemdSocket(const std::string& path) return -1; } -int Socket::createZoneSocket(const std::string& path) +int Socket::createSocketInternal(const std::string& path) { // Isn't the path too long? if (path.size() >= sizeof(sockaddr_un::sun_path)) { @@ -178,8 +178,8 @@ int Socket::createZoneSocket(const std::string& path) Socket Socket::createSocket(const std::string& path) { // Initialize a socket - int fd = getSystemdSocket(path); - fd = fd != -1 ? fd : createZoneSocket(path); + int fd = getSystemdSocketInternal(path); + fd = fd != -1 ? fd : createSocketInternal(path); return Socket(fd); } diff --git a/libs/ipc/internals/socket.hpp b/libs/ipc/internals/socket.hpp index 65f574d..c8f0a2d 100644 --- a/libs/ipc/internals/socket.hpp +++ b/libs/ipc/internals/socket.hpp @@ -108,8 +108,8 @@ private: int mFD; mutable std::recursive_mutex mCommunicationMutex; - static int createZoneSocket(const std::string& path); - static int getSystemdSocket(const std::string& path); + static int createSocketInternal(const std::string& path); + static int getSystemdSocketInternal(const std::string& path); }; } // namespace ipc diff --git a/tests/unit_tests/ipc/ut-ipc.cpp b/tests/unit_tests/ipc/ut-ipc.cpp index 958f1f2..ab920fe 100644 --- a/tests/unit_tests/ipc/ut-ipc.cpp +++ b/tests/unit_tests/ipc/ut-ipc.cpp @@ -44,17 +44,24 @@ #include "config/fields.hpp" #include "logger/logger.hpp" +#include +#include #include #include #include #include #include #include +#include +#include +#include + using namespace ipc; using namespace epoll; using namespace utils; using namespace std::placeholders; +namespace fs = boost::filesystem; // Timeout for sending one message const int TIMEOUT = 1000 /*ms*/; @@ -67,6 +74,7 @@ const int LONG_OPERATION_TIME = 1000 + TIMEOUT; const std::string TEST_DIR = "/tmp/ut-ipc"; const std::string SOCKET_PATH = TEST_DIR + "/test.socket"; +const std::string TEST_FILE = TEST_DIR + "/file.txt"; struct FixtureBase { ScopedDir mTestPathGuard; @@ -80,14 +88,18 @@ struct FixtureBase { struct ThreadedFixture : FixtureBase { ThreadDispatcher dispatcher; - EventPoll& getPoll() { return dispatcher.getPoll(); } + EventPoll& getPoll() { + return dispatcher.getPoll(); + } }; struct GlibFixture : FixtureBase { ScopedGlibLoop glibLoop; GlibDispatcher dispatcher; - EventPoll& getPoll() { return dispatcher.getPoll(); } + EventPoll& getPoll() { + return dispatcher.getPoll(); + } }; struct SendData { @@ -110,6 +122,16 @@ struct RecvData { ) }; +struct FDData { + config::FileDescriptor fd; + FDData(int fd = -1): fd(fd) {} + + CONFIG_REGISTER + ( + fd + ) +}; + struct LongSendData { LongSendData(int i, int waitTime): mSendData(i), mWaitTime(waitTime), intVal(i) {} @@ -710,6 +732,40 @@ MULTI_FIXTURE_TEST_CASE(MixOperations, F, ThreadedFixture, GlibFixture) BOOST_CHECK(l.wait(TIMEOUT)); } +MULTI_FIXTURE_TEST_CASE(FDSendReceive, F, ThreadedFixture, GlibFixture) +{ + const char DATA[] = "Content of the file"; + { + // Fill the file + fs::remove(TEST_FILE); + std::ofstream file(TEST_FILE); + file << DATA; + file.close(); + } + + auto methodHandler = [&](const PeerID, std::shared_ptr&, MethodResult::Pointer methodResult) { + int fd = ::open(TEST_FILE.c_str(), O_RDONLY); + auto returnData = std::make_shared(fd); + methodResult->set(returnData); + }; + + Service s(F::getPoll(), SOCKET_PATH); + s.setMethodHandler(1, methodHandler); + + Client c(F::getPoll(), SOCKET_PATH); + connect(s, c); + + std::shared_ptr fdData; + std::shared_ptr sentData(new EmptyData()); + fdData = c.callSync(1, sentData, TIMEOUT); + + // Use the file descriptor + char buffer[sizeof(DATA)]; + BOOST_REQUIRE(::read(fdData->fd.value, buffer, sizeof(buffer))>0); + BOOST_REQUIRE(strncmp(DATA, buffer, strlen(DATA))==0); + ::close(fdData->fd.value); +} + // MULTI_FIXTURE_TEST_CASE(ConnectionLimit, F, ThreadedFixture, GlibFixture) // { // unsigned oldLimit = ipc::getMaxFDNumber(); -- 2.7.4 From 314f5334d5fa3cf8d7dfe6207fc5e7aa10acccdc Mon Sep 17 00:00:00 2001 From: Dariusz Michaluk Date: Fri, 29 May 2015 14:44:12 +0200 Subject: [PATCH 10/16] Various changes relating to build on Fedora Linux. [Bug/Feature] Support different versions of json-c. Unify installation paths. Fix compiler warnings. Support different platform type in RPM spec file. Small changes in deamon and service configuration. [Cause] N/A [Solution] N/A [Verification] Build, run tests, run server on Tizen and Fedora. Select platform type with --define 'platform_type FEDORA or TIZEN' Change-Id: I6ef85e9605d2069701ee68dd8e8946f0346387f5 --- CMakeLists.txt | 18 ++++---- client/CMakeLists.txt | 2 +- libs/config/CMakeLists.txt | 6 ++- libs/config/from-json-visitor.hpp | 5 +++ libs/config/from-kvjson-visitor.hpp | 5 +++ libs/config/to-json-visitor.hpp | 9 ++++ libs/logger/ccolor.cpp | 2 +- packaging/vasum.spec | 48 ++++++++++++++++++---- server/CMakeLists.txt | 2 +- server/configs/daemon.conf.in | 6 +-- server/configs/systemd/vasum.service.in | 1 - server/configs/templates/tizen-common-wayland.sh | 2 + .../network_tests/network_common.py | 2 +- tests/unit_tests/CMakeLists.txt | 2 +- tests/unit_tests/configs/CMakeLists.txt | 5 ++- ...t-test.service => vasum-socket-test.service.in} | 2 +- wrapper/CMakeLists.txt | 2 +- 17 files changed, 88 insertions(+), 31 deletions(-) rename tests/unit_tests/configs/systemd/{vasum-socket-test.service => vasum-socket-test.service.in} (72%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d42f496..e865117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,11 @@ ADD_DEFINITIONS(-DPROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}") ADD_DEFINITIONS(-DUSE_EXEC) ADD_DEFINITIONS(-D__STDC_LIMIT_MACROS) +PKG_SEARCH_MODULE(JSON_C REQUIRED json json-c) +IF(JSON_C_VERSION GREATER 0.11) + ADD_DEFINITIONS(-DJSON_C_VERSION_NEW) +ENDIF(JSON_C_VERSION GREATER 0.11) + IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # Warn about documentation problems ADD_DEFINITIONS("-Wdocumentation") @@ -151,32 +156,29 @@ SET(TESTS_FOLDER ${PROJECT_SOURCE_DIR}/tests) SET(CLI_FOLDER ${PROJECT_SOURCE_DIR}/cli) SET(WRAPPER_FOLDER ${PROJECT_SOURCE_DIR}/wrapper) + IF(NOT DEFINED SYSCONF_INSTALL_DIR) SET(SYSCONF_INSTALL_DIR "/etc") ENDIF(NOT DEFINED SYSCONF_INSTALL_DIR) IF(NOT DEFINED LIB_INSTALL_DIR) - SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_FULL_LIBDIR}") + SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib") ENDIF(NOT DEFINED LIB_INSTALL_DIR) IF(NOT DEFINED INCLUDE_INSTALL_DIR) - SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}") + SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") ENDIF(NOT DEFINED INCLUDE_INSTALL_DIR) IF(NOT DEFINED SCRIPT_INSTALL_DIR) - SET(SCRIPT_INSTALL_DIR "${CMAKE_INSTALL_FULL_SBINDIR}") + SET(SCRIPT_INSTALL_DIR "${CMAKE_INSTALL_SBINDIR}") ENDIF(NOT DEFINED SCRIPT_INSTALL_DIR) -IF(NOT DEFINED SHARE_INSTALL_PREFIX) - SET(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_FULL_DATAROOTDIR}") -ENDIF(NOT DEFINED SHARE_INSTALL_PREFIX) - IF(NOT DEFINED SYSTEMD_UNIT_DIR) SET(SYSTEMD_UNIT_DIR "${LIB_INSTALL_DIR}/systemd/system") ENDIF(NOT DEFINED SYSTEMD_UNIT_DIR) IF(NOT DEFINED DATA_DIR) - SET(DATA_DIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}") + SET(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") ENDIF(NOT DEFINED DATA_DIR) SET(VSM_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/vasum) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c9f4c17..3fa44fd 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -62,7 +62,7 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(TARGETS ${PROJECT_NAME} - DESTINATION ${CMAKE_INSTALL_LIBDIR} + DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) INSTALL(FILES vasum-client.h diff --git a/libs/config/CMakeLists.txt b/libs/config/CMakeLists.txt index 87c2af1..fcc5e23 100644 --- a/libs/config/CMakeLists.txt +++ b/libs/config/CMakeLists.txt @@ -38,9 +38,11 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES ## Link libraries ############################################################## PKG_CHECK_MODULES(CONFIG_DEPS REQUIRED sqlite3 glib-2.0) +PKG_SEARCH_MODULE(JSON_C json json-c) + INCLUDE_DIRECTORIES(${LIBS_FOLDER}) -INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${CONFIG_DEPS_LIBRARIES}) +INCLUDE_DIRECTORIES(SYSTEM ${CONFIG_DEPS_INCLUDE_DIRS} ${JSON_C_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${CONFIG_DEPS_LIBRARIES} ${JSON_C_LIBRARIES}) ## Generate the pc file ######################################################## CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY) diff --git a/libs/config/from-json-visitor.hpp b/libs/config/from-json-visitor.hpp index 2934adf..8831ef6 100644 --- a/libs/config/from-json-visitor.hpp +++ b/libs/config/from-json-visitor.hpp @@ -28,7 +28,12 @@ #include "config/is-visitable.hpp" #include "config/exception.hpp" +#ifdef JSON_C_VERSION_NEW +#include +#else //JSON_C_VERSION_NEW #include +#endif //JSON_C_VERSION_NEW + #include #include diff --git a/libs/config/from-kvjson-visitor.hpp b/libs/config/from-kvjson-visitor.hpp index 35e1bf7..f9c11ef 100644 --- a/libs/config/from-kvjson-visitor.hpp +++ b/libs/config/from-kvjson-visitor.hpp @@ -28,7 +28,12 @@ #include "config/from-kvstore-visitor.hpp" #include "config/is-union.hpp" + +#ifdef JSON_C_VERSION_NEW +#include +#else //JSON_C_VERSION_NEW #include +#endif //JSON_C_VERSION_NEW namespace config { diff --git a/libs/config/to-json-visitor.hpp b/libs/config/to-json-visitor.hpp index f524900..1b68438 100644 --- a/libs/config/to-json-visitor.hpp +++ b/libs/config/to-json-visitor.hpp @@ -28,7 +28,12 @@ #include "config/is-visitable.hpp" #include "config/exception.hpp" +#ifdef JSON_C_VERSION_NEW +#include +#else //JSON_C_VERSION_NEW #include +#endif //JSON_C_VERSION_NEW + #include #include @@ -108,7 +113,11 @@ private: static json_object* toJsonObject(double value) { +#ifdef JSON_C_VERSION_NEW + return json_object_new_double_s(value, std::to_string(value).c_str()); +#else //JSON_C_VERSION_NEW return json_object_new_double(value); +#endif //JSON_C_VERSION_NEW } static json_object* toJsonObject(const std::string& value) diff --git a/libs/logger/ccolor.cpp b/libs/logger/ccolor.cpp index 7424044..9cc652d 100644 --- a/libs/logger/ccolor.cpp +++ b/libs/logger/ccolor.cpp @@ -34,7 +34,7 @@ std::string getConsoleEscapeSequence(Attributes attr, Color color) char command[10]; // Command is the control command to the terminal - snprintf(command, sizeof(command), "%c[%d;%dm", 0x1B, attr, color); + snprintf(command, sizeof(command), "%c[%u;%um", 0x1B, (unsigned int)attr, (unsigned int)color); return std::string(command); } diff --git a/packaging/vasum.spec b/packaging/vasum.spec index 8f10a1c..bd7346c 100644 --- a/packaging/vasum.spec +++ b/packaging/vasum.spec @@ -8,6 +8,8 @@ %define disk_group disk # The group that has write access to /dev/tty* devices. %define tty_group tty +# Default platform is Tizen, setup Fedora with --define 'platform_type FEDORA' +%{!?platform_type:%define platform_type "TIZEN"} Name: vasum Epoch: 1 @@ -19,13 +21,16 @@ Group: Security/Other Summary: Daemon for managing zones BuildRequires: cmake BuildRequires: boost-devel -BuildRequires: libjson-devel >= 0.10 -BuildRequires: lxc-devel BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(sqlite3) -Requires(post): libcap-tools +BuildRequires: lxc-devel +Requires: lxc +%if %{platform_type} == "TIZEN" Requires: iproute2 -Requires: libjson >= 0.10 +Requires(post): libcap-tools +%else +Requires: iproute +Requires(post): libcap +%endif Obsoletes: vasum-daemon < 1:0 %description @@ -34,11 +39,12 @@ between them. A process from inside a zone can request a switch of context (display, input devices) to the other zone. %files +%if %{platform_type} == "TIZEN" %manifest packaging/vasum.manifest +%endif %defattr(644,root,root,755) %attr(755,root,root) %{_bindir}/vasum-server %dir /etc/vasum -%dir /etc/vasum/zones %dir /etc/vasum/templates %config /etc/vasum/daemon.conf %attr(755,root,root) /etc/vasum/templates/*.sh @@ -47,7 +53,7 @@ between them. A process from inside a zone can request a switch of context %{_unitdir}/vasum.socket %{_unitdir}/multi-user.target.wants/vasum.service %config /etc/dbus-1/system.d/org.tizen.vasum.host.conf -%dir %{_datadir}/.zones +%dir %{_datadir}/zones %prep %setup -q @@ -77,7 +83,7 @@ make -k %{?jobs:-j%jobs} %make_install mkdir -p %{buildroot}/%{_unitdir}/multi-user.target.wants ln -s ../vasum.service %{buildroot}/%{_unitdir}/multi-user.target.wants/vasum.service -mkdir -p %{buildroot}/%{_datadir}/.zones +mkdir -p %{buildroot}/%{_datadir}/zones %clean rm -rf %{buildroot} @@ -127,7 +133,9 @@ Library interface to the vasum daemon %postun -n vasum-client -p /sbin/ldconfig %files client +%if %{platform_type} == "TIZEN" %manifest packaging/libvasum-client.manifest +%endif %defattr(644,root,root,755) %attr(755,root,root) %{_libdir}/libvasum-client.so.%{version} %{_libdir}/libvasum-client.so.0 @@ -146,7 +154,9 @@ Requires: vasum-client = %{epoch}:%{version}-%{release} Development package including the header files for the client library %files devel +%if %{platform_type} == "TIZEN" %manifest packaging/vasum.manifest +%endif %defattr(644,root,root,755) %{_libdir}/libvasum-client.so %{_libdir}/libvasum.so @@ -164,7 +174,9 @@ Group: Security/Other Zones support installed inside every zone. %files zone-support +%if %{platform_type} == "TIZEN" %manifest packaging/vasum-zone-support.manifest +%endif %defattr(644,root,root,755) %config /etc/dbus-1/system.d/org.tizen.vasum.zone.conf @@ -179,7 +191,9 @@ Requires: vasum-zone-support = %{epoch}:%{version}-%{release} Daemon running inside every zone. %files zone-daemon +%if %{platform_type} == "TIZEN" %manifest packaging/vasum-zone-daemon.manifest +%endif %defattr(644,root,root,755) %attr(755,root,root) %{_bindir}/vasum-zone-daemon %config /etc/dbus-1/system.d/org.tizen.vasum.zone.daemon.conf @@ -217,7 +231,9 @@ Group: Development/Libraries Requires: vasum = %{epoch}:%{version}-%{release} Requires: vasum-client = %{epoch}:%{version}-%{release} Requires: python +%if %{platform_type} == "TIZEN" Requires: python-xml +%endif Requires: boost-test %description tests @@ -236,7 +252,9 @@ systemctl disable vasum-socket-test.socket systemctl daemon-reload %files tests +%if %{platform_type} == "TIZEN" %manifest packaging/vasum-server-tests.manifest +%endif %defattr(644,root,root,755) %attr(755,root,root) %{_bindir}/vasum-server-unit-tests %attr(755,root,root) %{_bindir}/vasum-socket-test @@ -327,6 +345,14 @@ The package provides libSimpleDbus development tools and libs. %package -n libConfig Summary: Config library Group: Security/Other +BuildRequires: pkgconfig(sqlite3) +%if %{platform_type} == "TIZEN" +BuildRequires: libjson-devel >= 0.10 +Requires: libjson >= 0.10 +%else +BuildRequires: json-c-devel +Requires: json-c +%endif Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -348,7 +374,11 @@ Group: Development/Libraries Requires: libConfig = %{epoch}:%{version}-%{release} Requires: boost-devel Requires: pkgconfig(libLogger) -Requires: libjson-devel +%if %{platform_type} == "TIZEN" +Requires: libjson-devel >= 0.10 +%else +Requires: json-c-devel +%endif %description -n libConfig-devel The package provides libConfig development tools and libs. diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 9a1985c..92672c1 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -30,7 +30,7 @@ ADD_EXECUTABLE(${SERVER_CODENAME} ${project_SRCS} ${common_SRCS}) ## Link libraries ############################################################## FIND_PACKAGE(Boost COMPONENTS program_options system filesystem regex) -PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc json gio-2.0) +PKG_CHECK_MODULES(SERVER_DEPS REQUIRED lxc glib-2.0 gio-2.0) INCLUDE_DIRECTORIES(${COMMON_FOLDER}) INCLUDE_DIRECTORIES(${LIBS_FOLDER}) diff --git a/server/configs/daemon.conf.in b/server/configs/daemon.conf.in index b94eb29..f3dd9fd 100644 --- a/server/configs/daemon.conf.in +++ b/server/configs/daemon.conf.in @@ -1,13 +1,13 @@ { - "dbPath" : "/usr/dbspace/vasum.db", + "dbPath" : "/etc/vasum/vasum.db", "zoneIds" : [], - "zonesPath" : "${DATA_DIR}/.zones", + "zonesPath" : "${DATA_DIR}/zones", "zoneImagePath" : "", "zoneTemplateDir" : "/etc/vasum/templates/", "runMountPointPrefix" : "/var/run/zones", "defaultId" : "", "availableVTs" : [3, 4, 5, 6], - "inputConfig" : {"enabled" : true, + "inputConfig" : {"enabled" : false, "device" : "gpio_keys.6", "code" : 116, "numberOfEvents" : 2, diff --git a/server/configs/systemd/vasum.service.in b/server/configs/systemd/vasum.service.in index 29ebbc8..1b6284f 100644 --- a/server/configs/systemd/vasum.service.in +++ b/server/configs/systemd/vasum.service.in @@ -1,6 +1,5 @@ [Unit] Description=Vasum Server -ConditionVirtualization=no [Service] Type=simple diff --git a/server/configs/templates/tizen-common-wayland.sh b/server/configs/templates/tizen-common-wayland.sh index 5c57aff..30b90cd 100755 --- a/server/configs/templates/tizen-common-wayland.sh +++ b/server/configs/templates/tizen-common-wayland.sh @@ -122,6 +122,8 @@ ${path}/systemd/user /bin/ln -s /dev/null ${path}/systemd/system/systemd-udevd.service /bin/ln -s /dev/null ${path}/systemd/system/systemd-udevd-kernel.socket /bin/ln -s /dev/null ${path}/systemd/system/systemd-udevd-control.socket +/bin/ln -s /dev/null ${path}/systemd/system/vasum.service +/bin/ln -s /dev/null ${path}/systemd/system/vasum.socket /bin/ln -s /dev/null ${path}/systemd/system/vconf-setup.service /bin/ln -s /usr/lib/systemd/system/tlm.service ${path}/systemd/system/multi-user.target.wants/tlm.service /bin/ln -s /dev/null ${path}/systemd/user/media-server-user.service diff --git a/tests/integration_tests/network_tests/network_common.py b/tests/integration_tests/network_tests/network_common.py index acb120c..98e85b5 100755 --- a/tests/integration_tests/network_tests/network_common.py +++ b/tests/integration_tests/network_tests/network_common.py @@ -31,7 +31,7 @@ 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="/usr/share/.zones" +TEST_ZONE_PATH="/usr/share/zones" # Device Ethernet device ETHERNET_DEVICE="usb0" diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index 484e810..46a9a3b 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -47,7 +47,7 @@ ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS} ${clie ## Link libraries ############################################################## FIND_PACKAGE (Boost COMPONENTS unit_test_framework system filesystem regex) -PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc json gio-2.0) +PKG_CHECK_MODULES(UT_SERVER_DEPS REQUIRED lxc gio-2.0) INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${SERVER_FOLDER} ${UNIT_TESTS_FOLDER} ${CLIENT_FOLDER} ${LIBS_FOLDER} ${SOCKET_TEST_FOLDER}) INCLUDE_DIRECTORIES(SYSTEM ${UT_SERVER_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) diff --git a/tests/unit_tests/configs/CMakeLists.txt b/tests/unit_tests/configs/CMakeLists.txt index a18914e..6bffac4 100644 --- a/tests/unit_tests/configs/CMakeLists.txt +++ b/tests/unit_tests/configs/CMakeLists.txt @@ -34,6 +34,9 @@ CONFIGURE_FILE(templates/console-ipc.conf.in ${CMAKE_BINARY_DIR}/templates/console-ipc.conf @ONLY) FILE(GLOB ut_zone_templates_CONF_GEN ${CMAKE_BINARY_DIR}/templates/*.conf) +CONFIGURE_FILE(systemd/vasum-socket-test.service.in + ${CMAKE_BINARY_DIR}/systemd/vasum-socket-test.service) + ## Install ##################################################################### INSTALL(FILES ${ut_zone_CONF} @@ -58,7 +61,7 @@ INSTALL(FILES utils/file.txt DESTINATION ${VSM_TEST_CONFIG_INSTALL_DIR}/utils) INSTALL(FILES systemd/vasum-socket-test.socket - systemd/vasum-socket-test.service + ${CMAKE_BINARY_DIR}/systemd/vasum-socket-test.service DESTINATION ${SYSTEMD_UNIT_DIR}) INSTALL(FILES dbus-1/system.d/org.tizen.vasum.tests.conf diff --git a/tests/unit_tests/configs/systemd/vasum-socket-test.service b/tests/unit_tests/configs/systemd/vasum-socket-test.service.in similarity index 72% rename from tests/unit_tests/configs/systemd/vasum-socket-test.service rename to tests/unit_tests/configs/systemd/vasum-socket-test.service.in index 23c6d3a..b5da48b 100644 --- a/tests/unit_tests/configs/systemd/vasum-socket-test.service +++ b/tests/unit_tests/configs/systemd/vasum-socket-test.service.in @@ -3,7 +3,7 @@ Description=Vasum Socket tests mini-service [Service] Type=simple -ExecStart=/usr/bin/vasum-socket-test +ExecStart=${CMAKE_INSTALL_PREFIX}/bin/vasum-socket-test Sockets=vasum-socket-test.socket StartLimitInterval=0 StartLimitBurst=0 diff --git a/wrapper/CMakeLists.txt b/wrapper/CMakeLists.txt index a8aa173..23fdba6 100644 --- a/wrapper/CMakeLists.txt +++ b/wrapper/CMakeLists.txt @@ -70,7 +70,7 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(TARGETS ${PROJECT_NAME} - DESTINATION ${CMAKE_INSTALL_LIBDIR} + DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) INSTALL(FILES vasum.h vasum_list.h -- 2.7.4 From 48f17bbffc27fe5cc6d9491bdccdb6fcd5c42777 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Tue, 26 May 2015 08:52:19 +0200 Subject: [PATCH 11/16] Remove useless callback layer from Host*Connection [Bug] Host*Connection classes had redundant callback layer. [Cause] N/A [Solution] Make Host*Connection objects aware of ZonesManager. Remove unneeded callbacks. [Verification] For both with and without Dbus: * Build * Run tests * Make sure, that vasum-cli works Change-Id: I8fd76d279731efdf201e797f2ef7600aed355aaa --- server/host-dbus-connection.cpp | 324 +++++++--------------------------- server/host-dbus-connection.hpp | 266 +--------------------------- server/host-ipc-connection.cpp | 92 +++++++++- server/host-ipc-connection.hpp | 13 +- server/zones-manager.cpp | 96 +--------- server/zones-manager.hpp | 117 ++++++------ tests/unit_tests/client/ut-client.cpp | 1 + 7 files changed, 231 insertions(+), 678 deletions(-) diff --git a/server/host-dbus-connection.cpp b/server/host-dbus-connection.cpp index ad0ba0d..7714b65 100644 --- a/server/host-dbus-connection.cpp +++ b/server/host-dbus-connection.cpp @@ -32,6 +32,7 @@ #include "logger/logger.hpp" #include "config/manager.hpp" +#include "zones-manager.hpp" namespace vasum { @@ -41,13 +42,15 @@ namespace { // Can happen if glib loop is busy or not present. // TODO: this should be in host's configuration file const unsigned int NAME_ACQUIRED_TIMEOUT = 5 * 1000; +const std::string EMPTY_CALLER = ""; } // namespace -HostDbusConnection::HostDbusConnection() +HostDbusConnection::HostDbusConnection(ZonesManager* zonesManagerPtr) : mNameAcquired(false) , mNameLost(false) + , mZonesManagerPtr(zonesManagerPtr) { LOGT("Connecting to host system DBUS"); mDbusConnection = dbus::DbusConnection::createSystem(); @@ -117,151 +120,6 @@ void HostDbusConnection::setProxyCallCallback(const ProxyCallCallback& callback) mProxyCallCallback = callback; } -void HostDbusConnection::setGetZoneConnectionsCallback(const GetZoneConnectionsCallback& callback) -{ - mGetZoneConnectionsCallback = callback; -} - -void HostDbusConnection::setGetZoneIdsCallback(const GetZoneIdsCallback& callback) -{ - mGetZoneIdsCallback = callback; -} - -void HostDbusConnection::setGetActiveZoneIdCallback(const GetActiveZoneIdCallback& callback) -{ - mGetActiveZoneIdCallback = callback; -} - -void HostDbusConnection::setGetZoneInfoCallback(const GetZoneInfoCallback& callback) -{ - mGetZoneInfoCallback = callback; -} - -void HostDbusConnection::setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback) -{ - mSetNetdevAttrsCallback = callback; -} - -void HostDbusConnection::setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback) -{ - mGetNetdevAttrsCallback = callback; -} - -void HostDbusConnection::setGetNetdevListCallback(const GetNetdevListCallback& callback) -{ - mGetNetdevListCallback = callback; -} - -void HostDbusConnection::setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback) -{ - mCreateNetdevVethCallback = callback; -} - -void HostDbusConnection::setCreateNetdevMacvlanCallback(const CreateNetdevMacvlanCallback& callback) -{ - mCreateNetdevMacvlanCallback = callback; -} - -void HostDbusConnection::setCreateNetdevPhysCallback(const CreateNetdevPhysCallback& callback) -{ - mCreateNetdevPhysCallback = callback; -} - -void HostDbusConnection::setDestroyNetdevCallback(const DestroyNetdevCallback& callback) -{ - mDestroyNetdevCallback = callback; -} - -void HostDbusConnection::setDeleteNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback) -{ - mDeleteNetdevIpAddressCallback = callback; -} - -void HostDbusConnection::setDeclareFileCallback(const DeclareFileCallback& callback) -{ - mDeclareFileCallback = callback; -} - -void HostDbusConnection::setDeclareMountCallback(const DeclareMountCallback& callback) -{ - mDeclareMountCallback = callback; -} - -void HostDbusConnection::setDeclareLinkCallback(const DeclareLinkCallback& callback) -{ - mDeclareLinkCallback = callback; -} - -void HostDbusConnection::setGetDeclarationsCallback(const GetDeclarationsCallback& callback) -{ - mGetDeclarationsCallback = callback; -} - -void HostDbusConnection::setRemoveDeclarationCallback(const RemoveDeclarationCallback& callback) -{ - mRemoveDeclarationCallback = callback; -} - -void HostDbusConnection::setSetActiveZoneCallback(const SetActiveZoneCallback& callback) -{ - mSetActiveZoneCallback = callback; -} - -void HostDbusConnection::setCreateZoneCallback(const CreateZoneCallback& callback) -{ - mCreateZoneCallback = callback; -} - -void HostDbusConnection::setDestroyZoneCallback(const DestroyZoneCallback& callback) -{ - mDestroyZoneCallback = callback; -} - -void HostDbusConnection::setShutdownZoneCallback(const ShutdownZoneCallback& callback) -{ - mShutdownZoneCallback = callback; -} - -void HostDbusConnection::setStartZoneCallback(const StartZoneCallback& callback) -{ - mStartZoneCallback = callback; -} - -void HostDbusConnection::setLockZoneCallback(const LockZoneCallback& callback) -{ - mLockZoneCallback = callback; -} - -void HostDbusConnection::setUnlockZoneCallback(const UnlockZoneCallback& callback) -{ - mUnlockZoneCallback = callback; -} - -void HostDbusConnection::setGrantDeviceCallback(const GrantDeviceCallback& callback) -{ - mGrantDeviceCallback = callback; -} - -void HostDbusConnection::setRevokeDeviceCallback(const RevokeDeviceCallback& callback) -{ - mRevokeDeviceCallback = callback; -} - -void HostDbusConnection::setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback) -{ - mNotifyActiveZoneCallback = callback; -} - -void HostDbusConnection::setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback) -{ - mSwitchToDefaultCallback = callback; -} - -void HostDbusConnection::setFileMoveCallback(const FileMoveCallback& callback) -{ - mFileMoveCallback = callback; -} - void HostDbusConnection::onMessageCall(const std::string& objectPath, const std::string& interface, const std::string& methodName, @@ -276,10 +134,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); - if (mSetActiveZoneCallback) { - auto rb = std::make_shared>(result); - mSetActiveZoneCallback(zoneId, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleSetActiveZoneCall(zoneId, rb); return; } @@ -313,18 +169,14 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, } if (methodName == api::dbus::METHOD_GET_ZONE_ID_LIST) { - if (mGetZoneIdsCallback) { - auto rb = std::make_shared>(result); - mGetZoneIdsCallback(rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetZoneIdsCall(rb); return; } if (methodName == api::dbus::METHOD_GET_ACTIVE_ZONE_ID) { - if (mGetActiveZoneIdCallback) { - auto rb = std::make_shared>(result); - mGetActiveZoneIdCallback(rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetActiveZoneIdCall(rb); return; } @@ -332,10 +184,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId zoneId; config::loadFromGVariant(parameters, zoneId); - if (mGetZoneInfoCallback) { - auto rb = std::make_shared>(result); - mGetZoneInfoCallback(zoneId, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetZoneInfoCall(zoneId, rb); return; } @@ -343,10 +193,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::SetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); - if (mSetNetdevAttrsCallback) { - auto rb = std::make_shared>(result); - mSetNetdevAttrsCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleSetNetdevAttrsCall(data, rb); return; } @@ -354,10 +202,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::GetNetDevAttrsIn data; config::loadFromGVariant(parameters, data); - if (mGetNetdevAttrsCallback) { - auto rb = std::make_shared>(result); - mGetNetdevAttrsCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetNetdevAttrsCall(data, rb); return; } @@ -365,10 +211,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mGetNetdevListCallback) { - auto rb = std::make_shared>(result); - mGetNetdevListCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetNetdevListCall(data, rb); return; } @@ -376,10 +220,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::CreateNetDevVethIn data; config::loadFromGVariant(parameters, data); - if (mCreateNetdevVethCallback) { - auto rb = std::make_shared>(result); - mCreateNetdevVethCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleCreateNetdevVethCall(data, rb); return; } @@ -387,49 +229,44 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::CreateNetDevMacvlanIn data; config::loadFromGVariant(parameters, data); - if (mCreateNetdevMacvlanCallback) { - auto rb = std::make_shared>(result); - mCreateNetdevMacvlanCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleCreateNetdevMacvlanCall(data, rb); + return; } if (methodName == api::dbus::METHOD_CREATE_NETDEV_PHYS) { api::CreateNetDevPhysIn data; config::loadFromGVariant(parameters, data); - if (mCreateNetdevPhysCallback) { - auto rb = std::make_shared>(result); - mCreateNetdevPhysCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleCreateNetdevPhysCall(data, rb); + return; } if (methodName == api::dbus::METHOD_DESTROY_NETDEV) { api::DestroyNetDevIn data; config::loadFromGVariant(parameters, data); - if (mDestroyNetdevCallback) { - auto rb = std::make_shared>(result); - mDestroyNetdevCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDestroyNetdevCall(data, rb); + return; } if (methodName == api::dbus::METHOD_DELETE_NETDEV_IP_ADDRESS) { api::DeleteNetdevIpAddressIn data; config::loadFromGVariant(parameters, data); - if (mDeleteNetdevIpAddressCallback) { - auto rb = std::make_shared>(result); - mDeleteNetdevIpAddressCallback(data, rb); - } + + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDeleteNetdevIpAddressCall(data, rb); + return; } if (methodName == api::dbus::METHOD_DECLARE_FILE) { api::DeclareFileIn data; config::loadFromGVariant(parameters, data); - if (mDeclareFileCallback) { - auto rb = std::make_shared>(result); - mDeclareFileCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDeclareFileCall(data, rb); return; } @@ -437,10 +274,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::DeclareMountIn data; config::loadFromGVariant(parameters, data); - if (mDeclareMountCallback) { - auto rb = std::make_shared>(result); - mDeclareMountCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDeclareMountCall(data, rb); return; } @@ -448,10 +283,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::DeclareLinkIn data; config::loadFromGVariant(parameters, data); - if (mDeclareLinkCallback) { - auto rb = std::make_shared>(result); - mDeclareLinkCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDeclareLinkCall(data, rb); return; } @@ -459,10 +292,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mGetDeclarationsCallback) { - auto rb = std::make_shared>(result); - mGetDeclarationsCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGetDeclarationsCall(data, rb); return; } @@ -470,10 +301,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::RemoveDeclarationIn data; config::loadFromGVariant(parameters, data); - if (mRemoveDeclarationCallback) { - auto rb = std::make_shared>(result); - mRemoveDeclarationCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleRemoveDeclarationCall(data, rb); return; } @@ -481,10 +310,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::CreateZoneIn data; config::loadFromGVariant(parameters, data); - if (mCreateZoneCallback) { - auto rb = std::make_shared>(result); - mCreateZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleCreateZoneCall(data, rb); return; } @@ -492,10 +319,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mDestroyZoneCallback) { - auto rb = std::make_shared>(result); - mDestroyZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleDestroyZoneCall(data, rb); return; } @@ -503,30 +328,25 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mShutdownZoneCallback) { - auto rb = std::make_shared>(result); - mShutdownZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleShutdownZoneCall(data, rb); + return; } if (methodName == api::dbus::METHOD_START_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mStartZoneCallback) { - auto rb = std::make_shared>(result); - mStartZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleStartZoneCall(data, rb); } if (methodName == api::dbus::METHOD_LOCK_ZONE) { api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mLockZoneCallback) { - auto rb = std::make_shared>(result); - mLockZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleLockZoneCall(data, rb); return; } @@ -534,10 +354,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::ZoneId data; config::loadFromGVariant(parameters, data); - if (mUnlockZoneCallback) { - auto rb = std::make_shared>(result); - mUnlockZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleUnlockZoneCall(data, rb); return; } @@ -545,10 +363,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::GrantDeviceIn data; config::loadFromGVariant(parameters, data); - if (mGrantDeviceCallback) { - auto rb = std::make_shared>(result); - mGrantDeviceCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleGrantDeviceCall(data, rb); return; } @@ -556,10 +372,8 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::RevokeDeviceIn data; config::loadFromGVariant(parameters, data); - if (mRevokeDeviceCallback) { - auto rb = std::make_shared>(result); - mRevokeDeviceCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleRevokeDeviceCall(data, rb); return; } @@ -567,20 +381,18 @@ void HostDbusConnection::onMessageCall(const std::string& objectPath, api::NotifActiveZoneIn data; config::loadFromGVariant(parameters, data); - if (mNotifyActiveZoneCallback) { - auto rb = std::make_shared>(result); - mNotifyActiveZoneCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleNotifyActiveZoneCall(EMPTY_CALLER, data, rb); + return; } if (methodName == api::dbus::METHOD_FILE_MOVE_REQUEST) { api::FileMoveRequestIn data; config::loadFromGVariant(parameters, data); - if (mFileMoveCallback) { - auto rb = std::make_shared>(result); - mFileMoveCallback(data, rb); - } + auto rb = std::make_shared>(result); + mZonesManagerPtr->handleFileMoveCall(EMPTY_CALLER, data, rb); + return; } } @@ -595,9 +407,7 @@ void HostDbusConnection::onSignalCall(const std::string& /* senderBusName */, } if (signalName == api::dbus::SIGNAL_SWITCH_TO_DEFAULT) { - if (mSwitchToDefaultCallback) { - mSwitchToDefaultCallback(); - } + mZonesManagerPtr->handleSwitchToDefaultCall(EMPTY_CALLER); } } diff --git a/server/host-dbus-connection.hpp b/server/host-dbus-connection.hpp index cdd8dda..23bb9d9 100644 --- a/server/host-dbus-connection.hpp +++ b/server/host-dbus-connection.hpp @@ -39,11 +39,12 @@ namespace vasum { +class ZonesManager; class HostDbusConnection { public: - HostDbusConnection(); + HostDbusConnection(ZonesManager* zm); ~HostDbusConnection(); // ------------- API -------------- @@ -56,89 +57,6 @@ public: GVariant* parameters, dbus::MethodResultBuilder::Pointer result )> ProxyCallCallback; - typedef std::function GetZoneConnectionsCallback; - typedef std::function GetZoneIdsCallback; - typedef std::function GetActiveZoneIdCallback; - typedef std::function GetZoneInfoCallback; - 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 DeleteNetdevIpAddressCallback; - 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; - typedef std::function NotifyActiveZoneCallback; - typedef std::function FileMoveCallback; - typedef std::function SwitchToDefaultCallback; - /** * Register proxy call callback @@ -146,156 +64,6 @@ public: void setProxyCallCallback(const ProxyCallCallback& callback); /** - * Register get zone connections callback - */ - void setGetZoneConnectionsCallback(const GetZoneConnectionsCallback& callback); - - /** - * Send signal describing dbus address state change - */ - void signalZoneConnectionState(const api::ConnectionState& state); - - /** - * Register a callback called to get a list of zone ids - */ - void setGetZoneIdsCallback(const GetZoneIdsCallback& callback); - - /** - * Register a callback called to get the active zone id - */ - void setGetActiveZoneIdCallback(const GetActiveZoneIdCallback& callback); - - /** - * Register a callback called to get the zone informations - */ - void setGetZoneInfoCallback(const GetZoneInfoCallback& callback); - - /** - * Register a callback called to set network device attributes - */ - void setSetNetdevAttrsCallback(const SetNetdevAttrsCallback& callback); - - /** - * Register a callback called to get network device attributes - */ - void setGetNetdevAttrsCallback(const GetNetdevAttrsCallback& callback); - - /** - * Register a callback called to get network device list - */ - void setGetNetdevListCallback(const GetNetdevListCallback& callback); - - /** - * Register a callback called to create veth - */ - void setCreateNetdevVethCallback(const CreateNetdevVethCallback& callback); - - /** - * Register a callback called to create macvlan - */ - void setCreateNetdevMacvlanCallback(const CreateNetdevMacvlanCallback& callback); - - /** - * Register a callback called to create/move phys - */ - void setCreateNetdevPhysCallback(const CreateNetdevPhysCallback& callback); - - /** - * Register a callback called to destroy netdev - */ - void setDestroyNetdevCallback(const DestroyNetdevCallback& callback); - - /** - * Register a callback called to remove ip address from netdev - */ - void setDeleteNetdevIpAddressCallback(const DeleteNetdevIpAddressCallback& callback); - - /** - * Register a callback called to declare file - */ - void setDeclareFileCallback(const DeclareFileCallback& callback); - - /** - * Register a callback called to declare mount point - */ - void setDeclareMountCallback(const DeclareMountCallback& callback); - - /** - * Register a callback called to declare link - */ - void setDeclareLinkCallback(const DeclareLinkCallback& callback); - - /** - * Register a callback called to list declarations - */ - void setGetDeclarationsCallback(const GetDeclarationsCallback& callback); - - /** - * Register a callback called to remove declarartion - */ - void setRemoveDeclarationCallback(const RemoveDeclarationCallback& callback); - - /** - * Register a callback called to set the active zone - */ - void setSetActiveZoneCallback(const SetActiveZoneCallback& callback); - - /** - * Register a callback called to create new zone - */ - void setCreateZoneCallback(const CreateZoneCallback& callback); - - /** - * Register a callback called to destroy zone - */ - void setDestroyZoneCallback(const DestroyZoneCallback& callback); - - /** - * Register a callback called to shutdown zone - */ - void setShutdownZoneCallback(const ShutdownZoneCallback& callback); - - /** - * Register a callback called to start zone - */ - void setStartZoneCallback(const StartZoneCallback& callback); - - /** - * Register a callback called to lock zone - */ - void setLockZoneCallback(const LockZoneCallback& callback); - - /** - * Register a callback called to unlock zone - */ - void setUnlockZoneCallback(const UnlockZoneCallback& callback); - - /** - * Register a callback called to grant device - */ - void setGrantDeviceCallback(const GrantDeviceCallback& callback); - - /** - * Register a callback called to revoke device - */ - void setRevokeDeviceCallback(const RevokeDeviceCallback& callback); - - /** - * Register notification request callback - */ - void setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback); - - /** - * Register switch to default request callback - */ - void setSwitchToDefaultCallback(const SwitchToDefaultCallback& callback); - - /* - * Register file move request callback - */ - void setFileMoveCallback(const FileMoveCallback& callback); - - /** * Send notification signal to this zone */ void sendNotification(const api::Notification& notify); @@ -318,35 +86,7 @@ private: bool mNameLost; dbus::DbusConnection::SubscriptionId mSubscriptionId; ProxyCallCallback mProxyCallCallback; - GetZoneConnectionsCallback mGetZoneConnectionsCallback; - GetZoneIdsCallback mGetZoneIdsCallback; - GetActiveZoneIdCallback mGetActiveZoneIdCallback; - GetZoneInfoCallback mGetZoneInfoCallback; - SetNetdevAttrsCallback mSetNetdevAttrsCallback; - GetNetdevAttrsCallback mGetNetdevAttrsCallback; - GetNetdevListCallback mGetNetdevListCallback; - CreateNetdevVethCallback mCreateNetdevVethCallback; - CreateNetdevMacvlanCallback mCreateNetdevMacvlanCallback; - CreateNetdevPhysCallback mCreateNetdevPhysCallback; - DestroyNetdevCallback mDestroyNetdevCallback; - DeleteNetdevIpAddressCallback mDeleteNetdevIpAddressCallback; - DeclareFileCallback mDeclareFileCallback; - DeclareMountCallback mDeclareMountCallback; - DeclareLinkCallback mDeclareLinkCallback; - GetDeclarationsCallback mGetDeclarationsCallback; - RemoveDeclarationCallback mRemoveDeclarationCallback; - SetActiveZoneCallback mSetActiveZoneCallback; - CreateZoneCallback mCreateZoneCallback; - DestroyZoneCallback mDestroyZoneCallback; - ShutdownZoneCallback mShutdownZoneCallback; - StartZoneCallback mStartZoneCallback; - LockZoneCallback mLockZoneCallback; - UnlockZoneCallback mUnlockZoneCallback; - GrantDeviceCallback mGrantDeviceCallback; - RevokeDeviceCallback mRevokeDeviceCallback; - NotifyActiveZoneCallback mNotifyActiveZoneCallback; - SwitchToDefaultCallback mSwitchToDefaultCallback; - FileMoveCallback mFileMoveCallback; + ZonesManager* mZonesManagerPtr; void onNameAcquired(); void onNameLost(); diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp index d6519e9..1a003d4 100644 --- a/server/host-ipc-connection.cpp +++ b/server/host-ipc-connection.cpp @@ -24,14 +24,19 @@ #include "config.hpp" +#include + #include "host-ipc-connection.hpp" #include "host-ipc-definitions.hpp" #include "exception.hpp" #include "logger/logger.hpp" +#include "zones-manager.hpp" + namespace vasum { -HostIPCConnection::HostIPCConnection() +HostIPCConnection::HostIPCConnection(ZonesManager* zonesManagerPtr) + : mZonesManagerPtr(zonesManagerPtr) { LOGT("Connecting to host IPC socket"); mService.reset(new ipc::Service(mDispatcher.getPoll(), HOST_IPC_SOCKET)); @@ -39,6 +44,91 @@ HostIPCConnection::HostIPCConnection() LOGT("Starting IPC"); mService->start(); LOGD("Connected"); + + using namespace std::placeholders; + setGetZoneIdsCallback(std::bind(&ZonesManager::handleGetZoneIdsCall, + mZonesManagerPtr, _1)); + + setGetActiveZoneIdCallback(std::bind(&ZonesManager::handleGetActiveZoneIdCall, + mZonesManagerPtr, _1)); + + setGetZoneInfoCallback(std::bind(&ZonesManager::handleGetZoneInfoCall, + mZonesManagerPtr, _1, _2)); + + setSetNetdevAttrsCallback(std::bind(&ZonesManager::handleSetNetdevAttrsCall, + mZonesManagerPtr, _1, _2)); + + setGetNetdevAttrsCallback(std::bind(&ZonesManager::handleGetNetdevAttrsCall, + mZonesManagerPtr, _1, _2)); + + setGetNetdevListCallback(std::bind(&ZonesManager::handleGetNetdevListCall, + mZonesManagerPtr, _1, _2)); + + setCreateNetdevVethCallback(std::bind(&ZonesManager::handleCreateNetdevVethCall, + mZonesManagerPtr, _1, _2)); + + setCreateNetdevMacvlanCallback(std::bind(&ZonesManager::handleCreateNetdevMacvlanCall, + mZonesManagerPtr, _1, _2)); + + setCreateNetdevPhysCallback(std::bind(&ZonesManager::handleCreateNetdevPhysCall, + mZonesManagerPtr, _1, _2)); + + setDestroyNetdevCallback(std::bind(&ZonesManager::handleDestroyNetdevCall, + mZonesManagerPtr, _1, _2)); + + setDeleteNetdevIpAddressCallback(std::bind(&ZonesManager::handleDeleteNetdevIpAddressCall, + mZonesManagerPtr, _1, _2)); + + setDeclareFileCallback(std::bind(&ZonesManager::handleDeclareFileCall, + mZonesManagerPtr, _1, _2)); + + setDeclareMountCallback(std::bind(&ZonesManager::handleDeclareMountCall, + mZonesManagerPtr, _1, _2)); + + setDeclareLinkCallback(std::bind(&ZonesManager::handleDeclareLinkCall, + mZonesManagerPtr, _1, _2)); + + setGetDeclarationsCallback(std::bind(&ZonesManager::handleGetDeclarationsCall, + mZonesManagerPtr, _1, _2)); + + setRemoveDeclarationCallback(std::bind(&ZonesManager::handleRemoveDeclarationCall, + mZonesManagerPtr, _1, _2)); + + setSetActiveZoneCallback(std::bind(&ZonesManager::handleSetActiveZoneCall, + mZonesManagerPtr, _1, _2)); + + setCreateZoneCallback(std::bind(&ZonesManager::handleCreateZoneCall, + mZonesManagerPtr, _1, _2)); + + setDestroyZoneCallback(std::bind(&ZonesManager::handleDestroyZoneCall, + mZonesManagerPtr, _1, _2)); + + setShutdownZoneCallback(std::bind(&ZonesManager::handleShutdownZoneCall, + mZonesManagerPtr, _1, _2)); + + setStartZoneCallback(std::bind(&ZonesManager::handleStartZoneCall, + mZonesManagerPtr, _1, _2)); + + setLockZoneCallback(std::bind(&ZonesManager::handleLockZoneCall, + mZonesManagerPtr, _1, _2)); + + setUnlockZoneCallback(std::bind(&ZonesManager::handleUnlockZoneCall, + mZonesManagerPtr, _1, _2)); + + setGrantDeviceCallback(std::bind(&ZonesManager::handleGrantDeviceCall, + mZonesManagerPtr, _1, _2)); + + setRevokeDeviceCallback(std::bind(&ZonesManager::handleRevokeDeviceCall, + mZonesManagerPtr, _1, _2)); + + setNotifyActiveZoneCallback(std::bind(&ZonesManager::handleNotifyActiveZoneCall, + mZonesManagerPtr, "", _1, _2)); + + setSwitchToDefaultCallback(std::bind(&ZonesManager::handleSwitchToDefaultCall, + mZonesManagerPtr, "")); + + setFileMoveCallback(std::bind(&ZonesManager::handleFileMoveCall, + mZonesManagerPtr, "", _1, _2)); } HostIPCConnection::~HostIPCConnection() diff --git a/server/host-ipc-connection.hpp b/server/host-ipc-connection.hpp index b5d671e..3e4e7ff 100644 --- a/server/host-ipc-connection.hpp +++ b/server/host-ipc-connection.hpp @@ -33,6 +33,7 @@ namespace vasum { +class ZonesManager; class HostIPCConnection { public: @@ -47,11 +48,15 @@ public: typedef typename IPCSignalWrapper::type type; }; - HostIPCConnection(); + HostIPCConnection(ZonesManager* zm); ~HostIPCConnection(); - void setGetZoneConnectionsCallback(const Method::type& callback); + void signalZoneConnectionState(const api::ConnectionState& connectionState); + void sendNotification(const api::Notification& notification); + +private: void setGetZoneIdsCallback(const Method::type& callback); + void setGetZoneConnectionsCallback(const Method::type& callback); void setGetActiveZoneIdCallback(const Method::type& callback); void setGetZoneInfoCallback(const Method::type& callback); void setSetNetdevAttrsCallback(const Method::type& callback); @@ -80,12 +85,10 @@ public: void setSwitchToDefaultCallback(const Signal::type& callback); void setFileMoveCallback(const Method::type& callback); - void signalZoneConnectionState(const api::ConnectionState& connectionState); - void sendNotification(const api::Notification& notification); -private: ipc::epoll::ThreadDispatcher mDispatcher; std::unique_ptr mService; + ZonesManager* mZonesManagerPtr; }; } // namespace vasum diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 0762294..a66eff1 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -112,98 +112,14 @@ bool zoneIsRunning(const std::unique_ptr& zone) { } // namespace -template -void ZonesManager::setHandlers(Connection& connection) -{ - using namespace std::placeholders; - connection.setGetZoneIdsCallback(bind(&ZonesManager::handleGetZoneIdsCall, - this, _1)); - - connection.setGetActiveZoneIdCallback(bind(&ZonesManager::handleGetActiveZoneIdCall, - this, _1)); - - connection.setGetZoneInfoCallback(bind(&ZonesManager::handleGetZoneInfoCall, - this, _1, _2)); - - connection.setSetNetdevAttrsCallback(bind(&ZonesManager::handleSetNetdevAttrsCall, - this, _1, _2)); - - connection.setGetNetdevAttrsCallback(bind(&ZonesManager::handleGetNetdevAttrsCall, - this, _1, _2)); - - connection.setGetNetdevListCallback(bind(&ZonesManager::handleGetNetdevListCall, - this, _1, _2)); - - connection.setCreateNetdevVethCallback(bind(&ZonesManager::handleCreateNetdevVethCall, - this, _1, _2)); - - connection.setCreateNetdevMacvlanCallback(bind(&ZonesManager::handleCreateNetdevMacvlanCall, - this, _1, _2)); - - connection.setCreateNetdevPhysCallback(bind(&ZonesManager::handleCreateNetdevPhysCall, - this, _1, _2)); - - connection.setDestroyNetdevCallback(bind(&ZonesManager::handleDestroyNetdevCall, - this, _1, _2)); - - connection.setDeleteNetdevIpAddressCallback(bind(&ZonesManager::handleDeleteNetdevIpAddressCall, - this, _1, _2)); - - connection.setDeclareFileCallback(bind(&ZonesManager::handleDeclareFileCall, - this, _1, _2)); - - connection.setDeclareMountCallback(bind(&ZonesManager::handleDeclareMountCall, - this, _1, _2)); - - connection.setDeclareLinkCallback(bind(&ZonesManager::handleDeclareLinkCall, - this, _1, _2)); - - connection.setGetDeclarationsCallback(bind(&ZonesManager::handleGetDeclarationsCall, - this, _1, _2)); - - connection.setRemoveDeclarationCallback(bind(&ZonesManager::handleRemoveDeclarationCall, - this, _1, _2)); - - connection.setSetActiveZoneCallback(bind(&ZonesManager::handleSetActiveZoneCall, - this, _1, _2)); - - connection.setCreateZoneCallback(bind(&ZonesManager::handleCreateZoneCall, - this, _1, _2)); - - connection.setDestroyZoneCallback(bind(&ZonesManager::handleDestroyZoneCall, - this, _1, _2)); - - connection.setShutdownZoneCallback(bind(&ZonesManager::handleShutdownZoneCall, - this, _1, _2)); - - connection.setStartZoneCallback(bind(&ZonesManager::handleStartZoneCall, - this, _1, _2)); - - connection.setLockZoneCallback(bind(&ZonesManager::handleLockZoneCall, - this, _1, _2)); - - connection.setUnlockZoneCallback(bind(&ZonesManager::handleUnlockZoneCall, - this, _1, _2)); - - connection.setGrantDeviceCallback(bind(&ZonesManager::handleGrantDeviceCall, - this, _1, _2)); - - connection.setRevokeDeviceCallback(bind(&ZonesManager::handleRevokeDeviceCall, - this, _1, _2)); - - connection.setNotifyActiveZoneCallback(bind(&ZonesManager::handleNotifyActiveZoneCall, - this, "", _1, _2)); - - connection.setSwitchToDefaultCallback(bind(&ZonesManager::handleSwitchToDefaultCall, - this, "")); - - connection.setFileMoveCallback(bind(&ZonesManager::handleFileMoveCall, - this, "", _1, _2)); -} ZonesManager::ZonesManager(const std::string& configPath) : mWorker(utils::Worker::create()) + , mHostIPCConnection(this) , mDetachOnExit(false) +#ifdef DBUS_CONNECTION + , mHostDbusConnection(this) +#endif { LOGD("Instantiating ZonesManager object..."); @@ -213,13 +129,11 @@ ZonesManager::ZonesManager(const std::string& configPath) mDynamicConfig, getVasumDbPrefix()); - setHandlers(mHostIPCConnection); #ifdef DBUS_CONNECTION using namespace std::placeholders; mProxyCallPolicy.reset(new ProxyCallPolicy(mConfig.proxyCallRules)); mHostDbusConnection.setProxyCallCallback(bind(&ZonesManager::handleProxyCall, this, HOST_ID, _1, _2, _3, _4, _5, _6, _7)); - setHandlers(mHostDbusConnection); #endif //DBUS_CONNECTION for (const auto& zoneId : mDynamicConfig.zoneIds) { @@ -237,8 +151,6 @@ ZonesManager::ZonesManager(const std::string& configPath) std::bind(&ZonesManager::switchingSequenceMonitorNotify, this))); } - - } ZonesManager::~ZonesManager() diff --git a/server/zones-manager.hpp b/server/zones-manager.hpp index 2a2f6d7..c74f5ec 100644 --- a/server/zones-manager.hpp +++ b/server/zones-manager.hpp @@ -28,11 +28,12 @@ #include "zone.hpp" #include "zones-manager-config.hpp" -#include "host-ipc-connection.hpp" +#include "api/messages.hpp" #include "input-monitor.hpp" #include "utils/worker.hpp" #include "api/method-result-builder.hpp" +#include "host-ipc-connection.hpp" #ifdef DBUS_CONNECTION #include "host-dbus-connection.hpp" #include "proxy-call-policy.hpp" @@ -44,7 +45,6 @@ namespace vasum { - class ZonesManager final { public: @@ -115,62 +115,6 @@ public: */ void setZonesDetachOnExit(); -private: - typedef std::recursive_mutex Mutex; - typedef std::unique_lock Lock; - - utils::Worker::Pointer mWorker; - Mutex mMutex; // used to protect mZones - ZonesManagerConfig mConfig; //TODO make it const - ZonesManagerDynamicConfig mDynamicConfig; -#ifdef DBUS_CONNECTION - HostDbusConnection mHostDbusConnection; -#endif //DBUS_CONNECTION - HostIPCConnection mHostIPCConnection; - // to hold InputMonitor pointer to monitor if zone switching sequence is recognized - std::unique_ptr mSwitchingSequenceMonitor; - // like set but keep insertion order - // smart pointer is needed because Zone is not moveable (because of mutex) - typedef std::vector> Zones; - Zones mZones; - std::string mActiveZoneId; - bool mDetachOnExit; - - Zones::iterator findZone(const std::string& id); - Zone& getZone(const std::string& id); - Zones::iterator getRunningForegroundZoneIterator(); - Zones::iterator getNextToForegroundZoneIterator(); - void focusInternal(Zones::iterator iter); - - void saveDynamicConfig(); - void updateDefaultId(); - void refocus(); - void switchingSequenceMonitorNotify(); - void generateNewConfig(const std::string& id, - const std::string& templatePath); - std::string getTemplatePathForExistingZone(const std::string& id); - int getVTForNewZone(); - void insertZone(const std::string& zoneId, const std::string& templatePath); - - // Zone's handlers--------------------------------------------------------- - void handleNotifyActiveZoneCall(const std::string& caller, - const api::NotifActiveZoneIn& notif, - api::MethodResultBuilder::Pointer result); - void handleSwitchToDefaultCall(const std::string& caller); - void handleFileMoveCall(const std::string& srcZoneId, - const api::FileMoveRequestIn& request, - api::MethodResultBuilder::Pointer result); -#ifdef DBUS_CONNECTION - std::unique_ptr mProxyCallPolicy; - void handleProxyCall(const std::string& caller, - const std::string& target, - const std::string& targetBusName, - const std::string& targetObjectPath, - const std::string& targetInterface, - const std::string& targetMethod, - GVariant* parameters, - dbus::MethodResultBuilder::Pointer result); -#endif //DBUS_CONNECTION // Handlers -------------------------------------------------------- void handleGetZoneIdsCall(api::MethodResultBuilder::Pointer result); void handleGetActiveZoneIdCall(api::MethodResultBuilder::Pointer result); @@ -221,8 +165,61 @@ private: void handleRevokeDeviceCall(const api::RevokeDeviceIn& data, api::MethodResultBuilder::Pointer result); - template - void setHandlers(Connection& connnection); + // Zone's handlers--------------------------------------------------------- + void handleNotifyActiveZoneCall(const std::string& caller, + const api::NotifActiveZoneIn& notif, + api::MethodResultBuilder::Pointer result); + void handleSwitchToDefaultCall(const std::string& caller); + void handleFileMoveCall(const std::string& srcZoneId, + const api::FileMoveRequestIn& request, + api::MethodResultBuilder::Pointer result); + +private: + typedef std::recursive_mutex Mutex; + typedef std::unique_lock Lock; + + utils::Worker::Pointer mWorker; + Mutex mMutex; // used to protect mZones + ZonesManagerConfig mConfig; //TODO make it const + ZonesManagerDynamicConfig mDynamicConfig; + HostIPCConnection mHostIPCConnection; + // to hold InputMonitor pointer to monitor if zone switching sequence is recognized + std::unique_ptr mSwitchingSequenceMonitor; + // like set but keep insertion order + // smart pointer is needed because Zone is not moveable (because of mutex) + typedef std::vector> Zones; + Zones mZones; + std::string mActiveZoneId; + bool mDetachOnExit; + + Zones::iterator findZone(const std::string& id); + Zone& getZone(const std::string& id); + Zones::iterator getRunningForegroundZoneIterator(); + Zones::iterator getNextToForegroundZoneIterator(); + void focusInternal(Zones::iterator iter); + + void saveDynamicConfig(); + void updateDefaultId(); + void refocus(); + void switchingSequenceMonitorNotify(); + void generateNewConfig(const std::string& id, + const std::string& templatePath); + std::string getTemplatePathForExistingZone(const std::string& id); + int getVTForNewZone(); + void insertZone(const std::string& zoneId, const std::string& templatePath); + +#ifdef DBUS_CONNECTION + HostDbusConnection mHostDbusConnection; + std::unique_ptr mProxyCallPolicy; + void handleProxyCall(const std::string& caller, + const std::string& target, + const std::string& targetBusName, + const std::string& targetObjectPath, + const std::string& targetInterface, + const std::string& targetMethod, + GVariant* parameters, + dbus::MethodResultBuilder::Pointer result); +#endif //DBUS_CONNECTION }; diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 3e83884..ce02a33 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -30,6 +30,7 @@ #include "utils/latch.hpp" #include "utils/scoped-dir.hpp" #include "zones-manager.hpp" +#include "host-ipc-connection.hpp" #include "host-ipc-definitions.hpp" #include "logger/logger.hpp" -- 2.7.4 From 10a140ebdb5ab5c3482d26f569b1e84a4c3dc463 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Tue, 9 Jun 2015 10:55:03 +0200 Subject: [PATCH 12/16] Fix CMake variables [Bug] * systemd service/socket files should be in /usr/local/lib, while compiled libraries should reside in /usr/local/lib64 on 64-bit systems. * Two sockets were created - one by systemd service, one by vasum IPC mechanisms. [Cause] N/A [Solution] Rename vasum-ipc.socket to vasum.socket Correct variables regarding library and systemd file locations [Verification] Build, install, run tests, run vasum-cli, check file locations and service files. Change-Id: I54681eaebd00b1aec547617a2ea51b0675c24ec3 --- CMakeLists.txt | 12 ++++++++---- server/configs/CMakeLists.txt | 4 +++- server/configs/systemd/{vasum.socket => vasum.socket.in} | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) rename server/configs/systemd/{vasum.socket => vasum.socket.in} (73%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e865117..cbcf4b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,7 +162,7 @@ IF(NOT DEFINED SYSCONF_INSTALL_DIR) ENDIF(NOT DEFINED SYSCONF_INSTALL_DIR) IF(NOT DEFINED LIB_INSTALL_DIR) - SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib") + SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") ENDIF(NOT DEFINED LIB_INSTALL_DIR) IF(NOT DEFINED INCLUDE_INSTALL_DIR) @@ -174,16 +174,20 @@ IF(NOT DEFINED SCRIPT_INSTALL_DIR) ENDIF(NOT DEFINED SCRIPT_INSTALL_DIR) IF(NOT DEFINED SYSTEMD_UNIT_DIR) - SET(SYSTEMD_UNIT_DIR "${LIB_INSTALL_DIR}/systemd/system") + SET(SYSTEMD_UNIT_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system") ENDIF(NOT DEFINED SYSTEMD_UNIT_DIR) IF(NOT DEFINED DATA_DIR) SET(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") ENDIF(NOT DEFINED DATA_DIR) +IF(NOT DEFINED RUN_DIR) + SET(RUN_DIR "/var/run") +ENDIF(NOT DEFINED RUN_DIR) + SET(VSM_CONFIG_INSTALL_DIR ${SYSCONF_INSTALL_DIR}/vasum) -SET(VSM_SERVER_IPC_SOCKET_PATH /var/run/vasum-ipc.socket) -SET(VSM_UNIT_TESTS_IPC_SOCKET_PATH /var/run/vasum-ipc-unit-tests.socket) +SET(VSM_SERVER_IPC_SOCKET_PATH ${RUN_DIR}/vasum.socket) +SET(VSM_UNIT_TESTS_IPC_SOCKET_PATH ${RUN_DIR}/vasum-ipc-unit-tests.socket) ADD_SUBDIRECTORY(${LOGGER_FOLDER}) ADD_SUBDIRECTORY(${DBUS_FOLDER}) diff --git a/server/configs/CMakeLists.txt b/server/configs/CMakeLists.txt index 278a9fc..c57a806 100644 --- a/server/configs/CMakeLists.txt +++ b/server/configs/CMakeLists.txt @@ -25,6 +25,8 @@ FILE(GLOB lxc_templates_CONF templates/*.sh) ## Generate #################################################################### CONFIGURE_FILE(systemd/vasum.service.in ${CMAKE_BINARY_DIR}/systemd/vasum.service) +CONFIGURE_FILE(systemd/vasum.socket.in + ${CMAKE_BINARY_DIR}/systemd/vasum.socket) ## Install ##################################################################### @@ -51,5 +53,5 @@ INSTALL(PROGRAMS ${lxc_templates_CONF} INSTALL(FILES ${CMAKE_BINARY_DIR}/systemd/vasum.service - systemd/vasum.socket + ${CMAKE_BINARY_DIR}/systemd/vasum.socket DESTINATION ${SYSTEMD_UNIT_DIR}) diff --git a/server/configs/systemd/vasum.socket b/server/configs/systemd/vasum.socket.in similarity index 73% rename from server/configs/systemd/vasum.socket rename to server/configs/systemd/vasum.socket.in index 792935d..05bc66d 100644 --- a/server/configs/systemd/vasum.socket +++ b/server/configs/systemd/vasum.socket.in @@ -1,5 +1,5 @@ [Socket] -ListenStream=/run/vasum.socket +ListenStream=${VSM_SERVER_IPC_SOCKET_PATH} SocketMode=0755 SmackLabelIPIn=* SmackLabelIPOut=@ -- 2.7.4 From 03fed6bbca029b3d7c1c2954afdb997f22f24313 Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 9 Jun 2015 15:18:29 +0200 Subject: [PATCH 13/16] Fix bash completion in case of user grep color aliases [Bug] Mitigate user grep aliases that use colors [Cause] N/A [Solution] Add --color=never to grep [Verification] Checked that bash completion works Change-Id: Ifffaf2e931f1cd573c6629a1932aca28b924509a --- cli/support/vasum-cli-completion.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/support/vasum-cli-completion.sh.in b/cli/support/vasum-cli-completion.sh.in index 79a5dad..18dda54 100755 --- a/cli/support/vasum-cli-completion.sh.in +++ b/cli/support/vasum-cli-completion.sh.in @@ -6,7 +6,7 @@ __@PROJECT_NAME@_cli() { COMPREPLY=() if [ "$COMP_CWORD" == "1" ]; then - COMPREPLY=($(compgen -W "$(@CLI_CODENAME@ | grep -e '^\S' | tail -n +3 | cut -f1 -d' ')" -- $cur)) + COMPREPLY=($(compgen -W "$(@CLI_CODENAME@ | grep --color=never -e '^\S' | tail -n +3 | cut -f1 -d' ')" -- $cur)) elif [ "$COMP_CWORD" == "2" ]; then COMPREPLY=($(compgen -W "-h" -- $cur)) fi -- 2.7.4 From a952476014d42a26feb4c99f5c48095bcf3d2ce7 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Wed, 10 Jun 2015 12:11:56 +0200 Subject: [PATCH 14/16] Remove unused function [Bug] Compile error [Cause] capget is static unused function [Solution] Remove capget [Verification] Compile with clang Change-Id: I3fb8e4b3de7f4bf4a02d3cb1c96009c3beb262c7 --- common/utils/environment.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index 9614cfa..4a04e0d 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -72,15 +72,6 @@ static inline int capset(cap_user_header_t header, const cap_user_data_t data) #error "capset syscall isn't available" #endif -#ifdef __NR_capget -static inline int capget(cap_user_header_t header, cap_user_data_t data) -{ - return syscall(__NR_capget, header, data); -} -#else -#error "capget syscall isn't available" -#endif - using namespace utils; namespace { -- 2.7.4 From e681d41197e79fcef3007058b3d1b09cd130ef3f Mon Sep 17 00:00:00 2001 From: Lukasz Pawelczyk Date: Tue, 9 Jun 2015 17:30:14 +0200 Subject: [PATCH 15/16] Fix for responding to a first request after socket activation [Bug] When socket activated the first request might not be properly handled because all the callback might not have registered yet. [Cause] N/A [Solution] Delayed handling requests until all the callbacks have been registered. [Verification] Built, installed, run tests. Did several tries with triggering socket activation: 1. systemctl start vasum.service 2. vasum-cli create_zone test 3. systemctl stop vasum.service 4. vasum-cli get_zone_ids 5. observe no error and list of zones should show 'test' 6. goto 3 Change-Id: I6de9742959d32afe68f496246065d3befc823955 --- server/host-ipc-connection.cpp | 11 +++++++---- server/host-ipc-connection.hpp | 1 + server/zones-manager.cpp | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/server/host-ipc-connection.cpp b/server/host-ipc-connection.cpp index 1a003d4..e87adca 100644 --- a/server/host-ipc-connection.cpp +++ b/server/host-ipc-connection.cpp @@ -41,10 +41,6 @@ HostIPCConnection::HostIPCConnection(ZonesManager* zonesManagerPtr) LOGT("Connecting to host IPC socket"); mService.reset(new ipc::Service(mDispatcher.getPoll(), HOST_IPC_SOCKET)); - LOGT("Starting IPC"); - mService->start(); - LOGD("Connected"); - using namespace std::placeholders; setGetZoneIdsCallback(std::bind(&ZonesManager::handleGetZoneIdsCall, mZonesManagerPtr, _1)); @@ -135,6 +131,13 @@ HostIPCConnection::~HostIPCConnection() { } +void HostIPCConnection::start() +{ + LOGT("Starting IPC"); + mService->start(); + LOGD("Connected"); +} + void HostIPCConnection::setGetZoneIdsCallback(const Method::type& callback) { typedef IPCMethodWrapper Callback; diff --git a/server/host-ipc-connection.hpp b/server/host-ipc-connection.hpp index 3e4e7ff..8107612 100644 --- a/server/host-ipc-connection.hpp +++ b/server/host-ipc-connection.hpp @@ -51,6 +51,7 @@ public: HostIPCConnection(ZonesManager* zm); ~HostIPCConnection(); + void start(); void signalZoneConnectionState(const api::ConnectionState& connectionState); void sendNotification(const api::Notification& notification); diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index a66eff1..7e0f641 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -151,6 +151,9 @@ ZonesManager::ZonesManager(const std::string& configPath) std::bind(&ZonesManager::switchingSequenceMonitorNotify, this))); } + + // After everything's initialized start to respond to clients' requests + mHostIPCConnection.start(); } ZonesManager::~ZonesManager() -- 2.7.4 From 3cce24ba314a579c5fedd44e75c00b737cedd304 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Wed, 10 Jun 2015 13:25:25 +0200 Subject: [PATCH 16/16] Remove ZoneAdmin class [Feature] Removed ZoneAdmin class [Cause] Unneeded layer between Zone class and LXC Zone [Solution] Remove ZoneAdmin class, move its functionality to Zone class [Verification] Build, install, run tests Change-Id: Id539ee2596c948f4cac6a0b9dff198d3d2b42c75 --- server/zone-admin.cpp | 323 ------------------------------ server/zone-admin.hpp | 192 ------------------ server/zone.cpp | 224 ++++++++++++++++++--- server/zone.hpp | 42 +++- server/zones-manager.cpp | 1 - tests/unit_tests/server/ut-zone-admin.cpp | 174 ---------------- tests/unit_tests/server/ut-zone.cpp | 95 ++++++++- 7 files changed, 314 insertions(+), 737 deletions(-) delete mode 100644 server/zone-admin.cpp delete mode 100644 server/zone-admin.hpp delete mode 100644 tests/unit_tests/server/ut-zone-admin.cpp diff --git a/server/zone-admin.cpp b/server/zone-admin.cpp deleted file mode 100644 index 05d9c7d..0000000 --- a/server/zone-admin.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Implementation of class for administrating one zone - */ - -#include "config.hpp" - -#include "zone-admin.hpp" -#include "exception.hpp" -#include "netdev.hpp" - -#include "logger/logger.hpp" -#include "utils/paths.hpp" -#include "utils/c-array.hpp" -#include "lxc/cgroup.hpp" - -#include -#include -#include -#include - - -namespace vasum { - -const std::uint64_t DEFAULT_CPU_SHARES = 1024; -const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000; - -ZoneAdmin::ZoneAdmin(const std::string& zoneId, - const std::string& zonesPath, - const std::string& zoneTemplateDir, - const ZoneConfig& config, - const ZoneDynamicConfig& dynamicConfig) - : mConfig(config), - mDynamicConfig(dynamicConfig), - mZone(zonesPath, zoneId), - mId(zoneId), - mDetachOnExit(false), - mDestroyOnExit(false) -{ - LOGD(mId << ": Instantiating ZoneAdmin object"); - - if (!mZone.isDefined()) { - - const std::string zoneTemplate = utils::getAbsolutePath(config.zoneTemplate, - zoneTemplateDir); - LOGI(mId << ": Creating zone from template: " << zoneTemplate); - utils::CStringArrayBuilder args; - if (!dynamicConfig.ipv4Gateway.empty()) { - args.add("--ipv4-gateway"); - args.add(dynamicConfig.ipv4Gateway.c_str()); - } - if (!dynamicConfig.ipv4.empty()) { - args.add("--ipv4"); - args.add(dynamicConfig.ipv4.c_str()); - } - const std::string vt = std::to_string(dynamicConfig.vt); - if (dynamicConfig.vt > 0) { - args.add("--vt"); - args.add(vt.c_str()); - } - if (!mZone.create(zoneTemplate, args.c_array())) { - throw ZoneOperationException("Could not create zone"); - } - } -} - - -ZoneAdmin::~ZoneAdmin() -{ - LOGD(mId << ": Destroying ZoneAdmin object..."); - - if (mDestroyOnExit) { - if (!mZone.stop()) { - LOGE(mId << ": Failed to stop the zone"); - } - if (!mZone.destroy()) { - LOGE(mId << ": Failed to destroy the zone"); - } - } - - if (!mDetachOnExit) { - // Try to forcefully stop - if (!mZone.stop()) { - LOGE(mId << ": Failed to stop the zone"); - } - } - - LOGD(mId << ": ZoneAdmin object destroyed"); -} - - -const std::string& ZoneAdmin::getId() const -{ - return mId; -} - - -void ZoneAdmin::start() -{ - LOGD(mId << ": Starting..."); - if (isRunning()) { - LOGD(mId << ": Already running - nothing to do..."); - return; - } - - utils::CStringArrayBuilder args; - for (const std::string& arg : mConfig.initWithArgs) { - args.add(arg.c_str()); - } - if (args.empty()) { - args.add("/sbin/init"); - } - - if (!mZone.start(args.c_array())) { - throw ZoneOperationException("Could not start zone"); - } - - // Wait until the full platform launch with graphical stack. - // VT should be activated by a graphical stack. - // If we do it with 'zoneToFocus.activateVT' before starting the graphical stack, - // graphical stack initialization failed and we finally switch to the black screen. - // Skip waiting when graphical stack is not running (unit tests). - if (mDynamicConfig.vt > 0) { - // TODO, timeout is a temporary solution - std::this_thread::sleep_for(std::chrono::milliseconds(4000)); - } - - LOGD(mId << ": Started"); -} - - -void ZoneAdmin::stop() -{ - LOGD(mId << ": Stopping procedure started..."); - if (isStopped()) { - LOGD(mId << ": Already crashed/down/off - nothing to do"); - return; - } - - if (!mZone.shutdown(mConfig.shutdownTimeout)) { - // force stop - if (!mZone.stop()) { - throw ZoneOperationException("Could not stop zone"); - } - } - - LOGD(mId << ": Stopping procedure ended"); -} - - -void ZoneAdmin::destroy() -{ - LOGD(mId << ": Destroying procedure started..."); - - if (!mZone.destroy()) { - throw ZoneOperationException("Could not destroy zone"); - } - - LOGD(mId << ": Destroying procedure ended"); -} - - -bool ZoneAdmin::isRunning() -{ - return mZone.getState() == lxc::LxcZone::State::RUNNING; -} - - -bool ZoneAdmin::isStopped() -{ - return mZone.getState() == lxc::LxcZone::State::STOPPED; -} - - -void ZoneAdmin::suspend() -{ - LOGD(mId << ": Pausing..."); - if (!mZone.freeze()) { - throw ZoneOperationException("Could not pause zone"); - } - LOGD(mId << ": Paused"); -} - - -void ZoneAdmin::resume() -{ - LOGD(mId << ": Resuming..."); - if (!mZone.unfreeze()) { - throw ZoneOperationException("Could not resume zone"); - } - LOGD(mId << ": Resumed"); -} - - -bool ZoneAdmin::isPaused() -{ - return mZone.getState() == lxc::LxcZone::State::FROZEN; -} - - -void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched) -{ - assert(isRunning()); - - switch (sched) { - case SchedulerLevel::FOREGROUND: - LOGD(mId << ": Setting SchedulerLevel::FOREGROUND"); - setSchedulerParams(DEFAULT_CPU_SHARES, - DEFAULT_VCPU_PERIOD_MS, - mConfig.cpuQuotaForeground); - break; - case SchedulerLevel::BACKGROUND: - LOGD(mId << ": Setting SchedulerLevel::BACKGROUND"); - setSchedulerParams(DEFAULT_CPU_SHARES, - DEFAULT_VCPU_PERIOD_MS, - mConfig.cpuQuotaBackground); - break; - default: - assert(0 && "Unknown sched parameter value"); - } -} - - -void ZoneAdmin::setSchedulerParams(std::uint64_t cpuShares, - std::uint64_t vcpuPeriod, - std::int64_t vcpuQuota) -{ - assert(vcpuPeriod >= 1000 && vcpuPeriod <= 1000000); - assert(vcpuQuota == -1 || - (vcpuQuota >= 1000 && vcpuQuota <= static_cast(ULLONG_MAX / 1000))); - - if (!lxc::setCgroup(mId, "cpu", "cpu.shares", std::to_string(cpuShares)) || - !lxc::setCgroup(mId, "cpu", "cpu.cfs_period_us", std::to_string(vcpuPeriod)) || - !lxc::setCgroup(mId, "cpu", "cpu.cfs_quota_us", std::to_string(vcpuQuota))) { - - LOGE(mId << ": Error while setting the zone's scheduler params"); - throw ZoneOperationException("Could not set scheduler params"); - } -} - -void ZoneAdmin::setDetachOnExit() -{ - mDetachOnExit = true; -} - -void ZoneAdmin::setDestroyOnExit() -{ - mDestroyOnExit = true; -} - -std::int64_t ZoneAdmin::getSchedulerQuota() -{ - std::string ret; - if (!lxc::getCgroup(mId, "cpu", "cpu.cfs_quota_us", ret)) { - LOGE(mId << ": Error while getting the zone's scheduler quota param"); - throw ZoneOperationException("Could not get scheduler quota param"); - } - return std::stoll(ret); -} - -void ZoneAdmin::createNetdevVeth(const std::string& zoneDev, - const std::string& hostDev) -{ - netdev::createVeth(mZone.getInitPid(), zoneDev, hostDev); -} - -void ZoneAdmin::createNetdevMacvlan(const std::string& zoneDev, - const std::string& hostDev, - const uint32_t& mode) -{ - netdev::createMacvlan(mZone.getInitPid(), zoneDev, hostDev, static_cast(mode)); -} - -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) -{ - netdev::setAttrs(mZone.getInitPid(), netdev, attrs); -} - -ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& netdev) -{ - return netdev::getAttrs(mZone.getInitPid(), netdev); -} - -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 deleted file mode 100644 index ec4c7cd..0000000 --- a/server/zone-admin.hpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Declaration of the class for administrating one zone - */ - - -#ifndef SERVER_ZONE_ADMIN_HPP -#define SERVER_ZONE_ADMIN_HPP - -#include "zone-config.hpp" -#include "lxc/zone.hpp" -#include "netdev.hpp" - -namespace vasum { - - -enum class SchedulerLevel { - FOREGROUND, - BACKGROUND -}; - -class ZoneAdmin { - -public: - typedef netdev::Attrs NetdevAttrs; - - /** - * ZoneAdmin constructor - * @param zoneId zone id - * @param zonesPath directory where zones are defined (configs, rootfs etc) - * @param zoneTemplateDir directory where templates are stored - * @param config zones config - * @param dynamicConfig zones dynamic config - */ - ZoneAdmin(const std::string& zoneId, - const std::string& zonesPath, - const std::string& zoneTemplateDir, - const ZoneConfig& config, - const ZoneDynamicConfig& dynamicConfig); - virtual ~ZoneAdmin(); - - /** - * Get the zone id - */ - const std::string& getId() const; - - /** - * Boot the zone to the background. - */ - void start(); - - /** - * Try to shutdown the zone, if failed, kill it. - */ - void stop(); - - /** - * Destroy stopped zone. In particular it removes whole zones rootfs. - */ - void destroy(); - - /** - * @return Is the zone running? - */ - bool isRunning(); - - /** - * Check if the zone is stopped. It's NOT equivalent to !isRunning, - * because it checks different internal zone states. There are other states, - * (e.g. paused) when the zone isn't running nor stopped. - * - * @return Is the zone stopped? - */ - bool isStopped(); - - /** - * Suspends an active zone, the process is frozen - * without further access to CPU resources and I/O, - * but the memory used by the zone - * at the hypervisor level will stay allocated - */ - void suspend(); - - /** - * Resume the zone after suspension. - */ - void resume(); - - /** - * @return Is the zone in a paused state? - */ - bool isPaused(); - - /** - * Sets the zones scheduler CFS quota. - */ - void setSchedulerLevel(SchedulerLevel sched); - - /** - * Set whether zone should be detached on exit. - */ - void setDetachOnExit(); - - /** - * Set if zone should be destroyed on exit. - */ - void setDestroyOnExit(); - - /** - * @return Scheduler CFS quota, - * TODO: this function is only for UNIT TESTS - */ - std::int64_t getSchedulerQuota(); - - /** - * Create veth network device - */ - void createNetdevVeth(const std::string& zoneDev, - const std::string& hostDev); - - /** - * Create macvlan network device - */ - void createNetdevMacvlan(const std::string& zoneDev, - const std::string& hostDev, - const uint32_t& mode); - - /** - * Move network device to zone - */ - 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); - - /** - * Get network device attributes - */ - NetdevAttrs getNetdevAttrs(const std::string& netdev); - - /** - * Get network device list - */ - 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; - lxc::LxcZone mZone; - const std::string mId; - bool mDetachOnExit; - bool mDestroyOnExit; - - void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota); -}; - - -} // namespace vasum - - -#endif // SERVER_ZONE_ADMIN_HPP diff --git a/server/zone.cpp b/server/zone.cpp index 3fe0b12..94f6873 100644 --- a/server/zone.cpp +++ b/server/zone.cpp @@ -26,17 +26,22 @@ #include "zone.hpp" #include "dynamic-config-scheme.hpp" -#include "base-exception.hpp" +#include "exception.hpp" #include "logger/logger.hpp" #include "utils/paths.hpp" #include "utils/vt.hpp" +#include "utils/c-array.hpp" +#include "lxc/cgroup.hpp" #include "config/manager.hpp" #include +#include +#include #include #include +#include namespace vasum { @@ -50,6 +55,9 @@ const std::string STATE_STOPPED = "stopped"; const std::string STATE_RUNNING = "running"; const std::string STATE_PAUSED = "paused"; +const std::uint64_t DEFAULT_CPU_SHARES = 1024; +const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000; + } // namespace Zone::Zone(const std::string& zoneId, @@ -59,7 +67,13 @@ Zone::Zone(const std::string& zoneId, const std::string& zoneTemplateDir, const std::string& baseRunMountPointPath) : mDbPath(dbPath) + , mZone(zonesPath, zoneId) + , mId(zoneId) + , mDetachOnExit(false) + , mDestroyOnExit(false) { + LOGD(mId << ": Instantiating Zone object"); + const std::string dbPrefix = getZoneDbPrefix(zoneId); config::loadFromKVStoreWithJsonFile(dbPath, zoneTemplatePath, mConfig, dbPrefix); config::loadFromKVStoreWithJsonFile(dbPath, zoneTemplatePath, mDynamicConfig, dbPrefix); @@ -75,7 +89,28 @@ Zone::Zone(const std::string& zoneId, mRunMountPoint = fs::absolute(mDynamicConfig.runMountPoint, baseRunMountPointPath).string(); } - mAdmin.reset(new ZoneAdmin(zoneId, zonesPath, zoneTemplateDir, mConfig, mDynamicConfig)); + if (!mZone.isDefined()) { + const std::string zoneTemplate = utils::getAbsolutePath(mConfig.zoneTemplate, + zoneTemplateDir); + LOGI(mId << ": Creating zone from template: " << zoneTemplate); + utils::CStringArrayBuilder args; + if (!mDynamicConfig.ipv4Gateway.empty()) { + args.add("--ipv4-gateway"); + args.add(mDynamicConfig.ipv4Gateway.c_str()); + } + if (!mDynamicConfig.ipv4.empty()) { + args.add("--ipv4"); + args.add(mDynamicConfig.ipv4.c_str()); + } + const std::string vt = std::to_string(mDynamicConfig.vt); + if (mDynamicConfig.vt > 0) { + args.add("--vt"); + args.add(vt.c_str()); + } + if (!mZone.create(zoneTemplate, args.c_array())) { + throw ZoneOperationException("Could not create zone"); + } + } const fs::path zonePath = fs::path(zonesPath) / zoneId; mRootPath = (zonePath / fs::path("rootfs")).string(); @@ -83,6 +118,29 @@ Zone::Zone(const std::string& zoneId, mProvision.reset(new ZoneProvision(mRootPath, zoneTemplatePath, dbPath, dbPrefix, mConfig.validLinkPrefixes)); } +Zone::~Zone() +{ + LOGD(mId << ": Destroying Zone object..."); + + if (mDestroyOnExit) { + if (!mZone.stop()) { + LOGE(mId << ": Failed to stop the zone"); + } + if (!mZone.destroy()) { + LOGE(mId << ": Failed to destroy the zone"); + } + } + + if (!mDetachOnExit && !mDestroyOnExit) { + // Try to forcefully stop + if (!mZone.stop()) { + LOGE(mId << ": Failed to stop the zone"); + } + } + + LOGD(mId << ": Zone object destroyed"); +} + const std::vector& Zone::getPermittedToSend() const { return mPermittedToSend; @@ -96,7 +154,7 @@ const std::vector& Zone::getPermittedToRecv() const const std::string& Zone::getId() const { Lock lock(mReconnectMutex); - return mAdmin->getId(); + return mId; } int Zone::getPrivilege() const @@ -106,14 +164,14 @@ int Zone::getPrivilege() const void Zone::saveDynamicConfig() { - config::saveToKVStore(mDbPath, mDynamicConfig, getZoneDbPrefix(getId())); + config::saveToKVStore(mDbPath, mDynamicConfig, getZoneDbPrefix(mId)); } void Zone::updateRequestedState(const std::string& state) { // assume mutex is locked if (state != mDynamicConfig.requestedState) { - LOGT("Set requested state of " << getId() << " to " << state); + LOGT("Set requested state of " << mId << " to " << state); mDynamicConfig.requestedState = state; saveDynamicConfig(); } @@ -125,7 +183,7 @@ void Zone::restore() { Lock lock(mReconnectMutex); requestedState = mDynamicConfig.requestedState; - LOGT("Requested state of " << getId() << ": " << requestedState); + LOGT("Requested state of " << mId << ": " << requestedState); } if (requestedState == STATE_RUNNING) { @@ -143,9 +201,41 @@ void Zone::restore() void Zone::start() { Lock lock(mReconnectMutex); + + LOGD(mId << ": Starting..."); + updateRequestedState(STATE_RUNNING); mProvision->start(); - mAdmin->start(); + + if (isRunning()) { + LOGD(mId << ": Already running - nothing to do..."); + return; + } + + utils::CStringArrayBuilder args; + for (const std::string& arg : mConfig.initWithArgs) { + args.add(arg.c_str()); + } + if (args.empty()) { + args.add("/sbin/init"); + } + + if (!mZone.start(args.c_array())) { + throw ZoneOperationException("Could not start zone"); + } + + // Wait until the full platform launch with graphical stack. + // VT should be activated by a graphical stack. + // If we do it with 'zoneToFocus.activateVT' before starting the graphical stack, + // graphical stack initialization failed and we finally switch to the black screen. + // Skip waiting when graphical stack is not running (unit tests). + if (mDynamicConfig.vt > 0) { + // TODO, timeout is a temporary solution + std::this_thread::sleep_for(std::chrono::milliseconds(4000)); + } + + LOGD(mId << ": Started"); + // Increase cpu quota before connect, otherwise it'd take ages. goForeground(); // refocus in ZonesManager will adjust cpu quota after all @@ -154,15 +244,32 @@ void Zone::start() void Zone::stop(bool saveState) { Lock lock(mReconnectMutex); + + LOGD(mId << ": Stopping procedure started..."); + if (saveState) { updateRequestedState(STATE_STOPPED); } - if (mAdmin->isRunning()) { + if (isRunning()) { // boost stopping goForeground(); } - mAdmin->stop(); + + if (isStopped()) { + LOGD(mId << ": Already crashed/down/off - nothing to do"); + return; + } + + if (!mZone.shutdown(mConfig.shutdownTimeout)) { + // force stop + if (!mZone.stop()) { + throw ZoneOperationException("Could not stop zone"); + } + } + mProvision->stop(); + + LOGD(mId << ": Stopping procedure ended"); } int Zone::getVT() const @@ -191,7 +298,7 @@ void Zone::createNetdevVeth(const std::string& zoneDev, const std::string& hostDev) { Lock lock(mReconnectMutex); - mAdmin->createNetdevVeth(zoneDev, hostDev); + netdev::createVeth(mZone.getInitPid(), zoneDev, hostDev); } void Zone::createNetdevMacvlan(const std::string& zoneDev, @@ -199,75 +306,87 @@ void Zone::createNetdevMacvlan(const std::string& zoneDev, const uint32_t& mode) { Lock lock(mReconnectMutex); - mAdmin->createNetdevMacvlan(zoneDev, hostDev, mode); + netdev::createMacvlan(mZone.getInitPid(), zoneDev, hostDev, static_cast(mode)); } void Zone::moveNetdev(const std::string& devId) { Lock lock(mReconnectMutex); - mAdmin->moveNetdev(devId); + netdev::movePhys(mZone.getInitPid(), devId); } void Zone::destroyNetdev(const std::string& devId) { Lock lock(mReconnectMutex); - mAdmin->destroyNetdev(devId); + netdev::destroyNetdev(devId, mZone.getInitPid()); } void Zone::goForeground() { Lock lock(mReconnectMutex); - mAdmin->setSchedulerLevel(SchedulerLevel::FOREGROUND); + setSchedulerLevel(SchedulerLevel::FOREGROUND); } void Zone::goBackground() { Lock lock(mReconnectMutex); - mAdmin->setSchedulerLevel(SchedulerLevel::BACKGROUND); + setSchedulerLevel(SchedulerLevel::BACKGROUND); } void Zone::setDetachOnExit() { Lock lock(mReconnectMutex); - mAdmin->setDetachOnExit(); + mDetachOnExit = true; } void Zone::setDestroyOnExit() { Lock lock(mReconnectMutex); - mAdmin->setDestroyOnExit(); + mDestroyOnExit = true; } bool Zone::isRunning() { Lock lock(mReconnectMutex); - return mAdmin->isRunning(); + return mZone.getState() == lxc::LxcZone::State::RUNNING; } bool Zone::isStopped() { Lock lock(mReconnectMutex); - return mAdmin->isStopped(); + return mZone.getState() == lxc::LxcZone::State::STOPPED; } void Zone::suspend() { Lock lock(mReconnectMutex); - mAdmin->suspend(); + + LOGD(mId << ": Pausing..."); + if (!mZone.freeze()) { + throw ZoneOperationException("Could not pause zone"); + } + LOGD(mId << ": Paused"); + updateRequestedState(STATE_PAUSED); } void Zone::resume() { Lock lock(mReconnectMutex); - mAdmin->resume(); + + LOGD(mId << ": Resuming..."); + if (!mZone.unfreeze()) { + throw ZoneOperationException("Could not resume zone"); + } + LOGD(mId << ": Resumed"); + updateRequestedState(STATE_RUNNING); } bool Zone::isPaused() { Lock lock(mReconnectMutex); - return mAdmin->isPaused(); + return mZone.getState() == lxc::LxcZone::State::FROZEN; } bool Zone::isSwitchToDefaultAfterTimeoutAllowed() const @@ -308,28 +427,77 @@ void Zone::removeDeclaration(const std::string& declarationId) mProvision->remove(declarationId); } -void Zone::setNetdevAttrs(const std::string& netdev, const ZoneAdmin::NetdevAttrs& attrs) +void Zone::setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs) { Lock lock(mReconnectMutex); - mAdmin->setNetdevAttrs(netdev, attrs); + netdev::setAttrs(mZone.getInitPid(), netdev, attrs); } -ZoneAdmin::NetdevAttrs Zone::getNetdevAttrs(const std::string& netdev) +Zone::NetdevAttrs Zone::getNetdevAttrs(const std::string& netdev) { Lock lock(mReconnectMutex); - return mAdmin->getNetdevAttrs(netdev); + return netdev::getAttrs(mZone.getInitPid(), netdev); } std::vector Zone::getNetdevList() { Lock lock(mReconnectMutex); - return mAdmin->getNetdevList(); + return netdev::listNetdev(mZone.getInitPid()); } void Zone::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip) { Lock lock(mReconnectMutex); - mAdmin->deleteNetdevIpAddress(netdev, ip); + netdev::deleteIpAddress(mZone.getInitPid(), netdev, ip); +} + +std::int64_t Zone::getSchedulerQuota() +{ + std::string ret; + if (!lxc::getCgroup(mId, "cpu", "cpu.cfs_quota_us", ret)) { + LOGE(mId << ": Error while getting the zone's scheduler quota param"); + throw ZoneOperationException("Could not get scheduler quota param"); + } + return std::stoll(ret); +} + +void Zone::setSchedulerLevel(SchedulerLevel sched) +{ + assert(isRunning()); + + switch (sched) { + case SchedulerLevel::FOREGROUND: + LOGD(mId << ": Setting SchedulerLevel::FOREGROUND"); + setSchedulerParams(DEFAULT_CPU_SHARES, + DEFAULT_VCPU_PERIOD_MS, + mConfig.cpuQuotaForeground); + break; + case SchedulerLevel::BACKGROUND: + LOGD(mId << ": Setting SchedulerLevel::BACKGROUND"); + setSchedulerParams(DEFAULT_CPU_SHARES, + DEFAULT_VCPU_PERIOD_MS, + mConfig.cpuQuotaBackground); + break; + default: + assert(0 && "Unknown sched parameter value"); + } +} + +void Zone::setSchedulerParams(std::uint64_t cpuShares, + std::uint64_t vcpuPeriod, + std::int64_t vcpuQuota) +{ + assert(vcpuPeriod >= 1000 && vcpuPeriod <= 1000000); + assert(vcpuQuota == -1 || + (vcpuQuota >= 1000 && vcpuQuota <= static_cast(ULLONG_MAX / 1000))); + + if (!lxc::setCgroup(mId, "cpu", "cpu.shares", std::to_string(cpuShares)) || + !lxc::setCgroup(mId, "cpu", "cpu.cfs_period_us", std::to_string(vcpuPeriod)) || + !lxc::setCgroup(mId, "cpu", "cpu.cfs_quota_us", std::to_string(vcpuQuota))) { + + LOGE(mId << ": Error while setting the zone's scheduler params"); + throw ZoneOperationException("Could not set scheduler params"); + } } } // namespace vasum diff --git a/server/zone.hpp b/server/zone.hpp index fb9f0c7..0829c35 100644 --- a/server/zone.hpp +++ b/server/zone.hpp @@ -27,9 +27,11 @@ #define SERVER_ZONE_HPP #include "zone-config.hpp" -#include "zone-admin.hpp" #include "zone-provision.hpp" +#include "lxc/zone.hpp" +#include "netdev.hpp" + #include #include #include @@ -40,9 +42,16 @@ namespace vasum { +enum class SchedulerLevel { + FOREGROUND, + BACKGROUND +}; + class Zone { public: + typedef netdev::Attrs NetdevAttrs; + /** * Zone constructor * @param zoneId zone id @@ -60,6 +69,7 @@ public: const std::string& baseRunMountPointPath); Zone(const Zone&) = delete; Zone& operator=(const Zone&) = delete; + ~Zone(); typedef std::function StartAsyncResultCallback; @@ -75,8 +85,6 @@ public: */ const std::vector& getPermittedToRecv() const; - // ZoneAdmin API - /** * Get the zone id */ @@ -124,8 +132,6 @@ public: /** * Set if zone should be detached on exit. - * - * This sends detach flag to ZoneAdmin object. */ void setDetachOnExit(); @@ -149,7 +155,10 @@ public: bool isStopped(); /** - * Suspend zone. + * Suspends an active zone, the process is frozen + * without further access to CPU resources and I/O, + * but the memory used by the zone + * at the hypervisor level will stay allocated */ void suspend(); @@ -235,12 +244,12 @@ public: /** * Set network device attributes */ - void setNetdevAttrs(const std::string& netdev, const ZoneAdmin::NetdevAttrs& attrs); + void setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs); /** * Get network device attributes */ - ZoneAdmin::NetdevAttrs getNetdevAttrs(const std::string& netdev); + NetdevAttrs getNetdevAttrs(const std::string& netdev); /** * Get network device list @@ -252,21 +261,36 @@ public: */ void deleteNetdevIpAddress(const std::string& netdev, const std::string& ip); + /** + * Sets the zones scheduler CFS quota. + */ + void setSchedulerLevel(SchedulerLevel sched); + + /** + * @return Scheduler CFS quota, + * TODO: this function is only for UNIT TESTS + */ + std::int64_t getSchedulerQuota(); + private: ZoneConfig mConfig; ZoneDynamicConfig mDynamicConfig; std::vector mPermittedToSend; std::vector mPermittedToRecv; - std::unique_ptr mAdmin; std::unique_ptr mProvision; mutable std::recursive_mutex mReconnectMutex; std::string mRunMountPoint; std::string mRootPath; std::string mDbPath; + lxc::LxcZone mZone; + const std::string mId; + bool mDetachOnExit; + bool mDestroyOnExit; void onNameLostCallback(); void saveDynamicConfig(); void updateRequestedState(const std::string& state); + void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota); }; diff --git a/server/zones-manager.cpp b/server/zones-manager.cpp index 7e0f641..a34dbe9 100644 --- a/server/zones-manager.cpp +++ b/server/zones-manager.cpp @@ -27,7 +27,6 @@ #include "common-definitions.hpp" #include "dynamic-config-scheme.hpp" #include "zones-manager.hpp" -#include "zone-admin.hpp" #include "lxc/cgroup.hpp" #include "exception.hpp" diff --git a/tests/unit_tests/server/ut-zone-admin.cpp b/tests/unit_tests/server/ut-zone-admin.cpp deleted file mode 100644 index faee59a..0000000 --- a/tests/unit_tests/server/ut-zone-admin.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Jan Olszak - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - - -/** - * @file - * @author Jan Olszak (j.olszak@samsung.com) - * @brief Unit tests of the ZoneAdmin class - */ - -#include "config.hpp" -#include "ut.hpp" - -#include "zone-admin.hpp" -#include "exception.hpp" - -#include "utils/glib-loop.hpp" -#include "utils/scoped-dir.hpp" -#include "config/manager.hpp" - -using namespace vasum; - -namespace { - -const std::string TEMPLATES_DIR = VSM_TEST_TEMPLATES_INSTALL_DIR; -const std::string TEST_CONFIG_PATH = TEMPLATES_DIR + "/default.conf"; -const std::string TEST_NO_SHUTDOWN_CONFIG_PATH = TEMPLATES_DIR + "/test-no-shutdown.conf"; -const std::string BUGGY_CONFIG_PATH = TEMPLATES_DIR + "/buggy-init.conf"; -const std::string MISSING_CONFIG_PATH = TEMPLATES_DIR + "/missing.conf"; -const std::string ZONES_PATH = "/tmp/ut-zones"; - -struct Fixture { - utils::ScopedGlibLoop mLoop; - utils::ScopedDir mZonesPathGuard; - - ZoneConfig mConfig; - ZoneDynamicConfig mDynamicConfig; - - Fixture() - : mZonesPathGuard(ZONES_PATH) - {} - - std::unique_ptr create(const std::string& configPath) - { - config::loadFromJsonFile(configPath, mConfig); - config::loadFromJsonFile(configPath, mDynamicConfig); - return std::unique_ptr(new ZoneAdmin("zoneId", - ZONES_PATH, - TEMPLATES_DIR, - mConfig, - mDynamicConfig)); - } - - void ensureStarted() - { - // wait for zones init to fully start - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } -}; - -} // namespace - - -BOOST_FIXTURE_TEST_SUITE(ZoneAdminSuite, Fixture) - -BOOST_AUTO_TEST_CASE(ConstructorDestructor) -{ - auto admin = create(TEST_CONFIG_PATH); - admin.reset(); -} - -BOOST_AUTO_TEST_CASE(MissingConfig) -{ - BOOST_REQUIRE_EXCEPTION(create(MISSING_CONFIG_PATH), - ZoneOperationException, - WhatEquals("Could not create zone")); -} - -BOOST_AUTO_TEST_CASE(Start) -{ - auto admin = create(TEST_CONFIG_PATH); - - admin->start(); - ensureStarted(); - - BOOST_CHECK(admin->isRunning()); -} - -BOOST_AUTO_TEST_CASE(StartBuggy) -{ - auto admin = create(BUGGY_CONFIG_PATH); - BOOST_REQUIRE_EXCEPTION(admin->start(), - ZoneOperationException, - WhatEquals("Could not start zone")); -} - -BOOST_AUTO_TEST_CASE(StopShutdown) -{ - auto admin = create(TEST_CONFIG_PATH); - - admin->start(); - ensureStarted(); - BOOST_REQUIRE(admin->isRunning()); - - admin->stop(); - BOOST_CHECK(!admin->isRunning()); - BOOST_CHECK(admin->isStopped()); -} - -// This test needs to wait for a shutdown timer in stop() method. This takes 10s+. -BOOST_AUTO_TEST_CASE(StopDestroy) -{ - auto admin = create(TEST_NO_SHUTDOWN_CONFIG_PATH); - - admin->start(); - ensureStarted(); - BOOST_REQUIRE(admin->isRunning()); - - admin->stop(); - BOOST_CHECK(!admin->isRunning()); - BOOST_CHECK(admin->isStopped()); -} - -BOOST_AUTO_TEST_CASE(SuspendResume) -{ - auto admin = create(TEST_NO_SHUTDOWN_CONFIG_PATH); - - admin->start(); - ensureStarted(); - BOOST_REQUIRE(admin->isRunning()); - - admin->suspend(); - BOOST_CHECK(!admin->isRunning()); - BOOST_CHECK(!admin->isStopped()); - BOOST_CHECK(admin->isPaused()); - - admin->resume(); - BOOST_CHECK(!admin->isPaused()); - BOOST_CHECK(!admin->isStopped()); - BOOST_CHECK(admin->isRunning()); -} - -BOOST_AUTO_TEST_CASE(ForegroundBackgroundSchedulerLevel) -{ - auto admin = create(TEST_CONFIG_PATH); - - BOOST_REQUIRE(mConfig.cpuQuotaForeground != mConfig.cpuQuotaBackground); - - admin->start(); - ensureStarted(); - - admin->setSchedulerLevel(SchedulerLevel::FOREGROUND); - BOOST_CHECK_EQUAL(admin->getSchedulerQuota(), mConfig.cpuQuotaForeground); - - admin->setSchedulerLevel(SchedulerLevel::BACKGROUND); - BOOST_CHECK_EQUAL(admin->getSchedulerQuota(), mConfig.cpuQuotaBackground); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/unit_tests/server/ut-zone.cpp b/tests/unit_tests/server/ut-zone.cpp index abc10dc..1da6190 100644 --- a/tests/unit_tests/server/ut-zone.cpp +++ b/tests/unit_tests/server/ut-zone.cpp @@ -33,6 +33,7 @@ #include "utils/exception.hpp" #include "utils/glib-loop.hpp" #include "utils/scoped-dir.hpp" +#include "config/manager.hpp" #include "config/exception.hpp" #include "netdev.hpp" @@ -54,8 +55,10 @@ namespace { const std::string TEMPLATES_DIR = VSM_TEST_TEMPLATES_INSTALL_DIR; const std::string TEST_CONFIG_PATH = TEMPLATES_DIR + "/default.conf"; +const std::string TEST_NO_SHUTDOWN_CONFIG_PATH = TEMPLATES_DIR + "/test-no-shutdown.conf"; const std::string TEST_DBUS_CONFIG_PATH = TEMPLATES_DIR + "/console-dbus.conf"; const std::string BUGGY_CONFIG_PATH = TEMPLATES_DIR + "/buggy-template.conf"; +const std::string BUGGY_INIT_CONFIG_PATH = TEMPLATES_DIR + "/buggy-init.conf"; const std::string MISSING_CONFIG_PATH = TEMPLATES_DIR + "/missing-config.conf"; const std::string ZONES_PATH = "/tmp/ut-zones"; const std::string DB_PATH = ZONES_PATH + "/vasum.db"; @@ -144,6 +147,78 @@ BOOST_AUTO_TEST_CASE(StartStop) c->stop(true); } +BOOST_AUTO_TEST_CASE(StartBuggyInit) +{ + auto c = create(BUGGY_INIT_CONFIG_PATH); + BOOST_REQUIRE_EXCEPTION(c->start(), + ZoneOperationException, + WhatEquals("Could not start zone")); +} + +BOOST_AUTO_TEST_CASE(StopShutdown) +{ + auto c = create(TEST_CONFIG_PATH); + + c->start(); + ensureStarted(); + BOOST_REQUIRE(c->isRunning()); + + c->stop(true); + BOOST_CHECK(!c->isRunning()); + BOOST_CHECK(c->isStopped()); +} + +// This test needs to wait for a shutdown timer in stop() method. This takes 10s+. +BOOST_AUTO_TEST_CASE(StopDestroy) +{ + auto c = create(TEST_NO_SHUTDOWN_CONFIG_PATH); + + c->start(); + ensureStarted(); + BOOST_REQUIRE(c->isRunning()); + + c->stop(true); + BOOST_CHECK(!c->isRunning()); + BOOST_CHECK(c->isStopped()); +} + +BOOST_AUTO_TEST_CASE(SuspendResume) +{ + auto c = create(TEST_NO_SHUTDOWN_CONFIG_PATH); + + c->start(); + ensureStarted(); + BOOST_REQUIRE(c->isRunning()); + + c->suspend(); + BOOST_CHECK(!c->isRunning()); + BOOST_CHECK(!c->isStopped()); + BOOST_CHECK(c->isPaused()); + + c->resume(); + BOOST_CHECK(!c->isPaused()); + BOOST_CHECK(!c->isStopped()); + BOOST_CHECK(c->isRunning()); +} + +BOOST_AUTO_TEST_CASE(ForegroundBackgroundSchedulerLevel) +{ + auto c = create(TEST_CONFIG_PATH); + ZoneConfig refConfig; + config::loadFromJsonFile(TEST_CONFIG_PATH, refConfig); + + BOOST_REQUIRE(refConfig.cpuQuotaForeground != refConfig.cpuQuotaBackground); + + c->start(); + ensureStarted(); + + c->setSchedulerLevel(SchedulerLevel::FOREGROUND); + BOOST_CHECK_EQUAL(c->getSchedulerQuota(), refConfig.cpuQuotaForeground); + + c->setSchedulerLevel(SchedulerLevel::BACKGROUND); + BOOST_CHECK_EQUAL(c->getSchedulerQuota(), refConfig.cpuQuotaBackground); +} + BOOST_AUTO_TEST_CASE(DbusConnection) { mRunGuard.create("/tmp/ut-run"); // the same path as in zone template @@ -214,7 +289,7 @@ BOOST_AUTO_TEST_CASE(GetNetdevAttrs) c->start(); ensureStarted(); c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); - ZoneAdmin::NetdevAttrs attrs = c->getNetdevAttrs(ZONE_NETDEV); + Zone::NetdevAttrs attrs = c->getNetdevAttrs(ZONE_NETDEV); bool gotMtu = false; bool gotFlags = false; bool gotType = false; @@ -246,12 +321,12 @@ BOOST_AUTO_TEST_CASE(SetNetdevAttrs) c->start(); ensureStarted(); c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); - ZoneAdmin::NetdevAttrs attrsIn; + Zone::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); + Zone::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); for (auto& attr : attrsOut) { if (std::get<0>(attr) == "mtu") { BOOST_CHECK(!gotMtu); @@ -275,11 +350,11 @@ BOOST_AUTO_TEST_CASE(SetNetdevIpv4) c->start(); ensureStarted(); c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); - ZoneAdmin::NetdevAttrs attrsIn; + Zone::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); + Zone::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); int gotIp = 0; for (auto& attr : attrsOut) { if (std::get<0>(attr) == "ipv4") { @@ -315,11 +390,11 @@ BOOST_AUTO_TEST_CASE(SetNetdevIpv6) c->start(); ensureStarted(); c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); - ZoneAdmin::NetdevAttrs attrsIn; + Zone::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); + Zone::NetdevAttrs attrsOut = c->getNetdevAttrs(ZONE_NETDEV); int gotIp = 0; for (auto& attr : attrsOut) { if (std::get<0>(attr) == "ipv6") { @@ -350,10 +425,10 @@ BOOST_AUTO_TEST_CASE(SetNetdevIpv6) BOOST_AUTO_TEST_CASE(DelNetdevIpAddress) { - auto contain = [](const ZoneAdmin::NetdevAttrs& container, const std::string& key) { + auto contain = [](const Zone::NetdevAttrs& container, const std::string& key) { return container.end() != find_if(container.begin(), container.end(), - [&](const ZoneAdmin::NetdevAttrs::value_type& value) { + [&](const Zone::NetdevAttrs::value_type& value) { return std::get<0>(value) == key; }); }; @@ -363,7 +438,7 @@ BOOST_AUTO_TEST_CASE(DelNetdevIpAddress) c->start(); ensureStarted(); c->createNetdevVeth(ZONE_NETDEV, BRIDGE_NAME); - ZoneAdmin::NetdevAttrs attrs; + Zone::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); -- 2.7.4