Vasum Wrapper: wrap old api client library #2 89/38889/16
authorKrzysztof Dynowski <k.dynowski@samsung.com>
Tue, 21 Apr 2015 14:54:03 +0000 (16:54 +0200)
committerKrzysztof Dynowski <k.dynowski@samsung.com>
Fri, 8 May 2015 16:01:05 +0000 (18:01 +0200)
[Bug/Feature]   Old API wrapper
[Cause]         wrap to vasum lib
[Solution]      #2 binary compatible wrapper
[Verification]  Build, install on target, check journal

Change-Id: Ifadee97d41189937aacc1723f2890bb5904c6851

15 files changed:
cli/CMakeLists.txt
client/CMakeLists.txt
client/host-ipc-connection.cpp
client/host-ipc-connection.hpp
client/vasum-client-impl.cpp
client/vasum-client-impl.hpp
client/vasum-client.h
client/vasum-wrapper.cpp [new file with mode: 0644]
client/vasum.h
client/vasum_list.h [moved from client/sc_adt.h with 81% similarity]
client/wrapper-compat.cpp [new file with mode: 0644]
client/wrapper-compat.h [new file with mode: 0644]
common/epoll/event-poll.cpp
packaging/vasum.spec
tests/unit_tests/CMakeLists.txt

index 2ffdcc4..957faff 100644 (file)
@@ -31,7 +31,7 @@ PKG_CHECK_MODULES(LIB_DEPS REQUIRED vasum)
 
 INCLUDE_DIRECTORIES(${CLIENT_FOLDER})
 INCLUDE_DIRECTORIES(${COMMON_FOLDER})
-TARGET_LINK_LIBRARIES(${CLI_CODENAME} ${LIB_DEPS_LIBRARIES} ${PROJECT_NAME})
+TARGET_LINK_LIBRARIES(${CLI_CODENAME} ${PROJECT_NAME}-client ${LIB_DEPS_LIBRARIES})
 
 CONFIGURE_FILE(support/vasum-cli-completion.sh.in
                ${CMAKE_BINARY_DIR}/vasum-cli-completion.sh
index 753b7c4..e366e3c 100644 (file)
 
 MESSAGE(STATUS "")
 MESSAGE(STATUS "Generating makefile for the Client...")
+## set client library sources (without vasum-wrapper.cpp)
 FILE(GLOB project_SRCS *.cpp *.hpp *.h)
+FILE(GLOB project_SRCS_rm vasum-wrapper.cpp)
+LIST(REMOVE_ITEM project_SRCS ${project_SRCS_rm})
+
+## set wrapper library sources (without vasum-client.cpp)
+FILE(GLOB wrapper_SRCS *.cpp *.hpp *.h)
+FILE(GLOB wrapper_SRCS_rm vasum-client.cpp)
+LIST(REMOVE_ITEM wrapper_SRCS ${wrapper_SRCS_rm})
+
 FILE(GLOB common_SRCS ${COMMON_FOLDER}/epoll/*.hpp              ${COMMON_FOLDER}/epoll/*.cpp
                       ${COMMON_FOLDER}/ipc/*.hpp                ${COMMON_FOLDER}/ipc/*.cpp
                       ${COMMON_FOLDER}/ipc/internals/*.hpp      ${COMMON_FOLDER}/ipc/internals/*.cpp
                       ${COMMON_FOLDER}/utils/*.hpp              ${COMMON_FOLDER}/utils/*.cpp
                       ${COMMON_FOLDER}/*.hpp                    ${COMMON_FOLDER}/*.cpp)
 
-SET(_LIB_VERSION_ "0.0.1")
+## set version highier then vasum.so.0.1.0
+SET(_LIB_VERSION_ "0.1.1")
 SET(_LIB_SOVERSION_ "0")
 SET(PC_FILE "${PROJECT_NAME}.pc")
 
@@ -37,7 +47,13 @@ SET(PC_FILE "${PROJECT_NAME}.pc")
 ADD_DEFINITIONS(-fvisibility=hidden)
 
 ## Setup target ################################################################
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${project_SRCS} ${common_SRCS})
+ADD_LIBRARY(${PROJECT_NAME}-client SHARED ${project_SRCS} ${common_SRCS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME}-client PROPERTIES
+        SOVERSION ${_LIB_SOVERSION_}
+        VERSION ${_LIB_VERSION_}
+        COMPILE_DEFINITIONS HOST_IPC_SOCKET="${VSM_SERVER_IPC_SOCKET_PATH}")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${wrapper_SRCS} ${common_SRCS})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
         SOVERSION ${_LIB_SOVERSION_}
         VERSION ${_LIB_VERSION_}
@@ -50,6 +66,8 @@ INCLUDE_DIRECTORIES(SYSTEM ${LIB_DEPS_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES(${COMMON_FOLDER})
 INCLUDE_DIRECTORIES(${LIBS_FOLDER})
 INCLUDE_DIRECTORIES(${SERVER_FOLDER})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}-client ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES}
+                      Config SimpleDbus)
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIB_DEPS_LIBRARIES} ${Boost_LIBRARIES}
                       Config SimpleDbus)
 
@@ -61,9 +79,9 @@ CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY)
 INSTALL(FILES       ${CMAKE_BINARY_DIR}/${PC_FILE}
         DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
-INSTALL(TARGETS     ${PROJECT_NAME}
+INSTALL(TARGETS     ${PROJECT_NAME}-client ${PROJECT_NAME}
         DESTINATION ${CMAKE_INSTALL_LIBDIR}
         COMPONENT   RuntimeLibraries)
 
-INSTALL(FILES       vasum-client.h
+INSTALL(FILES       vasum-client.h vasum.h vasum_list.h
         DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME})
index 6541881..11741f6 100644 (file)
@@ -36,6 +36,10 @@ void HostIPCConnection::createSystem()
     mClient.reset(new ipc::Client(mDispatcher.getPoll(), HOST_IPC_SOCKET));
     mClient->start();
 }
+epoll::ThreadDispatcher& HostIPCConnection::getDispatcher()
+{
+    return mDispatcher;
+}
 
 void HostIPCConnection::create(const std::string& address)
 {
index 8fa6e06..39015f4 100644 (file)
@@ -44,6 +44,7 @@ public:
     typedef std::function<void(const vasum::api::Notification&)> NotificationCallback;
     void createSystem();
     void create(const std::string& address);
+    epoll::ThreadDispatcher& getDispatcher();
 
     void callGetZoneIds(vasum::api::ZoneIds& argOut);
     void callGetActiveZoneId(vasum::api::ZoneId& argOut);
index 8866e5f..9694dd3 100644 (file)
@@ -28,6 +28,7 @@
 #include "utils.hpp"
 #include "exception.hpp"
 #include "host-ipc-connection.hpp"
+#include "logger/logger.hpp"
 
 #include <algorithm>
 #include <vector>
@@ -176,6 +177,9 @@ VsmStatus Client::coverException(const function<void(void)>& worker) noexcept
     } catch (const exception& ex) {
         mStatus = Status(VSMCLIENT_CUSTOM_ERROR, ex.what());
     }
+    if (mStatus.mVsmStatus!=VSMCLIENT_SUCCESS) {
+        LOGE("Exception: " << mStatus.mMsg);
+    }
     return mStatus.mVsmStatus;
 }
 
@@ -193,6 +197,11 @@ VsmStatus Client::create(const string& address) noexcept
     });
 }
 
+epoll::EventPoll& Client::getEventPoll() noexcept
+{
+    return mHostClient.getDispatcher().getPoll();
+}
+
 const char* Client::vsm_get_status_message() const noexcept
 {
     return mStatus.mMsg.c_str();
@@ -338,7 +347,7 @@ VsmStatus Client::vsm_unlock_zone(const char* id) noexcept
     });
 }
 
-VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateCallback /* zoneDbusStateCallback */,
+VsmStatus Client::vsm_add_state_callback(VsmZoneDbusStateFunction /* zoneDbusStateCallback */,
                                     void* /* data */,
                                     VsmSubscriptionId* /* subscriptionId */) noexcept
 {
@@ -710,7 +719,7 @@ VsmStatus Client::vsm_file_move_request(const char* /*destZone*/, const char* /*
     });
 }
 
-VsmStatus Client::vsm_add_notification_callback(VsmNotificationCallback /*notificationCallback*/,
+VsmStatus Client::vsm_add_notification_callback(VsmNotificationFunction /*notificationCallback*/,
                                            void* /*data*/,
                                            VsmSubscriptionId* /*subscriptionId*/) noexcept
 {
index 3f3b13a..da6dc8f 100644 (file)
 #include <linux/if_link.h>
 
 /**
+ * Zone's D-Bus state change callback function signature.
+ *
+ * @param[in] zoneId affected zone id
+ * @param[in] dbusAddress new D-Bus address
+ * @param data custom user's data pointer passed to vsm_add_state_callback() function
+ */
+typedef std::function<void (const char *zoneId, const char *dbusAddress, void *data)> VsmZoneDbusStateFunction;
+
+/**
+ * Notification callback function signature.
+ *
+ * @param[in] zone source zone
+ * @param[in] application sending application name
+ * @param[in] message notification message
+ * @param data custom user's data pointer passed to vsm_add_notification_callback()
+ */
+typedef std::function<void(const char *zone, const char *application, const char *message, void *data)>
+    VsmNotificationFunction;
+
+/**
  * vasum's client definition.
  *
  * Client uses dbus API.
@@ -49,6 +69,8 @@ public:
      */
     VsmStatus createSystem() noexcept;
 
+    vasum::epoll::EventPoll& getEventPoll() noexcept;
+
     /**
      * Create client.
      *
@@ -135,7 +157,7 @@ public:
     /**
      *  @see ::vsm_add_state_callback
      */
-    VsmStatus vsm_add_state_callback(VsmZoneDbusStateCallback zoneDbusStateCallback,
+    VsmStatus vsm_add_state_callback(VsmZoneDbusStateFunction zoneDbusStateCallback,
                                      void* data,
                                      VsmSubscriptionId* subscriptionId) noexcept;
 
@@ -300,7 +322,7 @@ public:
     /**
      *  @see ::vsm_add_notification_callback
      */
-    VsmStatus vsm_add_notification_callback(VsmNotificationCallback notificationCallback,
+    VsmStatus vsm_add_notification_callback(VsmNotificationFunction notificationCallback,
                                             void* data,
                                             VsmSubscriptionId* subscriptionId) noexcept;
 
index 50ed162..1d43094 100644 (file)
@@ -187,6 +187,7 @@ typedef enum {
     VSMFILE_REGULAR
 } VsmFileType;
 
+#ifndef __VASUM_WRAPPER_SOURCE__
 /**
  * Start glib loop.
  *
@@ -831,6 +832,8 @@ VsmStatus vsm_add_notification_callback(VsmClient client,
  */
 VsmStatus vsm_del_notification_callback(VsmClient client, VsmSubscriptionId subscriptionId);
 
+#endif /* __VASUM_WRAPPER_SOURCE__ */
+
 /** @} Zone API */
 
 #ifdef __cplusplus
diff --git a/client/vasum-wrapper.cpp b/client/vasum-wrapper.cpp
new file mode 100644 (file)
index 0000000..2cbe806
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Krzysztof Dynowski <k.dynowski@samsung.com>
+ *
+ *  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  Krzysztof Dynowski (k.dynowski@samsung.com)
+ * @brief   Vasum old API wrapper to slp client lib
+ */
+
+#define __VASUM_WRAPPER_SOURCE__
+#include <vector>
+#include <string.h>
+#include <algorithm>
+
+#include "config.hpp"
+#include "logger/logger.hpp"
+#include "logger/backend-journal.hpp"
+
+#include "wrapper-compat.h"
+#include "vasum-client-impl.hpp"
+
+#define MAX_EPOLL_EVENTS 16
+
+struct WrappedZone
+{
+    Client *client;
+    VsmZone zone;
+    struct vsm_zone vz;
+    std::vector<vsm_netdev> netdevs;
+};
+
+struct WrappedContext
+{
+    Client *client;
+    vsm_context hq_ctx;
+    struct vsm_zone hq_root;
+    std::vector<WrappedZone> zones;
+};
+
+static struct
+{
+    int done;
+    int glib_stop;
+}wrap;
+
+#ifndef offsetof
+#define offsetof(type, memb) ((size_t)&((type *)0)->memb)
+#endif
+#ifdef container_of
+#undef container_of
+#endif
+#ifndef container_of
+#define container_of(ptr, type, memb) (\
+    (type *)((char *)(ptr) - offsetof(type, memb)))
+#endif
+
+#define UNUSED(x) ((void)(x))
+
+#define vsm_error_t vsm_error_s
+#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);
+static void init_wrapper();
+extern struct vasum_ops dummy_ops;
+
+using namespace logger;
+void wrapper_load(void)
+{
+    Logger::setLogLevel(LogLevel::TRACE);
+    Logger::setLogBackend(new SystemdJournalBackend());
+    init_wrapper();
+}
+
+void wrapper_unload(void)
+{
+    if (wrap.glib_stop) Client::vsm_stop_glib_loop();
+    wrap.glib_stop = 0;
+}
+
+static void callcheck()
+{
+    init_wrapper();
+}
+
+void init_wrapper()
+{
+    if (wrap.done) return ;
+    memset(&wrap,0,sizeof(wrap));
+    wrap.done = 1;
+    LOGS("");
+}
+
+static struct vsm_zone* wrap_vsm_zone(WrappedContext *w, VsmZone zone, bool create = false)
+{
+    if (zone == NULL) {
+        return NULL;
+    }
+    for (auto& zw : w->zones) {
+        if (zw.zone == zone) {
+            return &zw.vz;
+        }
+    }
+    if (create) {
+        w->zones.push_back(WrappedZone());
+        WrappedZone& zw = w->zones.back();
+        zw.client = w->client;
+        zw.zone = zone;
+        zw.vz.name = zone->id;
+        zw.vz.type = NULL;
+        zw.vz.user_data = NULL;
+        zw.vz.rootfs_path = zone->rootfs_path;
+        zw.vz.parent = &zw.vz;
+        LOGI("return (create) zone " << zone->id);
+        return &w->zones.back().vz;
+    }
+    LOGE("return zone NULL");
+    return NULL;
+}
+
+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"));
+    switch (st) {
+        case VSMCLIENT_SUCCESS: return VSM_ERROR_NONE;
+        case VSMCLIENT_CUSTOM_ERROR: return -VSM_ERROR_GENERIC;
+        case VSMCLIENT_IO_ERROR: return -VSM_ERROR_IO;
+        case VSMCLIENT_OPERATION_FAILED: return -VSM_ERROR_NOT_PERMITTED;
+        case VSMCLIENT_INVALID_ARGUMENT: return -VSM_ERROR_INVALID;
+        case VSMCLIENT_OTHER_ERROR: return -VSM_ERROR_GENERIC;
+    }
+    return -VSM_ERROR_GENERIC;
+}
+
+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);
+
+    memset(&w->hq_ctx, 0, sizeof(w->hq_ctx));
+    memset(&w->hq_root, 0, sizeof(w->hq_root));
+
+    vsm_context *ctx = &w->hq_ctx;
+    adt_init_list(&ctx->listeners);
+    //init root_zone
+    ctx->root_zone = &w->hq_root;
+    ctx->root_zone->name = (char*)"";
+    ctx->root_zone->id=0;
+    ctx->root_zone->rootfs_path = (char*)"/";
+
+    ctx->root_zone->terminal = -1;
+    ctx->root_zone->state = VSM_ZONE_STATE_RUNNING;
+    ctx->root_zone->user_data = ctx->root_zone;
+
+    ctx->root_zone->parent = ctx->root_zone;
+    ctx->root_zone->ctx = ctx;
+
+    pthread_rwlock_init(&ctx->root_zone->lock, NULL);
+    adt_init_list(&ctx->root_zone->netdevs);
+    adt_init_list(&ctx->root_zone->devices);
+    adt_init_list(&ctx->root_zone->children);
+
+    pthread_rwlock_init(&ctx->lock, NULL);
+    adt_init_list(&ctx->listeners);
+    adt_init_list(&ctx->sc_listeners);
+    adt_init_list(&ctx->ev_listeners);
+
+    //struct mainloop *mainloop = mainloop_create();
+    //struct mxe_engine *engine = mxe_prepare_engine(mainloop, ctx);
+    //struct mxe_endpoint *ep = mxe_create_client(engine, SERVICEPATH);
+
+    ctx->foreground_zone = ctx->root_zone;
+    ctx->vsm_ops = &dummy_ops;
+    ctx->error = VSM_ERROR_NONE;
+    //ctx->data = ep;
+}
+
+API struct vsm_context *vsm_create_context(void)
+{
+    LOGS(""); callcheck();
+    WrappedContext *w = new WrappedContext();
+    init_context_wrap(w);
+
+    vsm_context *ctx = &w->hq_ctx;
+    return ctx;
+}
+
+API int vsm_cleanup_context(struct vsm_context *ctx)
+{
+    LOGS(""); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    if (w->client != NULL) {
+        delete w->client;
+        w->client = NULL;
+    }
+    for (auto& zw : w->zones) {
+        zw.netdevs.clear();
+    }
+    w->zones.clear();
+    delete w;
+    return VSM_ERROR_NONE;
+}
+
+static const char *const vsm_error_strtab[] = {
+    "No error",
+    "Undefined error",
+    "Invalid",
+    "Operation cancelled",
+    "Operation aborted",
+    "Connection refused",
+    "Object exists",
+    "Resource busy",
+    "Input/Output error",
+    "Timeout",
+    "Overflow",
+    "Out of memory",
+    "Out of range",
+    "Operation not permitted",
+    "Function not implemented",
+    "Operation not supported",
+    "Access denied",
+    "No object found",
+    "Bad state"
+};
+
+API vsm_error_e vsm_last_error(struct vsm_context *ctx)
+{
+    if (ctx)
+        return ctx->error;
+    return static_cast<vsm_error_e>(-1);
+}
+
+API const char *vsm_error_string(vsm_error_e error)
+{
+    LOGS(""); callcheck();
+    if (error < 0 || error > VSM_MAX_ERROR) {
+        return NULL;
+    }
+    return vsm_error_strtab[error];
+}
+
+API int vsm_get_poll_fd(struct vsm_context *ctx)
+{
+    LOGS(""); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(w);
+    //FIXME Client should create Dispatcher and pass to IPCConnection
+    //      now: IPCConnection has field ThreadWrapper
+    //return w->client->getEventPoll().getPollFD();
+    return -1;
+}
+API int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout)
+{
+    LOGS(""); callcheck();
+    UNUSED(flags);
+    UNUSED(timeout);
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(w);
+    //FIXME Client should create Dispatcher and pass to IPCConnection
+    //      now: IPCConnection has field ThreadWrapper
+    //TODO Use EventPoll from Dispatcher
+    return 0;
+}
+
+API int vsm_create_zone(struct vsm_context *ctx, const char *zone_name, const char *template_name, int flag)
+{
+    LOGS("create_zone " << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(flag);
+    //template_name = NULL; //template name not supported by libvasum-client
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_create_zone(zone_name, template_name);
+    if (st != VSMCLIENT_SUCCESS) {
+        LOGE("vsm_create_zone(" << zone_name << ") = " << st);
+    }
+    return wrap_error(st, w->client);
+}
+
+API int vsm_destroy_zone(struct vsm_context *ctx, const char *zone_name, int force)
+{
+    LOGS("zone=" << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(force);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_destroy_zone(zone_name);
+    if (st == VSMCLIENT_SUCCESS) {
+        auto zonebyname = [zone_name](const WrappedZone& v) {return v.zone->id == zone_name;};
+        auto zonelist = std::remove_if(w->zones.begin(), w->zones.end(), zonebyname);
+        w->zones.erase(zonelist);
+    }
+    return wrap_error(st, w->client);
+}
+
+API int vsm_start_zone(struct vsm_context *ctx, const char *zone_name)
+{
+    LOGS("zone=" << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_start_zone(zone_name);
+    return wrap_error(st, w->client);
+}
+
+API int vsm_shutdown_zone(struct vsm_context *ctx, const char *zone_name, int force)
+{
+    LOGS("zone=" << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(force);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_shutdown_zone(zone_name);
+    return wrap_error(st, w->client);
+}
+
+API int vsm_lock_zone(struct vsm_context *ctx, const char *zone_name, int shutdown)
+{
+    LOGS("zone=" << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    UNUSED(shutdown);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_lock_zone(zone_name);
+    return wrap_error(st, w->client);
+}
+
+API int vsm_unlock_zone(struct vsm_context *ctx, const char *zone_name)
+{
+    LOGS("zone=" << zone_name); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_lock_zone(zone_name);
+    return wrap_error(st, w->client);
+}
+
+API int vsm_set_foreground(struct vsm_zone *zone)
+{
+    LOGS(""); callcheck();
+    WrappedZone *w = container_of(zone, WrappedZone, vz);
+    if (!w->client) return VSM_ERROR_GENERIC;
+    VsmStatus st = w->client->vsm_set_active_zone(zone->name);
+    return wrap_error(st, w->client);
+}
+
+//execute command in specified zone
+API int vsm_attach_zone(struct vsm_context *ctx,
+                        const char *zone_name,
+                        vsm_attach_command_t *command,
+                        vsm_attach_options_t *opts,
+                        pid_t *attached_process)
+{
+    return ctx->vsm_ops->attach_zone(ctx, zone_name, command, opts,
+                     attached_process);
+}
+
+//execute command in specified zone and wait
+API int vsm_attach_zone_wait(struct vsm_context *ctx,
+                             const char *zone_name,
+                             vsm_attach_command_t *command,
+                             vsm_attach_options_t *opts)
+{
+    return ctx->vsm_ops->attach_zone_wait(ctx, zone_name, command, opts);
+}
+
+API int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data)
+{
+    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) {
+        callback(&z.vz, user_data);
+    }
+    return 0;
+}
+
+API struct vsm_zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path)
+{
+    LOGS("name=" << path); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    VsmZone zone;
+    if (!w->client) return NULL;
+    //CHECK if path is same as zone_name
+    if (w->client->vsm_lookup_zone_by_id(path, &zone) != VSMCLIENT_SUCCESS)
+        return NULL;
+    return wrap_vsm_zone(w, zone, true);
+}
+
+API struct vsm_zone *vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid)
+{
+    LOGS("pid=" << pid); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    VsmZone zone;
+    VsmString id;
+    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");
+        return NULL;
+    }
+    if (::strcmp(id, "host") == 0) {
+        return w->hq_ctx.root_zone;
+    }
+    w->client->vsm_lookup_zone_by_id(id, &zone); //zone is malloced
+    return wrap_vsm_zone(w, zone);
+}
+
+API struct vsm_zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal)
+{
+    LOGS("terminal=" << terminal); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    VsmZone zone;
+    VsmString id;
+    if (!w->client) return NULL;
+    if (w->client->vsm_lookup_zone_by_terminal_id(terminal, &id) != VSMCLIENT_SUCCESS)
+        return NULL;
+    w->client->vsm_lookup_zone_by_id(id, &zone);
+    return wrap_vsm_zone(w, zone);
+}
+#if 0
+API int vsm_add_state_changed_callback(struct vsm_context *ctx, vsm_zone_state_cb callback, void *user_data)
+{
+    LOGS(""); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    VsmSubscriptionId subscriptionId;
+
+    auto dbus_cb = [=](const char* id, const char* dbusAddress, void* data) ->
+    void {
+        VsmZone zone;
+        //TODO what are valid state, event
+        UNUSED(dbusAddress);
+        w->client->vsm_lookup_zone_by_id(id, &zone);
+        callback(wrap_vsm_zone(w, zone), data);
+    };
+    w->client->vsm_add_state_callback(dbus_cb, user_data, &subscriptionId);
+    return (int)subscriptionId;
+}
+
+API int vsm_del_state_changed_callback(struct vsm_context *ctx, int handle)
+{
+    LOGS(""); callcheck();
+    WrappedContext *w = container_of(ctx, WrappedContext, hq_ctx);
+    VsmSubscriptionId subscriptionId = (VsmSubscriptionId)handle;
+    VsmStatus st = w->client->vsm_del_state_callback(subscriptionId);
+    return wrap_error(st, w->client);
+}
+#endif
+API int vsm_grant_device(struct vsm_zone *dom, const char *name, uint32_t flags)
+{
+    LOGS(""); callcheck();
+    WrappedZone *w = container_of(dom, WrappedZone, vz);
+    const char *id = dom->name;
+    VsmZone zone;
+    w->client->vsm_lookup_zone_by_id(id, &zone);
+    VsmStatus st = w->client->vsm_grant_device(id, name, flags);
+    return wrap_error(st, w->client);
+}
+
+API int vsm_revoke_device(struct vsm_zone *dom, const char *name)
+{
+    LOGS(""); callcheck();
+    WrappedZone *w = container_of(dom, WrappedZone, vz);
+    const char *id = dom->name;
+    VsmStatus st = w->client->vsm_revoke_device(id, name);
+    return wrap_error(st, w->client);
+}
+
+API struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev)
+{
+    LOGS(""); callcheck();
+    UNUSED(zone);
+    UNUSED(type);
+    UNUSED(target);
+    UNUSED(netdev);
+
+    WrappedZone *w = container_of(zone, WrappedZone, vz);
+    const char *id = zone->name;
+    VsmStatus st;
+    if (type == VSM_NETDEV_VETH)
+        st = w->client->vsm_create_netdev_veth(id, target, netdev);
+    else if (type == VSM_NETDEV_PHYS)
+        st = w->client->vsm_create_netdev_phys(id, netdev);
+    else if (type == VSM_NETDEV_MACVLAN) // macvlan_mode from if_link.h
+        st = w->client->vsm_create_netdev_macvlan(id, target, netdev, MACVLAN_MODE_BRIDGE);
+    else {
+        LOGE("Invalid arguments");
+        //ctx->error = VSM_ERROR_INVALID;
+        return NULL;
+    }
+
+    if (st != VSMCLIENT_SUCCESS) {
+        LOGE("vsm_create_netdev(" << netdev << ") = " << st);
+        return NULL;
+    }
+
+    vsm_netdev vnd;
+    vnd.zone = zone;
+    vnd.name = (char*)netdev; //FIXME? copy content of string
+    vnd.type = type;
+    w->netdevs.push_back(vnd); //copy pushed to vector
+    return &w->netdevs.back(); //pointer to struct on vector
+}
+
+API int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev)
+{
+    LOGS(""); 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);
+}
+
+API int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data)
+{
+    LOGS(""); callcheck();
+    WrappedZone *w = container_of(zone, WrappedZone, vz);
+    for (auto nd : w->netdevs) {
+        callback(&nd, user_data);
+    }
+    return 0;
+}
+
+API struct vsm_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name)
+{
+    LOGS(""); callcheck();
+    WrappedZone *w = container_of(zone, WrappedZone, vz);
+    VsmNetdev nd;
+    VsmStatus st = w->client->vsm_lookup_netdev_by_name(zone->name, name, &nd);
+    if (st == VSMCLIENT_SUCCESS) {
+        auto devbyname = [name](const vsm_netdev& v) {return ::strcmp(v.name, name) == 0;};
+        auto devlist = std::find_if(w->netdevs.begin(), w->netdevs.end(), devbyname);
+        if (devlist != w->netdevs.end()) {
+            return &devlist[0];
+        }
+    }
+    return NULL;
+}
+
+API int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode)
+{
+    LOGS(""); callcheck();
+    UNUSED(ctx);
+    UNUSED(ftype);
+    UNUSED(path);
+    UNUSED(flags);
+    UNUSED(mode);
+    //TODO apply declare link for existing zones (and those created in the future, so must store paits source, target)
+    return VSM_ERROR_NONE;
+}
+
+API int vsm_declare_mount(struct vsm_context *ctx,
+                          const char *source,
+                          const char *target,
+                          const char *fstype,
+                          unsigned long flags,
+                          const void *data)
+{
+    LOGS(""); callcheck();
+    UNUSED(ctx);
+    UNUSED(source);
+    UNUSED(target);
+    UNUSED(fstype);
+    UNUSED(flags);
+    UNUSED(data);
+    //TODO apply declare link for existing zones (and those created in the future, so must store paits source, target)
+    return VSM_ERROR_NONE;
+}
+
+API int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target)
+{
+    LOGS("src=" << source << "dst=" << target); callcheck();
+    UNUSED(ctx);
+    UNUSED(source);
+    UNUSED(target);
+    //TODO apply declare link for existing zones (and those created in the future, so must store paits source, target)
+    return VSM_ERROR_NONE;
+}
+
+API int vsm_add_state_changed_callback(vsm_context_h  /*ctx*/, vsm_zone_state_changed_cb  /*callback*/, void * /*user_data*/)
+{
+    return VSM_ERROR_NONE;
+}
+API int vsm_del_state_changed_callback(vsm_context_h  /*ctx*/, int  /*id*/)
+{
+    return VSM_ERROR_NONE;
+}
+API const char * vsm_get_zone_rootpath(vsm_zone_h  /*zone*/)
+{
+    return NULL;
+}
+API const char * vsm_get_zone_name(vsm_zone_h  /*zone*/)
+{
+    return NULL;
+}
+API int vsm_is_host_zone(vsm_zone_h  /*zone*/)
+{
+    return VSM_ERROR_NONE;
+}
+API vsm_zone_h vsm_join_zone(vsm_zone_h  /*zone*/)
+{
+    return NULL;
+}
+API int vsm_canonicalize_path(const char * /*input_path*/, char ** /*output_path*/)
+{
+    return VSM_ERROR_NONE;
+}
+
+
index f7393ff..ae4f37d 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * Container Control Framework
+ * Vasum : Tizen Zone Control Framework
  *
  * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
  * 
- * Contact: Krzysztof Dynowski <k.dynowski@samsung.com>
+ * Contact: Keunhwan Kwak <kh243.kwak@samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
 #include <sys/types.h>
 #include <sys/mount.h>
 
-#include "sc_adt.h"
+#include "vasum_list.h"
 
 #ifndef API
 #define API __attribute__((visibility("default")))
 #ifdef __cplusplus
 extern "C" {
 #endif
-
 /*
  * @file        vasum.h
- * @version     0.2
- * @brief       This file contains APIs of the Container control Framework
+ * @version     0.3
+ * @brief       This file contains APIs of the Zone control Framework
  */
 
 /*
  * <tt>
- *
  * Revision History:
- *
+ *   2014-09-01        sungbae you    First created
+ *   2014-10-07        sungbae you    First doxygen commented
+ *   2015-03-19        kuenhwan Kwak  doxygen revise
  * </tt>
  */
 
 /**
- * @addtogroup ZONE_CONTROL Zone Control
+ * @addtogroup CONTEXT vasum context
  * @{
 */
 
-typedef enum {
-       VSM_ERROR_NONE,                 /* The operation was successful */
-       VSM_ERROR_GENERIC,              /* Non-specific cause */
-       VSM_ERROR_INVALID,              /* Invalid argument */
-       VSM_ERROR_CANCELED,             /* The requested operation was cancelled */
-       VSM_ERROR_ABORTED,              /* Operation aborted */
-       VSM_ERROR_REFUSED,              /* Connection refused */
-       VSM_ERROR_EXIST,                /* Target exists */
-       VSM_ERROR_BUSY,                 /* Resource is busy */
-       VSM_ERROR_IO,                   /* I/O error*/
-       VSM_ERROR_TIMEOUT,              /* Timer expired */
-       VSM_ERROR_OVERFLOW,             /* Value too large to be stored in data type */
-       VSM_ERROR_OUT_OF_MEMORY,        /* No memory space */
-       VSM_ERROR_OUT_OF_RANGE,         /* Input is out of range */
-       VSM_ERROR_NOT_PERMITTED,                /* Operation not permitted */
-       VSM_ERROR_NOT_IMPLEMENTED,      /* Function is not implemented yet */
-       VSM_ERROR_NOT_SUPPORTED,        /* Operation is not supported */
-       VSM_ERROR_ACCESS_DENIED,        /* Access privilege is not sufficient */
-       VSM_ERROR_NO_OBJECT,            /* Object not found */
-       VSM_ERROR_BAD_STATE,            /* Bad state */
-       VSM_MAX_ERROR = VSM_ERROR_BAD_STATE
-}vsm_error_t;
-
 /**
- *@brief struct vsm_context keeps track of an execution state of the container control framework.
+ *@brief vasum handle for interact with vasum server process. This is opaque data type.
  */
-struct vsm_context {
-       /// â€” Used for internal â€”
-       void             *data;
-       /// Error code
-       vsm_error_t     error;
-       /// RWLock for list members
-       pthread_rwlock_t lock;
-       /// List of callback function for changing state
-       struct adt_list listeners;
-       /// Root(host) of zones (except for stopped zones)
-       struct vsm_zone *root_zone;
-       /// Foreground zone 
-       struct vsm_zone *foreground_zone;
-};
-
-/**
- * @brief Get last error string.
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * const char *vsm_error_string(struct vsm_context *ctx);
- * \endcode
- *
- * \par Description:
- * vsm_error_string return last error string for debug or logging.
- *
- * \param[in] ctx vsm context
- *
- * \return string for last error in context.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre None
- *
- * \post None
- *
- * \see struct vsm_context
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- * struct vsm_zone * zone;
- *
- * ctx = vsm_create_context();
- * zone = vsm_lookup_zone_by_pid(ctx, pid);
- * if(zone == NULL)
- * {
- *             fprintf(stderr, "API Failed : %s", vsm_error_string(ctx));
- * }
- * ...
- * \endcode
- *
-*/
-
-API const char *vsm_error_string(struct vsm_context *ctx);
+typedef struct vsm_context* vsm_context_h;
 
 /**
  * @brief Create vsm context
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * struct vsm_context *vsm_create_context(void *)
- * \endcode
- *
  * \par Description:
  * The vsm context is an abstraction of the logical connection between the zone controller and it's clients.
- * The vsm context must be initialized before attempting to use almost any of the APIs,
- * and it should be finalized when interaction with the zone controller is no longer required.\n
- * \n
- * A call to vsm_create_context() makes a connection to zone controller(vsm-zone-svc),
- * and creates a new instance of struct vsm_context called vsm context.\n
- *
- * \param None
- *
- * \return An instance of vsm context on success, or NULL on error (in which case, errno is set appropriately)
- *
+ * and vsm_context_h object should be finalized when interaction with the vasum server is no longer required.\n
+ * \return An instance of vsm context on success, or NULL
+ * \retval vsm_context_h     successful
+ * \retval NULL               get vasum context failed.
  * \par Known issues/bugs:
- * None
- *
- * \pre vsm-zone-svc must be started 
- *
- * \post None
- *
+ *  Only a host process has permission for vsm_create_context();
+ * \pre vsm-zone-svc must be started
  * \see vsm_cleanup_context()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- *
- * ctx = vsm_create_context();
- * if(ctx == NULL)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
 */
-API struct vsm_context *vsm_create_context(void);
+API vsm_context_h vsm_create_context(void);
 
 /**
  * @brief Cleanup zone control context
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_cleanup_context(struct vsm_context *ctx)
- *\endcode
- *
  * \par Description:
  * vsm_cleanup_context() finalizes vsm context and release all resources allocated to the vsm context.\n
- * \n
  * This function should be called if interaction with the zone controller is no longer required.
- *
  * \param[in] ctx vsm context
- *
- * \return 0 on success, or -1 on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post vsm context will not be valid after calling this API
- *
+ * \return #VSM_ERROR_NONE on success.
+ * \pre vsm_context_h must be initialized by vsm_create_context()
+ * \post vsm context_h will not be valid after calling this API
  * \see vsm_create_context()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * retval = vsm_cleanup_context(ctx);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
 */
-API int vsm_cleanup_context(struct vsm_context *ctx);
+API int vsm_cleanup_context(vsm_context_h ctx);
 
 /**
  * @brief Get file descriptor associated with event dispatcher of zone control context
- *
- * \par Synopsis:
- * \code
- * #include <vasum>
- *
- * int vsm_get_poll_fd(struct vsm_context *ctx)
- * \endcode
- *
  * \par Description:
  * The function vsm_get_poll_fd() returns the file descriptor associated with the event dispatcher of vsm context.\n
  * The file descriptor can be bound to another I/O multiplexing facilities like epoll, select, and poll.
- *
  * \param[in] ctx vsm context
- *
- * \return On success, a nonnegative file descriptor is returned. On error -1 is returned.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_enter_eventloop()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int fd;
- * struct vsm_context *ctx;
- * ...
- * fd = vsm_get_poll_fd(ctx);
- * while (1) {
- *     ...
- *     epoll_wait(fd, events, MAX_EPOLL_EVENTS, -1);
- *     ...
- *     if (vsm_enter_eventloop(ctx, 0, 0) < 0)
- *             break;
- *     ...
- * }
- * ...
- * \endcode
- *
+ * \return On success, a nonnegative file descriptor is returned. On negative error code is returned.
+ * \retval fd nonnegative integer fd value for getting vasum event and refresh vsm_context_h.
+ * \retval #VSM_ERROR_INVALID invalid vsm_context_h
+ * \pre vsm_context_h must be initialized by vsm_create_context()
+ * \see vsm_create_context()
 */
-API int vsm_get_poll_fd(struct vsm_context *ctx);
+API int vsm_get_poll_fd(vsm_context_h ctx);
+
 /**
  * @brief Wait for an I/O event on a VSM context
- *
- * \par Synopsis:
- * \code
- * #incldue <vasum.h>
- * 
- * int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout)
- * \endcode
- * 
  * \par Description:
  * vsm_enter_eventloop() waits for event on the vsm context.\n
  *\n
  * The call waits for a maximum time of timout milliseconds. Specifying a timeout of -1 makes vsm_enter_eventloop() wait indefinitely,
  * while specifying a timeout equal to zero makes vsm_enter_eventloop() to return immediately even if no events are available.
- *
  * \param[in] ctx vsm context
  * \param[in] flags Reserved
  * \param[in] timeout Timeout time (milisecond), -1 is infinite
- *
- * \return 0 on success, or -1 on error.
- *
- * \par Known issues/bugs:
- * None
- *
+ * \return 0 on success,  or negative error code.
  * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
  * \see vsm_create_context(), vsm_get_poll_fd()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- * ...
- * while (vsm_enter_eventloop(ctx, 0, -1)) {
- * ...
- * }
- * ...
- * \endcode
- *
 */
-API int vsm_enter_eventloop(struct vsm_context *ctx, int flags, int timeout);
+API int vsm_enter_eventloop(vsm_context_h ctx, int flags, int timeout);
 
 /**
- * @brief Definition for default zone name.
- * Default zone is started at boot sequence by systemd.
+ * @brief Enumeration for vasum error.
+ */
+typedef enum {
+       VSM_ERROR_NONE,                 /**< The operation was successful */
+       VSM_ERROR_GENERIC,              /**< Non-specific cause */
+       VSM_ERROR_INVALID,              /**< Invalid argument */
+       VSM_ERROR_CANCELED,             /**< The requested operation was cancelled */
+       VSM_ERROR_ABORTED,              /**< Operation aborted */
+       VSM_ERROR_REFUSED,              /**< Connection refused */
+       VSM_ERROR_EXIST,                /**< Target exists */
+       VSM_ERROR_BUSY,                 /**< Resource is busy */
+       VSM_ERROR_IO,                   /**< I/O error*/
+       VSM_ERROR_TIMEOUT,              /**< Timer expired */
+       VSM_ERROR_OVERFLOW,             /**< Value too large to be stored in data type */
+       VSM_ERROR_OUT_OF_MEMORY,        /**< No memory space */
+       VSM_ERROR_OUT_OF_RANGE,         /**< Input is out of range */
+       VSM_ERROR_NOT_PERMITTED,                /**< Operation not permitted */
+       VSM_ERROR_NOT_IMPLEMENTED,      /**< Function is not implemented yet */
+       VSM_ERROR_NOT_SUPPORTED,        /**< Operation is not supported */
+       VSM_ERROR_ACCESS_DENIED,        /**< Access privilege is not sufficient */
+       VSM_ERROR_NO_OBJECT,            /**< Object not found */
+       VSM_ERROR_BAD_STATE,            /**< Bad state */
+       VSM_MAX_ERROR = VSM_ERROR_BAD_STATE
+}vsm_error_e;
+
+/**
+ * @brief Get last vasum error code from vsm_context.
+ * \param[in] ctx vsm context
+ * \return vasum error enum value.
+ * \par Known issues/bugs:
+ *     thread non-safe
+ * \see vsm_error_string()
 */
-#define VSM_DEFAULT_ZONE "personal"
+API vsm_error_e vsm_last_error(vsm_context_h ctx);
 
 /**
- * @brief Definition for zone states.
- * This definition shows the available states.
- * Zone is started from VSM_ZONE_STATE_STOPPED state. During start up, zone controller instantiates zone and
- * starts the first process in the zone.
- * Once the first process has started, the state of the zone will not be changed unless
- * the process is killed.
+ * @brief Get vasum error string.
+ * \par Description:
+ * return string pointer for vasum error string.
+ * \param[in] vsm_error_e error.
+ * \return string pointer value represent to error code.
+ * \warning Do not free returned pointer.
 */
+API const char *vsm_error_string(vsm_error_e error);
 
-typedef enum {
-       VSM_ZONE_STATE_STOPPED,
-       VSM_ZONE_STATE_STARTING,
-       VSM_ZONE_STATE_RUNNING,
-       VSM_ZONE_STATE_STOPPING,
-       VSM_ZONE_STATE_ABORTING,
-       VSM_ZONE_STATE_FREEZING,
-       VSM_ZONE_STATE_FROZEN,
-       VSM_ZONE_STATE_THAWED,
-       VSM_ZONE_MAX_STATE = VSM_ZONE_STATE_THAWED
-} vsm_zone_state_t;
+/// @}
 
-typedef enum {
-       VSM_ZONE_EVENT_NONE,
-       VSM_ZONE_EVENT_CREATED,
-       VSM_ZONE_EVENT_DESTROYED,
-       VSM_ZONE_EVENT_SWITCHED,
-       VSM_ZONE_MAX_EVENT = VSM_ZONE_EVENT_SWITCHED
-} vsm_zone_event_t;
+/**
+ * @addtogroup LIFECYCLE Vasum Lifecycle
+ * @{
+ */
 
 /**
- * @brief Zone structure which is used to represent an instance of container.
+ * @brief vsm_zone_h opaque datatype which is used to represent an instance of zone.
  */
-struct vsm_zone {
-       /// Parent
-       struct vsm_zone *parent;
-       /// Name (null-terminated string)
-       char *name;
-       /// Zone type (null-terminated string)
-       char *type;
-       /// Domain's Virtual Terminal number
-       int terminal;
-       /// State
-       vsm_zone_state_t state;
-       /// Container's rootfs path
-       char *rootfs_path;
-       /// RWLock for list members
-       pthread_rwlock_t lock;
-       /// List of child zones
-       struct adt_list children;
-       /// List of devices in zone
-       struct adt_list devices;
-       /// List of network devices in zone
-       struct adt_list netdevs;
-       /// Pointer of user-defined data for clients.
-       void *user_data;
-       ///List head
-       struct adt_list list;
-};
+
+typedef struct vsm_zone* vsm_zone_h;
+
+/**
+ * @brief Definition for default zone name.
+ * Default zone is started at boot sequence by systemd.
+*/
+#define VSM_DEFAULT_ZONE "personal"
+
 
 /**
  * @brief Create a new persistent zone
- *
- * \par Synopsis
- * \code
- * #include <vasum.h>
- *
- * int vsm_create_zone(struct vsm_context *ctx, const char *name, const char *template_name, int flag)
- * \endcode
- *
  * \par Description:
- * vsm_create_zone() triggers zone controller to create new persistent zone.\n
- * \n
+ * vsm_create_zone() triggers zone controller to create new persistent zone.\n\n
  * The zone controller distinguishes two types of zones: peristent and transient.
  * Persistent zones exist indefinitely in storage.
- * While, transient zones are created and started on-the-fly.\n
- * \n
- * Creating zone requires template.
- * In general, creating a zone involves constructing root file filesystem and 
+ * While, transient zones are created and started on-the-fly.\n\n
+ * Creating zone requires template.\n
+ * In general, creating a zone involves constructing root file filesystem and
  * generating configuration files which is used to feature the zone.
  * Moreover, it often requires downloading tools and applications pages,
  * which are not available in device.
- * In that reason, this Domain Separation Framework delegates this work to templates.
- *
+ * In that reason, Vasum Framework delegates this work to templates.
  * \param[in] ctx vsm context
  * \param[in] zone_name zone name
  * \param[in] template_name template name to be used for constructing the zone
  * \param[in] flag Reserved
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_start_zone(), vsm_shutdown_zone(), vsm_destroy_zone()
- *
- * \remarks By default, a zone is in an inactive state even if it has succefully created.
- * Thus, the zone should be unlocked explicitly to start its execution.\n
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * retval = vsm_create_zone(ctx, "personal", "tizen", 0);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE     Successful
+ * \retval #VSM_ERROR_INVALID  Invalid arguments
+ * \retval #VSM_ERROR_EXIST    The same name zone is existed.
+ * \retval #VSM_ERROR_GENERIC  Lxc failed to create zone.
+ * \retval #VSM_ERROR_IO       Database access failed
 */
-API int vsm_create_zone(struct vsm_context *ctx, const char *zone_name, const char *template_name, int flag);
+API int vsm_create_zone(vsm_context_h ctx, const char *zone_name, const char *template_name, int flag);
+
 /**
  * @brief Destroy persistent zone
- * 
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_destroy_zone(struct vsm_context *ctx, const char *name, int force)
- * \endcode
- *
  * \par Description:
  * The function vsm_destroy_zone() triggers zone controller to destroy persistent zone corresponding to the given name.\n
  * All data stored in the repository of the zone are also deleted if force argument is set.
  * Once the zone repository is deleted, it cannot be recovered.
- *
  * \param[in] ctx vsm context
- * \param[in] zone_name Domain name
- * \param[in] force
- * - 0 is Remaining the zone when the zone is running
- * - non-zero is Destroy the zone even though the zone is running
- *
- * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * Parameter "force" is not implemented yet, now it works as non-zero.
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_create_zone(), vsm_shutdown_zone(), vsm_destroy_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * retval = vsm_destroy_zone(ctx, "personal", 1);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \param[in] zone_name zone name
+ * \param[in] force forced flags
+ * - 0 : do not destory running zone.
+ * - non-zero : if zone is running, shutdown forcefully, and destroy.
+ * \return 0 on success, or negative integer error code on error.i
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_BUSY       Target zone is running
+ * \retval #VSM_ERROR_NO_OBJECT  Target zone does not exist
+ * \retval #VSM_ERROR_GENERIC    Lxc failed to destroy zone
+ * \retval #VSM_ERROR_IO         Database access failed
 */
-API int vsm_destroy_zone(struct vsm_context *ctx, const char *zone_name, int force);
+API int vsm_destroy_zone(vsm_context_h ctx, const char *zone_name, int force);
+
 /**
  * @brief Start an execution of a persistent zone
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_start_zone(struct vsm_context *ctx, const char *name)
- * \endcode
- * 
  * \par Description:
  * The function vsm_start_zone() triggers zone controller to start zone corresponding to the given name.\n
  * Caller can speficy the type of zones: transient and peristent.
  * Persistent zones need to be defined before being start up(see vsm_create_zone())
  * While, transient zones are created and started on-the-fly.
- *
  * \param[in] ctx vsm context
  * \param[in] zone_name zone name
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_shutdown_zone(), vsm_create_zone(), vsm_destroy_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * retval = vsm_start_zone(ctx, "personal");
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_INVALID    Invalid argument.
+ * \retval #VSM_ERROR_BUSY       Target zone is already running state.
+ * \retval #VSM_ERROR_NO_OBJECT  Target zone does not exist
+ * \retval #VSM_ERROR_GENERIC    Lxc failed to start zone
 */
-API int vsm_start_zone(struct vsm_context *ctx, const char *zone_name);
+API int vsm_start_zone(vsm_context_h ctx, const char *zone_name);
+
 /**
  * @brief Stop an execution of running zone
- *
- * \par Synopsys
- * \code
- * #include <vasum.h>
- *
- * int vsm_shutdown_zone(struct vsm_context * ctx, struct zone * zone, int force)
- * \endcode
- *
  * \par Description:
- * vsm_shutdown_zone() triggers zone controller to stop execution of the zone corresponsing to the given zone.\n
- *
- * \par Important notes:
- * None
- *
+ * Send request to stop running zone.\n
  * \param[in] ctx vsm context
  * \param[in] zone_name zone name
  * \param[in] force option to shutdown.
- *            Without if 0 send SIGPWR signal to init process in zone,
-              otherwise, terminate all processes in zone forcefully.
- *
+ *     - 0 : send SIGPWR signal to init process of target zone.
+ *  - non-zero : terminate all processes in target zone.
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_create_zone(), vsm_destroy_zone(), vsm_start_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * retval = vsm_shutdown_zone(ctx, "zone", 1);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_INVALID    Invalid argument.
+ * \retval #VSM_ERROR_BAD_STATE  Failed to lookup running zone.
+ * \retval #VSM_ERROR_NO_OBJECT  Target zone does not exist
+ * \retval #VSM_ERROR_GENERIC    Lxc failed to destroy zone
 */
-API int vsm_shutdown_zone(struct vsm_context *ctx, const char *zone_name, int force);
+API int vsm_shutdown_zone(vsm_context_h ctx, const char *zone_name, int force);
 
 /**
- * @brief Prevent starting zone
- *
- * \par Synopsys
- * \code
- * #include <vasum.h>
- *
- * int vsm_lock_zone(struct vsm_context *ctx, const char *name, int shutdown);
- * \endcode
- *
+ * @brief Shutdown zone and prevent starting zone
  * \par Description:
- * Prevent starting a zone
- *
+ *  Prevent starting target zone.
+ *  If target zone is running, shutdown the zone first.
  * \param[in] ctx vsm context
  * \param[in] zone_name zone name
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_create_zone(), vsm_start_zone(), vsm_unlock_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- * ...
- * ret = vsm_lock_zone(ctx, "zone");
- * if(ret < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_NO_OBJECT  Target zone does not exist
+ * \retval #VSM_ERROR_GENERIC    Locking failed.
 */
-API int vsm_lock_zone(struct vsm_context *ctx, const char *zone_name, int shutdown);
+API int vsm_lock_zone(vsm_context_h ctx, const char *zone_name, int shutdown);
 
 /**
  * @brief Allow a zone to be launched
- *
- * \par Synopsys
- * \code
- * #include <vasum.h>
- *
- * int vsm_unlock_zone(struct vsm_context *ctx, const char *name)
- * \endcode
- *
  * \par Description:
  * Remove lock applied to the zone corresponding to the given name.
- *
  * \param[in] ctx vsm context
  * \param[in] zone_name zone name
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_lock_zone(), vsm_create_zone(), vsm_start_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- * ...
- * if (vsm_unlock_zone(ctx, "zone") < 0) {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_GENERIC    Unlocking failed.
 */
-API int vsm_unlock_zone(struct vsm_context *ctx, const char *zone_name);
-
-
-API int vsm_set_foreground(struct vsm_zone * zone);
-
-
-typedef struct vsm_attach_command_t {
-       /** @brief excutable file path */
-       char * exec;
-       /** @brief arguments including the executable binary itself in argv[0] */
-       char ** argv;
-} vsm_attach_command_t;
+API int vsm_unlock_zone(vsm_context_h ctx, const char *zone_name);
 
 /**
- * @brief Domain attach option
+ * @brief Switch target zone to foreground
+ * \par Description:
+ * Switch target zone to foreground on device.
+ * \param[in] zone vsm_zone_h
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_INVALID    vsm_zone_h is invalid
  */
-typedef struct vsm_attach_options_t {
-       /** @brief user id */
-       uid_t uid;
-       /** @brief group id  */
-       gid_t gid;
-       /** @brief number of environment variables */
-       int env_num;
-       /** @brief environment variables */
-       char **extra_env;
-} vsm_attach_options_t;
-
-#define VSM_ATTACH_OPT_DEFAULT \
-{ \
-       /*.uid =*/ (uid_t)0, \
-       /*.gid =*/ (gid_t)0, \
-       /*.env_num=*/ 0, \
-       /*.extra_env = */ NULL \
-}
+API int vsm_set_foreground(vsm_zone_h zone);
 
 /**
- * @brief Launch a process in a running zone.
- *
- * \par Synopsys
- * \code
- * #include <vasum.h>
- *
- * int vsm_attach_zone(struct vsm_context *ctx, const char * name, vsm_attach_command_t * command, vsm_attach_options_t * opt)
- * \endcode
- *
+ * @brief Get current foreground zone on device
  * \par Description:
- * Execute specific command inside the container with given arguments and environment
- *
- * \param[in] ctx vsm context
- * \param[in] zone_name zone name
- * \param[in] command vsm attach command
- * \param[in] opt vsm attach options (can be NULL)
- *
- * \return On sucess, exit code of attached process.
- *         otherwise, a negative value.
- *
- * \par Known issues/bugs:
- *
- * \pre None
- *
- * \post None
- *
- * \see vsm_start_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vsm.h>
- * ...
- * struct vsm_context *ctx;
- * struct vsm_zone *zone;
- * vsm_attach_command_t comm;
- * vsm_attach_options_t opts = VSM_ATTACH_OPT_DEFAULT;
- * char * attach_argv[] = {"-al", "/proc/"};
- *
- * comm.exec = "ls";
- * comm.argc = 2;
- * comm.argv = attach_argv;
- *
- * opts.uid = 5000;
- * opts.gid = 5000;
- * opts.env_num = 0;
- *
- * ...
- * res = vsm_attach_zone(ctx, zone, &comm,  &opts);
- * ...
- * \endcode
- *
+ * Get foreground zone handle.
+ * \param[in] ctx vsm_context_h
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE       Successful
+ * \retval #VSM_ERROR_INVALID    vsm_context_h is invalid
  */
+API vsm_zone_h vsm_get_foreground(vsm_context_h ctx);
 
-API int vsm_attach_zone(struct vsm_context *ctx, struct vsm_zone *zone, vsm_attach_command_t * command, vsm_attach_options_t * opt, pid_t *attached_process);
+/// @}
+/**
+ * @addtogroup ACCESS Vasum Access
+ * @{
+*/
 
+/**
+ * @brief Definition for zone states.
+ * This definition shows the available states.
+*/
+typedef enum {
+       VSM_ZONE_STATE_STOPPED,  /**< Zone stopped */
+       VSM_ZONE_STATE_STARTING, /**< Zone is prepare for running */
+       VSM_ZONE_STATE_RUNNING,  /**< Zone is running on device */
+       VSM_ZONE_STATE_STOPPING, /**< Zone is stopping by request */
+       VSM_ZONE_STATE_ABORTING, /**< Zone is failed to start */
+       VSM_ZONE_STATE_FREEZING, /**< Reserved State */
+       VSM_ZONE_STATE_FROZEN,   /**< Reserved State */
+       VSM_ZONE_STATE_THAWED,   /**< Reserved State */
+       VSM_ZONE_MAX_STATE = VSM_ZONE_STATE_THAWED
+} vsm_zone_state_t;
 
-API int vsm_attach_zone_wait(struct vsm_context *ctx, struct vsm_zone *zone, vsm_attach_command_t * command, vsm_attach_options_t * opt);
 
 /**
- * @brief Interate all zone instances which are in running state
- *
- * \par Synopsys
- * \code
- * #include <vasum.h>
- *
- * int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data)
- * \endcode
- *
- * \par Description:
- * The function vsm_iterate_zone() traverses all zones which are in running state, and callback function will be called on every entry.
- *
- * \param[in] ctx vsm context
- * \param[in] callback Function to be executed in iteration, which can be NULL
- * \param[in] user_data Parameter to be passed to callback function
- *
- * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_lock_zone(), vsm_unlock_zone(), vsm_start_zone(), vsm_shutdown_zone()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_context *ctx;
- * ...
- * void callback(struct vsm_zone *zone, void *user_data)
- * {
- *     printf("Zone : %s\n", zone->name);
- * }
- * ...
- * zone = vsm_iterate_zone(ctx, callback, NULL);
- * if(netdev == NULL)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * @brief Definition for zone events
 */
-API int vsm_iterate_zone(struct vsm_context *ctx, void (*callback)(struct vsm_zone *zone, void *user_data), void *user_data);
+typedef enum {
+       VSM_ZONE_EVENT_NONE,      /**< Zone has no event */ 
+       VSM_ZONE_EVENT_CREATED,   /**< Zone is created */
+       VSM_ZONE_EVENT_DESTROYED, /**< Zone is destroted */
+       VSM_ZONE_EVENT_SWITCHED,  /**< Foreground is switched */
+       VSM_ZONE_MAX_EVENT = VSM_ZONE_EVENT_SWITCHED
+} vsm_zone_event_t;
+
 
 /**
- * @brif Find zone corresponding to the name
- *
- * \par Synopsys
- * \code
- * #include <vasum>
- *
- * struct zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path)
- * \endcode
- *
+ * @brief Definition for zone iteration callback function.
+ */
+typedef void (*vsm_zone_iter_cb)(vsm_zone_h zone, void *user_data);
+/**
+ * @brief Definition for zone state changed callback function.
+ */
+typedef int (*vsm_zone_state_changed_cb)(vsm_zone_h zone, vsm_zone_state_t state,  void *user_data);
+/**
+ * @brief Definition for zone event callback function.
+ */
+typedef int (*vsm_zone_event_cb)(vsm_zone_h zone, vsm_zone_event_t event, void *user_data);
+
+/**
+ * @brief Interate all zone instances which are in running state
  * \par Description:
+ * This API traverses all zones which are in running state, and callback function will be called on every entry.
+ * \param[in] ctx vsm context
+ * \param[in] zone_name zone name string
+ * \param[in] callback Function to be executed in iteration, which can be NULL
+ * \param[in] user_data Parameter to be passed to callback function
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_OUT_OF_MEMORY  Zone handle allocation failed
+ * \retval #VSM_ERROR_GENERIC        Zone initialize failed
+ * \remark In case of callback and is NULL, 
+ *  This API refresh vsm_context which means reloading current running zone to vsm_context again.
+*/
+API int vsm_iterate_zone(vsm_context_h ctx, vsm_zone_iter_cb callback, void *user_data);
+
+/**
+ * @brief Find zone corresponding to the name
  * The function vsm_lookup_zone_by_name() looks for the zone instance corresponding to the given name.
- *
  * \param[in] ctx vsm context
  * \param[in] path zone path to search
- *
  * \return Zone instance on success, or NULL on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_lookup_zone_by_pid(), vsm_lookup_zone_by_terminal(), vsm_iterate_zone() 
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_zone *zone;
- * struct vsm_context *ctx;
- * ...
- * zone = vsm_lookup_zone_by_name(ctx, "personal");
- * if(zone == NULL)
- * {
- *      printf("Knox isn't exist or isn't running\n");
- * } else {
- *     printf("%s is found", zone->name);
- * }
- * ...
- * \endcode
- *
+ * \retval vsm_zone_h  Successful 
+ * \retval NULL        Failed to lookup
+ * \pre  vsm_context_h have to bind by vsm_enter_eventloop() or vsm_context_h does not have current zone status. 
+ * \see vsm_create_context(), vsm_enter_eventloop()
 */
-API struct vsm_zone *vsm_lookup_zone_by_name(struct vsm_context *ctx, const char *path);
+API vsm_zone_h vsm_lookup_zone_by_name(vsm_context_h ctx, const char *name);
 
 /**
  * @brief Find zone instance associated with the process id
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- * 
- * struct zone * vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid)
- * \endcode
- *
  * \par Description:
  * The function vsm_lookup_zone_by_pid() looks for the zone instance associated with the given pid.
- *
  * \param[in] ctx vsm context
  * \param[in] pid Process id
- *
  * \return Zone instance on success, or NULL on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_lookup_zone_by_name(), vsm_lookup_zone_by_terminal(), vsm_iterate_zone() 
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_zone *zone;
- * struct vsm_context *ctx;
- * ...
- * zone = vsm_lookup_zone_by_pid(ctx, 1208);
- * if(zone == NULL)
- * {
- *      printf("Not found\n");
- * } else {
- *     printf("%s is found", zone->name);
- * }
- * ...
- * \endcode
- *
+ * \retval vsm_zone_h  Successful 
+ * \retval NULL        Failed to lookup
+ * \pre  vsm_context_h have to bind by vsm_enter_eventloop() or vsm_context_h does not have current zone status. 
+ * \see vsm_create_context(), vsm_enter_eventloop()
 */
-API struct vsm_zone *vsm_lookup_zone_by_pid(struct vsm_context *ctx, pid_t pid);
+API vsm_zone_h vsm_lookup_zone_by_pid(vsm_context_h ctx, pid_t pid);
 
 /**
- * @brief Find zone instance associated with the given terminal
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * struct zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal)
- * \endcode
- *
- * \par Purpose:
- * The function vsm_lookup_zone_by_terminal_id() search zone instance which is associated with the given terminal.
- * In general, the terminal id would be tty number.
- *
+ * @brief Register zone status changed callback
+ * \par Description:
+ * Register a callback function for zone status change.
  * \param[in] ctx vsm context
- * \param[in] terminal Terminal id to search
- *
- * \return Zone instance on success, or NULL on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_start_context(), vsm_shutdown_context(), vsm_lookup_zone_by_name(), vsm_lookup_zone_by_pid(), vsm_iterate_zone() 
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_zone *zone;
- * struct vsm_context *ctx;
- * ...
- * zone = vsm_lookup_zone_by_terminal_id(ctx, 2);
- * if(zone == NULL)
- * {
- *      printf("Not found\n");
- * } else {
- *     printf("%s is found", zone->name);
- * }
- * ...
- * \endcode
- *
+ * \param[in] callback Callback function to invoke when zone satte event occurs
+ * \return Callback handle on success, or negative error code on error.
+ * \retval handle nonnegative handle id for callback.
+ * \retval #VSM_ERROR_OUT_OF_MEMORY  Callback hanlder allocation failed.
+ * \pre  vsm_context_h have to bind by vsm_enter_eventloop() or callback function does not called. 
+ * \see vsm_create_context(), vsm_enter_eventloop(), vsm_del_state_changed_callback()
 */
-API struct vsm_zone *vsm_lookup_zone_by_terminal_id(struct vsm_context *ctx, int terminal);
+API int vsm_add_state_changed_callback(vsm_context_h ctx, vsm_zone_state_changed_cb callback, void *user_data);
 
 /**
- * @brief Definition for zone event callback function.
- */
-typedef int (*vsm_zone_state_cb)(struct vsm_zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data);
+ * @brief Deregister zone status changed callback handler
+ * \par Description:
+ * Remove an event callback from the zone control context.
+ * \param[in] ctx vsm context
+ * \param[in] handle Callback Id to remove
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE Successful
+ * \retval #VSM_ERROR_NO_OBJECT Failed to lookup callback handler
+*/
+API int vsm_del_state_changed_callback(vsm_context_h ctx, int handle);
 
 /**
- * @brief Register a callback to be notified when zone state has changed
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_add_state_callback(struct vsm_context *ctx, zone_state_cb callback, void *user_data)
- * \endcode
- *
+ * @brief Register zone event callback
  * \par Description:
- * Register a callback to be notified when zone state event occurs.
- *
+ * Register a callback function for zone event.
  * \param[in] ctx vsm context
- * \param[in] callback Callback function to invoke when zone satte event occurs
- *
- * \return Callback ID on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_del_state_callback(), vsm_enter_eventloop(), vsm_get_poll_fd()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_context *ctx;
- * ...
- * void callback(struct zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data)
- * {
- *     if (state == VSM_ZONE_STATE_RUNNING)
- *             printf("Domain(%s) is running\n", zone->name);
- * }
- * ...
- * retval = vsm_add_state_callback(ctx, callback, NULL);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * \param[in] callback callback function to invoke when zone event occurs
+ * \return positive callback handle on success, or negative error code on error.
+ * \retval handle nonnegative handle id for callback.
+ * \retval #VSM_ERROR_OUT_OF_MEMORY  Callback hanlder allocation failed.
+ * \pre  vsm_context_h have to bind by vsm_enter_eventloop() or callback function does not called.
+ * \see vsm_create_context(), vsm_enter_eventloop(), vsm_del_state_changed_callback()
 */
-API int vsm_add_state_callback(struct vsm_context *ctx, vsm_zone_state_cb callback, void *user_data);
+API int vsm_add_event_callback(vsm_context_h ctx, vsm_zone_event_cb callback, void *user_data);
+
 /**
- * @brief Remove zone event callback
- * 
- * \par Synopsis
- * \code
- * #include <vasum.h>
- *
- * \endcode
- *
+ * @brief Deregister zone event callback handler
  * \par Description:
  * Remove an event callback from the zone control context.
- *
- * \par Important notes:
- * None
- *
  * \param[in] ctx vsm context
- * \param[in] handle Callback Id to remove
- *
+ * \param[in] handle callback handle to remove
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_create_context(), vsm_cleanup_context(), vsm_add_state_callback()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int id;
- * struct vsm_context *ctx;
- * ...
- * void callback(struct zone *zone, vsm_zone_state_t state, vsm_zone_event_t event, void *user_data)
- * {
- *     if (state == VSM_ZONE_STATE_RUNNING)
- *             printf("Domain(%s) is running\n", zone->name);
- * }
- * ...
- * id = vsm_add_state_callback(ctx, callback, NULL);
- * ...
- * vsm_del_state_callback(ctx, id);
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE Successful
+ * \retval #VSM_ERROR_NO_OBJECT Failed to lookup callback handler
 */
-API int vsm_del_state_callback(struct vsm_context *ctx, int handle);
+API int vsm_del_event_callback(vsm_context_h ctx, int handle);
 
-/// @}
+/**
+ * @brief Zone attach parameters
+ * Arguments are same as linux system-call execv()
+ */
+typedef struct vsm_attach_command_s {
+       char * exec;      /**< Program binary path */
+       char ** argv;     /**< An array of argument pointers to null-terminated strings include program path */
+} vsm_attach_command_s;
 
 /**
- * @addtogroup DEVICE_CONTROL
- * @{
+ * @brief Zone attach option
+ */
+typedef struct vsm_attach_options_s {
+       uid_t uid;        /**< requested uid*/
+       gid_t gid;        /**< requested gid*/
+       int env_num;      /**< requested environ count */
+       char **extra_env; /**< requested environ string pointer array. */
+} vsm_attach_options_s;
+
+/**
+ * @brief default attach options
+ * \n
+ * uid = root\n
+ * gid = root\n
+ * env = no extra env\n
+ */
+
+#define VSM_ATTACH_OPT_DEFAULT {  (uid_t)0, (gid_t)0,  0, NULL }
+
+/**
+ * @brief Launch a process in a running zone.
+ * \par Description:
+ * Execute specific command inside the zone with given arguments and environment
+ * \param[in] zone vsm_zone_h
+ * \param[in] command vsm attach command
+ * \param[in] opt vsm attach options (can be NULL), using VSM_ATTACH_OPT_DEFAULT
+ * \param[out] attached process pid
+ * \return On sucess 0, otherwise, a negative integer error code on error
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_NO_OBJECT      Target zone is not running state
+ * \retval #VSM_ERROR_GENERIC        IPC failed
+ */
+API int vsm_attach_zone(vsm_context_h ctx, const char * zone_name, vsm_attach_command_s * command, vsm_attach_options_s * opt, pid_t *attached_process);
+
+/**
+ * @brief Launch a process in a running zone and wait till child process exited.
+ * \par Description:
+ * Execute specific command inside the zone with given arguments and environment
+ * \param[in] zone vsm_zone_h
+ * \param[in] command vsm attach command
+ * \param[in] opt vsm attach options (can be NULL), using VSM_ATTACH_OPT_DEFAULT
+ * \return On sucess waitpid exit code or attached process, or a negative error code
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_NO_OBJECT      Target zone is not running state
+ * \retval #VSM_ERROR_GENERIC        IPC failed or waitpid error
+ */
+API int vsm_attach_zone_wait(vsm_context_h ctx, const char * zone_name, vsm_attach_command_s * command, vsm_attach_options_s * opt);
+
+/**
+ * @brief Get name string of zone.
+ * \par Description:
+ * Get name string of zone.
+ * \param[in] zone vsm zone handle
+ * \return a pointer of zone name string on sucess or NULL on fail.
+ * \retval name string value of zone.
+ * \retval NULL vsm_zone_h is invalid.
+ * \warning Do not modify or free returned pointer memroy.
+ *          This memory will be cleanup by vsm_cleanup context()
 */
+API const char * vsm_get_zone_name(vsm_zone_h zone);
 
 /**
- * @brief Grant device to zone
- *
- * \par Synopsys:
- * \code
- * #include <vasum.h>
- *
- * int vsm_grant_device(struct vsm_zone *zone, const char *name, uint32_t flags)
- * \endcode
- *
+ * @brief Get zone root ablsolute path on host side.
  * \par Description:
- * The function vsm_grant_device() permits the zone using the device corresponding to the given name.
- *
- * \param[in] zone Zone
- * \param[in] name Path of device to grant
- * \param[in] flags O_RDWR, O_WRONLY, O_RDONLY
- *
- * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre None
- *
- * \post None
- *
- * \see vsm_revoke_device()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_zone *zone;
- * ...
- * retval = vsm_grant_device(zone, "/dev/dri/card0", O_RDWR);
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * Get rootpath string of zone.
+ * \param[in] zone vsm zone handle
+ * \return a pointer of zone rootpath string on sucess or NULL on fail.
+ * \retval rootpath string value of zone.
+ * \retval NULL vsm_zone_h is invalid.
+ * \warning Do not modify or free returned memroy.
+ *          This memory will be cleanup by vsm_cleanup context()
 */
-API int vsm_grant_device(struct vsm_zone *dom, const char *name, uint32_t flags);
+API const char * vsm_get_zone_rootpath(vsm_zone_h zone);
+
 /**
- * @brief Revoke device from the zone
- * 
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_revoke_device(struct vsm_zone *zone, const char *name)
- * \endcode
- *
+ * @brief Get type of running zone.
  * \par Description:
- *
- * \param[in] zone Zone
- * \param[in] name Host-side path of device to revoke
- *
- * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_grant_device()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_zone *zone;
- * ...
- * retval = vsm_revoke_device(dom, "/dev/samsung_sdb");
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
+ * Get type string of zone. This value is defined in template file when using vsm_create_zone()
+ * \param[in] zone vsm zone handle
+ * \return a pointer of zone path string on sucess or NULL on fail.
+ * \retval rootpath string value of zone.
+ * \retval NULL vsm_zone_h is invalid.
+ * \see vsm_create_zone()
+ * \warning Do not modify or free returned memroy.
+ *          This memory will be cleanup by vsm_cleanup context()
+*/
+API const char * vsm_get_zone_type(vsm_zone_h zone);
+
+/**
+ * @brief Check zone handle, a host or a normal zone by zone handle.
+ * \param[in] zone vsm zone handle
+ * \return positive integer on host case, or 0 on normal zone.
+ * \retval positive target zone is host zone.
+ * \retval NULL     target zone is NOT host.
+*/
+API int vsm_is_host_zone(vsm_zone_h zone);
+
+/**
+ * @brief get zone state.
+ * \par Description:
+ * Get zone state value by zone handle.
+ * \param[in] zone vsm zone handle
+ * \return vsm_zone_state_t value, or negative value.
+ * \retval state vsm_zone_state_t value of zone
+ * \retval #VSM_ERROR_INVALID vsm_zone_h is invalid
+*/
+
+API vsm_zone_state_t vsm_get_zone_state(vsm_zone_h zone);
+
+/**
+ * @brief get zone id by handle.
+ * \par Description:
+ * Get zone id value by zone handle.
+ * \param[in] zone vsm zone handle
+ * \return interger id value of zone or negative error.
+ * \retval id nonnegative interger value.
+ * \retval #VSM_ERROR_INVALID vsm_zone_h is invalid
+ * \remarks id '0' is reserved for host.
+*/
+API int vsm_get_zone_id(vsm_zone_h zone);
+
+
+/**
+ * @brief Set userdata pointer value in vsm_zone_h.
+ * \par Description:
+ * Get zone id value by zone handle.
+ * \param[in] zone vsm zone handle
+ * \return On success 0, or negative error.
+ * \retval #VSM_ERROR_NONE     Successful.
+ * \retval #VSM_ERROR_INVALID  vsm_zone_h is invalid
+ * \warning This userdata have to be free before vsm_cleanup_context() or VSM_ZONE_STATE_STOPPED callback handler
+*/
+API int vsm_set_userdata(vsm_zone_h zone, void * userdata);
+
+/**
+ * @brief Set userdata pointer value in vsm_zone_h.
+ * \par Description:
+ * Get zone id value by zone handle.
+ * \param[in] zone vsm zone handle
+ * \return On success pointer of userdata, or NULL pointer
+ * \retval userdata pointer of userdata.
+ * \retval NULL invalid vsm_zone_h.
+ * \remark initial value is pointer of self vsm_zone_h
 */
-API int vsm_revoke_device(struct vsm_zone *dom, const char *name);
+API void * vsm_get_userdata(vsm_zone_h zone);
+
+/**
+ * @brief join current process into zone.
+ * \par Synopsys:
+ * Change self peer credential to target zone
+ * \param[in] vsm_zone_h zone
+ * \return before vsm_zone on success, or NULL on error.
+ * \retval vsm_zone_h before zone handle, If caller process running in host, then host handle returned.
+ * \retval NULL       invalid zone handle.
+ * \pre parameter vsm zone must be lookup by vsm lookup APIs
+ * \post  After finish target zone procedure, must join again before zone by same API.
+ * \warning This function is not thread-safe. \n
+ *   All requests of threads in same process are considered target zone request to other host processes.
+ */
+API vsm_zone_h vsm_join_zone(vsm_zone_h zone);
+
+/**
+ * @brief get canonical file path based on current zone.
+ * \par Description:
+ *    get canonical file path based on current zone.
+ * \param[in] input_path requested zone path
+ * \param[out] output_path string pointer for canonicalized output path 
+ * \return int positive string length of output_path, or negative error code on error.
+ * \retval #VSM_ERROR_INVALID Invalid arguments.
+ * \retval #VSM_ERROR_GENERIC gethostname() is failed.
+ * \post Out buffer(*output_path) have to be freed by caller after use.
+ * \remarks This API can call inside zone without vsm_context_h
+ *   It means this API can call library side for apps.
+ */
+API int vsm_canonicalize_path(const char *input_path, char **output_path);
+
+/**
+ * @brief Check current environment, a host or virtualized zone.
+ * \par Description:
+ *    Check current caller process environment.
+ * \return positive integer on running in zone, or 0 on running in host.
+ * \retval NULL     Current process running in host.
+ * \remarks This API can call inside zone without vsm_context_h
+ *   It means this API can call library side for apps.
+ */
+API int vsm_is_virtualized(void);
+
+/**
+ * @brief Check equivalence between caller and target pid.
+ * \par Description:
+ *    Check API caller process and target pid running in same zone.
+ * \retval NULL       target process is running in another zone.
+ * \retval 1        target process is running in same zone.
+ * \retval -1       failed to check target process.
+ * \remarks This API can check real zone of target pid.
+            Real zone is not changed by even join API.
+ */
+API int vsm_is_equivalent_zone(vsm_context_h ctx, pid_t pid);
+
+/**
+ * @brief Translate zone pid to host pid.
+ * \par Description:
+ *    This API would translate zone namespace pid to host namespace pid.
+ * \param[in] zone  the zone of target process
+ * \param[in] pid   target process id of zone namespace
+ * \return positive pid or negative error code.
+ * \retval pid                       translated host pid of zone process.
+ * \retval #VSM_ERROR_NO_OBJECT      No such process in a target zone.
+ * \retval #VSM_ERROR_NOT_PERMITTED  Permission denied to get target pid info.
+ * \retval #VSM_ERROR_NOT_SUPPORTED  Kernel config is not enabled about pid namespace.
+ * \retval #VSM_ERROR_INVALID        Arguments is invalid.
+ * \retval #VSM_ERROR_IO             Failed to get process info.
+ * \retval #VSM_ERROR_GENERIC        Failed to matching zone pid to host pid.
+ */
+API int vsm_get_host_pid(vsm_zone_h zone, pid_t pid);
+
 
 /// @}
 
 /**
- * @addtogroup NETWORK_CONTROL
+ * @addtogroup NETWORK Vasum Network
  * @{
 */
 
@@ -1236,410 +699,251 @@ API int vsm_revoke_device(struct vsm_zone *dom, const char *name);
  * @brief Types of virtual network interfaces
  */
 typedef enum {
-       ///Virtual Ethernet(veth), this type device will be attached to host-side network bridge
-       VSM_NETDEV_VETH,
-       ///Physical device
-       VSM_NETDEV_PHYS,
-       ///Mac VLAN, this type isn't implemented yet
-       VSM_NETDEV_MACVLAN
+       VSM_NETDEV_VETH, /**< Virtual Ethernet(veth), this type device will be attached to host-side network bridge */
+       VSM_NETDEV_PHYS, /**< Physical device */
+       VSM_NETDEV_MACVLAN /**< Mac VLAN, this type isn't implemented yet */
 } vsm_netdev_type_t;
 
+typedef enum {
+       VSM_NETDEV_ADDR_IPV4, /**< IPV4 Address family */
+       VSM_NETDEV_ADDR_IPV6 /**< IPV6 Address family */
+} vsm_netdev_addr_t;
+
 /**
  * @brief Network device information
  */
-struct vsm_netdev {
-       /// Domain
-       struct vsm_zone *zone;
-       /// Device name
-       char *name;
-       /// Type
-       vsm_netdev_type_t type;
+typedef struct vsm_netdev *vsm_netdev_h;
 
-       ///List head
-       struct adt_list list;
-};
+/**
+ * @brief Definition for zone network devince iteration callback function.
+ */
+typedef void (*vsm_zone_netdev_iter)(struct vsm_netdev *, void *user_data);
 
 /**
  * @brief Create a new network device and assisgn it to zone
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev)
- * \endcode
- *
  * \par Description:
  * This function creates net netdev instance and assign it to the given zone.
- *
  * \param[in] zone Zone
  * \param[in] type Type of network device to be create
  * \param[in] target
  * - If type is veth, this will be bridge name to attach.
  * - If type is phys, this will be ignored.
  * \param[in] netdev Name of network device to be create
- *
  * \return Network devce on success, or NULL on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
+ * \retval vsm_netdev_h New net device handle
+ * \retval NULL         Failed to create netdev
  * \see vsm_create_netdev()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int retval;
- * struct vsm_netdev *netdev;
- * ...
- * netdev = vsm_create_netdev(zone, VSM_NETDEV_VETH, "virbr0", "vethKnox");
- * if(retval < 0)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
- * Macvlan isn't implemented yet.
-*/
-API struct vsm_netdev *vsm_create_netdev(struct vsm_zone *zone, vsm_netdev_type_t type, const char *target, const char *netdev);
+ * \par Known Issues:
+ *  Macvlan is not implemented yet.
+ */
+API vsm_netdev_h vsm_create_netdev(vsm_zone_h zone, vsm_netdev_type_t type, const char *target, const char *netdev);
+
 /**
- * @brief Removes a network device from zone control context
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev)
- * \endcode
- *
+ * @brief Removes a network device from zone
  * \par Description:
  * This function remove the given netdev instance from the zone control context.
- *
- * \param[in] zone zone
  * \param[in] netdev network device to be removed
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
  * \see vsm_destroy_netdev()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_zone *zone;
- * struct vsm_netdev *netdev;
- * ...
- * netdev = vsm_create_netdev(zone, VSM_NETDEV_VETH, "virbr0", "vethKnox");
- * if(netdev == NULL)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * vsm_destroy_netdev(zone, netdev);
- * ...
- * \endcode
- *
-*/
-API int vsm_destroy_netdev(struct vsm_zone *zone, struct vsm_netdev *netdev);
+ */
+API int vsm_destroy_netdev(vsm_netdev_h netdev);
 
 /**
  * @brief Iterates network devices found in the zone vsm context and executes callback() on each interface.
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- * 
- * int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data)
- * \endcode
- *
  * \par Description:
  * vsm_destroy_netdev() scans all network interfaces which are registered in the vsm context, and calls callback() on each entry.
- *
  * \param[in] zone Zone
  * \param[in] callback Function to be executed in iteration, which can be NULL
  * \param[in] user_data Parameter to be delivered to callback function
- *
  * \return 0 on success, or negative integer error code on error.
- *
- * \par Known issues/bugs:
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
  * \see vsm_create_netdev(), vsm_destroy_netdev()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct zone *zone;
- * ...
- * void callback(struct vsm_neatdev *netdev, void *user_data)
- * {
- *     printf("Network device : %s\n", netdev->name);
- * }
- * ...
- * netdev = vsm_iterate_netdev(zone, callback, NULL);
- * if(netdev == NULL)
- * {
- *      printf("Error has occurred\n");
- *      exit(0);
- * }
- * ...
- * \endcode
- *
-*/
-API int vsm_iterate_netdev(struct vsm_zone *zone, void (*callback)(struct vsm_netdev *, void *user_data), void *user_data);
+ */
+API int vsm_iterate_netdev(vsm_zone_h zone, vsm_zone_netdev_iter callback, void *user_data);
 
 /**
  * @brief Find a network device corresponding to the name
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * struct zone_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name)
- * \endcode
- *
  * \par Description:
- * The function vsm_lookup_netdev_by_name() looks for a network interface corresponding to the given name.
- *
- * \param[in] zone Zone
+ * The function vsm_lookup_netdev_by_name() looks for a network interface.
  * \param[in] name Network device name to search
- *
  * \return Network device on success, or NULL on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_iterate_netdev()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * struct vsm_zone *zone;
- * struct vsm_netdev *netdev;
- * ...
- * netdev = vsm_lookup_netdev(zone, "vethKnox");
- * if(netdev == NULL)
- * {
- *      printf("Network device isn't exist\n");
- * } else {
- *     printf("There is %s in %s", netdev->name);
- * }
- * ...
- * \endcode
- *
+ * \retval vsm_netdev_h Target net device handle
+ * \retval NULL         Failed to lookup netdev
+ */
+
+API vsm_netdev_h vsm_lookup_netdev_by_name(vsm_zone_h zone, const char *name);
+
+/**
+ * @brief Turn up a network device in the zone
+ * \par Description:
+ * This function turns up the given netdev instance in the zone.
+ * \param[in] netdev network device to be removed
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_down_netdev()
+ */
+API int vsm_up_netdev(vsm_netdev_h netdev);
+
+/**
+ * @brief Turn down a network device in the zone
+ * \par Description:
+ * This function turns down the given netdev instance in the zone.
+ * \param[in] netdev network device to be removed
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_down_netdev()
+ */
+API int vsm_down_netdev(vsm_netdev_h netdev);
+
+/**
+ * @brief Get ip address from a network device
+ * \par Description:
+ * The function vsm_get_ip_addr_netdev() get ip address from a network interface
+ * \param[in] netdev Network device to get address
+ * \param[in] family Address family
+ * \param[out] addr Buffer to get address from a network device
+ * \param[out] size Size of buffer
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_OVERFLOW       Parameter overflow
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_set_ip_addr_netdev()
+ */
+API int vsm_get_ip_addr_netdev(vsm_netdev_h netdev, vsm_netdev_addr_t addr_family, char *addr, int size);
+
+/**
+ * @brief Set ip address to a network device
+ * \par Description:
+ * The function vsm_set_ip_addr_netdev() set ipv4 address to a network interface
+ * \param[in] netdev Network device to set address
+ * \param[in] family Address family
+ * \param[in] addr IP address string to be set
+ * \param[in] prefix prefix ( ex> 192.168.122.1/24, 24 is prefix )
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_OVERFLOW       Parameter overflow
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_get_ip_addr_netdev()
+ */
+API int vsm_set_ip_addr_netdev(vsm_netdev_h netdev, vsm_netdev_addr_t addr_family, const char *addr, int prefix);
+
+
+
+/// @}
+
+/**
+ * @addtogroup DEVICE Vasum Device
+ * @{
 */
-API struct vsm_netdev *vsm_lookup_netdev_by_name(struct vsm_zone *zone, const char *name);
 
+/**
+ * @brief Grant device to zone
+ * \par Description:
+ * Request permission device file node to target zone.
+ * \param[in] zone vsm_zone_h
+ * \param[in] name device node path
+ * \param[in] flags requested permission O_RDWR, O_WRONLY, O_RDONLY
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_NOT_PERMITTED  Change cgroup is not permitted
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_revoke_device()
+ */
+API int vsm_grant_device(vsm_zone_h zone, const char *path, uint32_t flags);
+
+/**
+ * @brief Revoke device from the zone
+ * \par Description:
+ * Revoke device node permissions from target zone.
+ * \param[in] zone vsm_zone_h
+ * \param[in] name device node path
+ * \return 0 on success, or negative integer error code on error.
+ * \retval #VSM_ERROR_NONE           Successful
+ * \retval #VSM_ERROR_INVALID        Invalid arguments
+ * \retval #VSM_ERROR_NOT_PERMITTED  Change cgroup is not permitted
+ * \retval #VSM_ERROR_GENERIC        Failed to interact with vasum server
+ * \see vsm_grant_device()
+ */
+API int vsm_revoke_device(vsm_zone_h zone, const char *path);
 /// @}
 
+
 /**
- * @addtogroup RESOURCE_PROVISIONING
+ * @addtogroup RESOURCE Vasum Resource
  * @{
  */
 
+/**
+ * @brief Definition for declare file type.
+*/
 typedef enum {
-       VSM_FSO_TYPE_DIR,
-       VSM_FSO_TYPE_REG,
-       VSM_FSO_TYPE_FIFO,
-       VSM_FSO_TYPE_SOCK,
-       VSM_FSO_TYPE_DEV,
+       VSM_FSO_TYPE_DIR,  /**< Directoy type */
+       VSM_FSO_TYPE_REG,  /**< Regular file type */
+       VSM_FSO_TYPE_FIFO, /**< Fifo file type */
+       VSM_FSO_TYPE_SOCK, /**< Socket file type */
+       VSM_FSO_TYPE_DEV,  /**< Device node type */
        VSM_FSO_MAX_TYPE = VSM_FSO_TYPE_DEV
 } vsm_fso_type_t;
 
+/**
+ * @brief Declare file mode.
+*/
+
 typedef mode_t vsm_mode_t;
 
 /**
- * @brief Register file system object to vsm context.
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode)
- * \endcode
- *
+ * @brief Declare specific file object to every zone.
  * \par Description:
- * Register file system object to vsm context. Once the object is registered to the context, it will be populated when
- * any zone is started.\n
- *
+ * Declare host file system to every running zone.
+ * In case of host target file exist, create new file in running zone. or create a new file in running zone. 
+ * And add hook info in vsm-resource-provier for automatically link host target file to starting zone.
+ * Smack labels are also copied as same as host labels.
  * \param[in] ctx vsm context
  * \param[in] type Type of file system object
  * \param[in] path Path for the file system object
  * \param[in] flags Flasg
  * \param[in] mode mode
- *
- * \return zero on success, or negative value on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_declare_mount(), vsm_declare_link()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int ret;
- * struct vsm_zone *zone;
- * ...
- * ret = vsm_declare_file(zone, VSM_FSO_TYPE_DIR, "/vethKnox", 0666);
- * if(ret < 0)
- * {
- *      printf("Failed to declare file system object\n");
- * }
- *
- * ...
- * \endcode
- *
-*/
-
-API int vsm_declare_file(struct vsm_context *ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode);
-
-/**
- * @brief Register file system object to vsm context.
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_declare_mount(struct vsm_context *ctx, const char *source, const char *target, const char *fstype, unsigned long flags, const void *data)
- * \endcode
- *
- * \par Description:
- * Register mount to vsm context. Once the mount is registered to the context, it will be populated when
- * any zone is started.\n
- *
- * \param[in] ctx vsm context
- * \param[in] source filesystem source
- * \param[in] target mount point
- * \param[in] fstype filesystem type
- * \param[in] flags mount options
- * \param[in] data filesystem specific data
- *
  * \return zero on success, or negative value on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_decalre_file(), vsm_declare_link()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int ret;
- * struct vsm_zone *zone;
- * ...
- * ret = vsm_declare_file(zone, "/dev/block0", "/mnt/target", "ext4", 0, NULL);
- * if(ret < 0)
- * {
- *      printf("Failed to declare file system object\n");
- * }
- *
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE      successful.
+ * \retval #VSM_ERROR_INVALID   Invalid file type or path.
+ * \retval #VSM_ERROR_GENERIC   Error in vasum server side.
+ * \retval #VSM_ERROR_NO_OBJECT Source file is not exist in host filesystem
 */
-
-API int vsm_declare_mount(struct vsm_context *ctx, const char *source, const char *target, const char *fstype, unsigned long flags, const void *data);
+API int vsm_declare_file(vsm_context_h ctx, vsm_fso_type_t ftype, const char *path, int flags, vsm_mode_t mode);
 
 /**
- * @brief Declare hardlink to vsm context.
- *
- * \par Synopsis:
- * \code
- * #include <vasum.h>
- *
- * int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target)
- * \endcode
- *
+ * @brief Declare hardlink to every zone.
  * \par Description:
- *  Declare hardlink to the vsm context.\n
- * In general, this function is used to create shared socket.
- *
+ * Declare hardlink to host file to every running zone.
+ * And add hook info in vsm-resource-provier for automatically link host target file to starting zone.
+ * In general, this function is used to share file host and all running zones.
+ * Smack labels are also copied as same as host labels.
  * \param[in] ctx vsm context
  * \param[in] source source
  * \param[in] target target
- *
  * \return zero on success, or negative value on error.
- *
- * \par Known issues/bugs:
- * None
- *
- * \pre vsm context must be initialized by vsm_create_context()
- *
- * \post None
- *
- * \see vsm_declare_file(), vsm_declare_mount()
- *
- * \remarks None
- *
- * \par Sample code:
- * \code
- * #include <vasum.h>
- * ...
- * int ret;
- * struct vsm_zone *zone;
- * ...
- * ret = vsm_declare_link(zone, "/tmp/sock", "/tmp/sock");
- * if(ret < 0)
- * {
- *      printf("Failed to declare file system object\n");
- * }
- *
- * ...
- * \endcode
- *
+ * \retval #VSM_ERROR_NONE      successful
+ * \retval #VSM_ERROR_INVALID   Invalid provision type to db. 
+ * \retval #VSM_ERROR_GENERIC   Error in vasum server side.
+ * \retval #VSM_ERROR_NO_OBJECT Source file is not exist in host filesystem
 */
-
-API int vsm_declare_link(struct vsm_context *ctx, const char *source, const char *target);
+API int vsm_declare_link(vsm_context_h ctx , const char *source, const char *target);
 
 /// @}
 
+
 #ifdef __cplusplus
 }
 #endif
similarity index 81%
rename from client/sc_adt.h
rename to client/vasum_list.h
index ec4c498..185287b 100644 (file)
@@ -1,11 +1,22 @@
-#ifndef __SCX_ADT_LIST_H__
-#define __SCX_ADT_LIST_H__
+#ifndef __VASUM_ADT_LIST_H__
+#define __VASUM_ADT_LIST_H__
 
 struct adt_list {
        struct adt_list* next;
        struct adt_list* prev;
 };
 
+#undef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define container_of(ptr, type, member) ({                      \
+               const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+               (type *)( (char *)__mptr - offsetof(type,member) );})
+
 #define adt_iterate_list(__iterator, __list)    \
     for (__iterator = (__list)->next;   \
          __iterator != __list;      \
@@ -88,4 +99,4 @@ static inline struct adt_list *adt_find_list(struct adt_list* head,
        return NULL;
 }
 
-#endif /*!__ADT_LIST_H__*/
+#endif /*!__VASUM_ADT_LIST_H__*/
diff --git a/client/wrapper-compat.cpp b/client/wrapper-compat.cpp
new file mode 100644 (file)
index 0000000..dcd9e38
--- /dev/null
@@ -0,0 +1,1580 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Krzysztof Dynowski <k.dynowski@samsung.com>
+ *
+ *  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  Krzysztof Dynowski (k.dynowski@samsung.com)
+ * @brief   Vasum old API compatibility functions
+ */
+
+#include "wrapper-compat.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <regex.h>
+#include <limits.h>
+#include <sys/mount.h>
+#include <sys/xattr.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <asm/unistd.h>
+
+extern "C" {
+
+// find_container_by_pid
+char *find_container_by_pid(pid_t  /*pid*/) {
+    return NULL;
+}
+// get_domain_pid
+pid_t get_domain_pid(const char * /*name*/, const char * /*target*/) {
+    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*/) {
+    return 0;
+}
+// sock_connect
+int sock_connect(const char * /*path*/) {
+    return 0;
+}
+// sock_create_socket
+int sock_create_socket(const char * /*path*/, int  /*type*/, int  /*flags*/) {
+    return 0;
+}
+// sock_monitor_address
+int sock_monitor_address(char * /*buffer*/, int  /*len*/, const char * /*lxcpath*/) {
+    return 0;
+}
+// sock_recv_fd (intern)
+int sock_recv_fd(int  /*fd*/, int * /*recvfd*/, void * /*data*/, size_t  /*size*/) {
+    return 0;
+}
+// sock_send_fd
+int sock_send_fd(int  /*fd*/, int  /*sendfd*/, void * /*data*/, size_t  /*size*/) {
+    return 0;
+}
+// vasum_log
+void vasum_log(int  /*type*/, const char *  /*tag*/, const char *  /*fmt*/ , ...) {
+}
+
+#define MAX_ERROR_MSG  0x1000
+#define BUF_SIZE       4096
+
+#define SMACK_LABEL_LEN 8
+#define ERROR(...) do{}while(0)
+#define WARN(...) do{}while(0)
+#define DEBUG(...) do{}while(0)
+#define INFO(...) do{}while(0)
+
+// lib/utils.c
+const char *const fso_type_strtab[] = {
+       "Directory",
+       "Regular file",
+       "FIFO",
+       "Socket",
+       "Device node"
+};
+
+const char *fso_type_to_string(vsm_fso_type_t fso)
+{
+       if (fso < 0 || fso > VSM_FSO_MAX_TYPE) {
+               return NULL;
+       }
+
+       return fso_type_strtab[fso];
+}
+
+int wait_for_pid_status(pid_t pid)
+{
+       int status, ret;
+
+ again:
+       ret = waitpid(pid, &status, 0);
+       if (ret == -1) {
+               if (errno == EINTR) {
+                       goto again;
+               } else {
+                       ERROR("waitpid- pid : %d error : %s", pid,
+                             strerror(errno));
+                       return -1;
+               }
+       }
+       if (ret != pid)
+               goto again;
+       return status;
+}
+
+vsm_fso_type_t fso_string_to_type(char *str)
+{
+       int len;
+       int i;
+       for (i = 0; i <= VSM_FSO_MAX_TYPE; i++) {
+               len = strlen(fso_type_strtab[i]);
+               if (strncmp(str, fso_type_strtab[i], len) == 0)
+                       return static_cast<vsm_fso_type_t>(i);
+       }
+
+       return static_cast<vsm_fso_type_t>(-1);
+}
+
+int mkdir_p(const char *dir, mode_t mode)
+{
+       const char *tmp = dir;
+       const char *orig = dir;
+       char *makeme;
+
+       do {
+               dir = tmp + strspn(tmp, "/");
+               tmp = dir + strcspn(dir, "/");
+               makeme = strndup(orig, dir - orig);
+               if (*makeme) {
+                       if (mkdir(makeme, mode) && errno != EEXIST) {
+                               free(makeme);
+                               return -1;
+                       }
+               }
+               free(makeme);
+       } while (tmp != dir);
+
+       return 0;
+}
+
+int lock_fd(int fd, int wait)
+{
+       int ret;
+       struct flock f;
+
+       while (1) {
+               f.l_type = F_WRLCK;
+               f.l_whence = SEEK_SET;
+               f.l_start = 0;
+               f.l_len = 0;
+
+               if (wait)
+                       ret = fcntl(fd, F_SETLKW, &f);
+               else
+                       ret = fcntl(fd, F_SETLK, &f);
+               if (ret != -1)
+                       return 0;
+               if (errno == EINTR)
+                       continue;
+               return -1;
+       }
+}
+
+int unlock_fd(int fd)
+{
+       struct flock f;
+       f.l_type = F_UNLCK;
+       f.l_whence = SEEK_SET;
+       f.l_start = 0;
+       f.l_len = 0;
+       return fcntl(fd, F_SETLKW, &f);
+}
+
+int copy_smacklabel(const char * /*source*/, const char * /*dest*/)
+{
+       return 0;
+}
+
+int remove_file(char *path)
+{
+       struct stat path_stat;
+       DIR *dp;
+       struct dirent *d;
+       int status = 0;
+
+       if (lstat(path, &path_stat) < 0) {
+               if (errno != ENOENT) {
+                       ERROR("Unable to stat : %s");
+                       return -1;
+               }
+       }
+
+       if (S_ISDIR(path_stat.st_mode)) {
+               if ((dp = opendir(path)) == NULL) {
+                       ERROR("Unable to opendir %s", path);
+                       return -1;
+               }
+
+               while ((d = readdir(dp)) != NULL) {
+                       char new_path[PATH_MAX];
+                       if (strcmp(d->d_name, ".") == 0 ||
+                           strcmp(d->d_name, "..") == 0)
+                               continue;
+
+                       snprintf(new_path, PATH_MAX, "%s/%s", path, d->d_name);
+                       if (remove_file(new_path) < 0)
+                               status = -1;
+               }
+
+               if (closedir(dp) < 0) {
+                       ERROR("Unable to close dp : %s", path);
+                       return -1;
+               }
+
+               if (rmdir(path) < 0) {
+                       ERROR("Failed to remove dir : %s, cause: %s", path,
+                             strerror(errno));
+                       return -1;
+               }
+
+       } else {
+               if (unlink(path) < 0) {
+                       ERROR("Unable to remove %s", path);
+                       return -1;
+               }
+       }
+
+       return status;
+}
+
+int copy_file(const char *source, const char *dest, int /*flags*/)
+{
+       int ret;
+       FILE *sfp, *dfp;
+       size_t nread, nwritten, size = BUF_SIZE;
+       char buffer[BUF_SIZE];
+
+       if ((sfp = fopen(source, "r")) == NULL) {
+               ERROR("Unable to open source : %s", source);
+               return -1;
+       }
+
+       if ((dfp = fopen(dest, "w+")) == NULL) {
+               ERROR("Unable to open destination : %s", dest);
+               fclose(sfp);
+               return -1;
+       }
+
+       while (1) {
+               nread = fread(buffer, 1, size, sfp);
+
+               if (nread != size && ferror(sfp)) {
+                       ERROR("Read failed");
+                       return -1;
+               } else if (nread == 0) {
+                       break;
+               }
+
+               nwritten = fwrite(buffer, 1, nread, dfp);
+
+               if (nwritten != nread) {
+                       if (ferror(dfp))
+                               ERROR("write fail");
+                       else
+                               ERROR("Unable to write all data");
+                       return -1;
+               }
+       }
+
+       fclose(sfp);
+       fclose(dfp);
+
+       ret = copy_smacklabel(source, dest);
+       if (ret != 0) {
+               ERROR("Unable to setting smack lable");
+               return -1;
+       }
+       return 0;
+}
+
+int regex_compile(regex_t * r, const char *regex_text)
+{
+       int status = regcomp(r, regex_text, REG_EXTENDED | REG_NEWLINE);
+
+       if (status != 0) {
+               char error_message[MAX_ERROR_MSG];
+
+               regerror(status, r, error_message, MAX_ERROR_MSG);
+               DEBUG("Regex error compiling '%s': %s\n",
+                     regex_text, error_message);
+               return 1;
+       }
+
+       return 0;
+}
+
+int regex_match(regex_t * r, const char *to_match)
+{
+       const char *p = to_match;
+       const int n_matches = 10;
+       regmatch_t m[n_matches];
+
+       while (1) {
+               int i = 0;
+               int nomatch = regexec(r, p, n_matches, m, 0);
+
+               if (nomatch) {
+                       DEBUG("No more matches.\n");
+                       return nomatch;
+               }
+
+               for (i = 0; i < n_matches; i++) {
+                       int start;
+                       int finish;
+            (void)start;
+            (void)finish;
+
+                       if (m[i].rm_so == -1) {
+                               break;
+                       }
+
+                       start = m[i].rm_so + (p - to_match);
+                       finish = m[i].rm_eo + (p - to_match);
+                       if (i == 0) {
+                               INFO("$& is ");
+                       } else {
+                               INFO("$%d is ", i);
+                       }
+
+                       INFO("'%.*s' (bytes %d:%d)\n", (finish - start),
+                            to_match + start, start, finish);
+               }
+
+               p += m[0].rm_eo;
+       }
+
+       return 0;
+}
+
+int get_peer_pid(int fd)
+{
+       struct ucred cred;
+       socklen_t cr_len = sizeof(cred);
+       if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &cr_len) < 0) {
+               return -1;
+       }
+       return cred.pid;
+}
+
+pid_t gettid(void)
+{
+       return syscall(__NR_gettid);
+}
+
+int set_smacklabel_fd(int fd, const char *xattr_name, const char *label)
+{
+    size_t len;
+    int ret;
+
+    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) {
+        ERROR("Set Smack lable error : %s", strerror(errno));
+    }
+    return ret;
+}
+
+int set_smacklabel(const char *path, const char *xattr_name, const char *label)
+{
+    size_t len;
+    int ret;
+
+    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) {
+        ERROR("Set Smack lable error : %s", strerror(errno));
+    }
+    return ret;
+}
+char *get_self_smacklabel(void)
+{
+       int ret;
+       int fd;
+       const char *attr_path = "/proc/self/attr/current";
+       char buffer[SMACK_LABEL_LEN+1];
+
+       bzero(buffer, SMACK_LABEL_LEN+1);
+
+       fd = open(attr_path, O_RDONLY);
+       if( fd < 0) {
+               return NULL;
+       }
+
+       ret = read(fd, buffer, SMACK_LABEL_LEN+1);
+       close(fd);
+       if (ret < 0) {
+               return NULL;
+       }
+
+       if( ret > SMACK_LABEL_LEN) {
+               //return NULL;
+       }
+    buffer[SMACK_LABEL_LEN]=0;
+
+       return strdup(buffer);
+}
+
+int get_self_cpuset(char *name, int buf_sz)
+{
+       int fd;
+       int lxc_len, ret;
+       char cpuset_path[] = "/proc/self/cpuset";
+       char current_name[NAME_MAX];
+
+       fd = open(cpuset_path, O_RDONLY);
+       if (fd < 0) {
+               return 0;
+       }
+
+       ret = read(fd, current_name, NAME_MAX - 1);
+       if (ret < 0) {
+               close(fd);
+               return -1;
+       }
+
+       current_name[ret - 1] = '\0';
+       close(fd);
+
+       lxc_len = sizeof("/lxc");
+       if( ret < lxc_len) {
+               name[0] = '/';
+               name[1] = 0;
+               return 1;
+       } else {
+               char *p;
+               p = current_name + lxc_len;
+
+               while(*p != '\0') {
+                       if(*p == '/') {
+                               *p = '\0';
+                               break;
+                       }
+                       p++;
+               }
+               snprintf(name, buf_sz, "%s", current_name+lxc_len);
+       }
+
+       return ret - lxc_len;
+}
+
+
+char * get_pid_cpuset(int pid)
+{
+       int fd;
+       int ret;
+       char cpuset_path[PATH_MAX];
+       char current_name[NAME_MAX];
+
+       snprintf(cpuset_path, PATH_MAX, "/proc/%d/cpuset", pid);
+
+       ret = access(cpuset_path, F_OK | R_OK);
+       if( ret != 0 )
+               return NULL;
+
+       fd = open(cpuset_path, O_RDONLY);
+       if (fd < 0) {
+               return NULL;
+       }
+
+       ret = read(fd, current_name, NAME_MAX - 1);
+       if (ret < 0) {
+               close(fd);
+               return NULL;
+       }
+
+       current_name[ret - 1] = 0;
+       close(fd);
+
+       INFO("cpuset path : %s, value : %s", cpuset_path, current_name);
+
+       return strdup(current_name);
+}
+
+char * read_namespace_link(const char *ns, int pid)
+{
+       char ns_path[PATH_MAX];
+       char buf[NAME_MAX];
+       int ret;
+
+       snprintf(ns_path, PATH_MAX, "/proc/%d/ns/%s", pid, ns);
+
+       ret = access(ns_path, F_OK);
+       if(ret != 0)
+               return NULL;
+
+       ret = readlink(ns_path, buf, NAME_MAX);
+       if( ret == -1 ) {
+               ERROR("Failed to readlink ns file - [%s]", ns_path);
+               return NULL;
+       }
+
+       buf[ret] = 0;
+
+       INFO("Read ns link data -pid : %d data : %s", pid, buf);
+
+       return strdup(buf);
+}
+
+// libs/device.c
+#define DEV_ITERATE_CONTINUE    0
+int dev_enumerate_nodes(const char *cname, dev_enumerator enumerator,
+                       void *data)
+{
+       int ret;
+       FILE *fp;;
+       char path[PATH_MAX], entry[64];
+
+       ret = snprintf(path, sizeof(path),
+                      "/sys/fs/cgroup/devices/lxc/%s/devices.list", cname);
+
+       if (ret < 0) {
+               ERROR("Failed to make pathname");
+               return -1;
+       }
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               ERROR("File open failed: %s(%s)", path, strerror(errno));
+               return -1;
+       }
+
+       while (fgets(entry, sizeof(entry), fp) != NULL) {
+               int major, minor;
+               char *next, *ptr = &entry[2];
+
+               major = strtol(ptr, &next, 10);
+               minor = strtol(++next, (char **)NULL, 10);
+
+               ret = enumerator(entry[0], major, minor, data);
+               if (ret != DEV_ITERATE_CONTINUE)
+                       break;
+       }
+
+       fclose(fp);
+
+       return ret;
+}
+
+int dev_terminal_enumerator(int type, int major, int minor, void *data)
+{
+       int *dev = (int*)data;
+
+       *dev = minor;
+    (void)type;
+    (void)major;
+    
+       INFO("Matched device: %c, %d, %d\n", type, major, minor);
+
+       return 1;
+}
+
+// libs/namespace.c
+pid_t get_init_pid(const char *name)
+{
+       char filename[PATH_MAX];
+       FILE *fp;
+       pid_t ret = -1;
+
+       snprintf(filename, sizeof(filename),
+                       "/sys/fs/cgroup/devices/lxc/%s/cgroup.procs", name);
+
+       fp = fopen(filename, "r");
+
+       if (fp != NULL) {
+               if (fscanf(fp, "%d", &ret) < 0) {
+                       ERROR("Failed to read %s\n", filename);
+                       ret = -2;
+               }
+               fclose(fp);
+       } else {
+               INFO("Unable to access %s\n", filename);
+               ret = errno;
+       }
+
+       return ret;
+}
+
+
+pid_t get_zone_pid(const char *name, const char *target)
+{
+       char path[PATH_MAX];
+       char cmd[PATH_MAX];
+       int res = 0, len;
+       pid_t ret = -1;
+       FILE *fp;
+
+       char *line = NULL;
+       size_t line_len;
+
+       snprintf(path, PATH_MAX,
+                "/sys/fs/cgroup/cpuset/lxc/%s/cgroup.procs", name);
+
+       res = access(path, F_OK | R_OK);
+       if (res != 0) {
+               ERROR("Failed to acess zone cgroup file: %s", path);
+               return -EINVAL;
+       }
+
+       if (target == NULL) {
+               ERROR("Failed to lookup cmdline in zone proc");
+               return -EINVAL;
+       } else {
+               len = strlen(target);
+       }
+
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               ERROR("Failed to open zone cgroup");
+               return -1;
+       }
+
+       while (getline(&line, &line_len, fp) != -1) {
+               int res;
+               pid_t pid;
+               FILE *cmdfp;
+               char cmdpath[PATH_MAX];
+
+               res = sscanf(line, "%d", &pid);
+               if (res != 1) {
+                       ERROR("Failed to read %s\n", path);
+                       res = -1;
+                       goto out;
+               }
+
+               if (pid < 0)
+                       continue;
+
+               snprintf(cmdpath, PATH_MAX, "/proc/%d/cmdline", pid);
+
+               if (access(cmdpath, F_OK | R_OK) != 0)
+                       continue;
+
+               cmdfp = fopen(cmdpath, "r");
+               if (cmdfp == NULL) {
+                       ERROR("Unable to access %s\n", cmdpath);
+                       continue;
+               }
+
+               if (fscanf(cmdfp, "%s", cmd) < 0) {
+                       ERROR("Failed to read cmdline - pid : %d\n", pid);
+                       continue;
+               }
+
+               fclose(cmdfp);
+
+               if (strncmp(cmd, target, len) == 0) {
+                       ret = pid;
+                       break;
+               }
+       }
+ out:
+       fclose(fp);
+       return ret;
+}
+
+int open_ns(pid_t pid, const char *name)
+{
+       int fd, ret;
+       char path[PATH_MAX];
+
+       ret = snprintf(path, PATH_MAX, "/proc/%d/ns/%s", pid, name);
+       if (ret < 0 || ret >= PATH_MAX) {
+               ERROR("Failed to namespace - pid %d, ns: %s ", pid, name);
+               return -EINVAL;
+       }
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               ERROR("failed to open %s\n", path);
+               return -errno;
+       }
+
+       return fd;
+}
+/*
+void enter_to_ns(pid_t pid, char *name)
+{
+       int newns;
+       char *ns[] = { "mnt", "pid", "uts", "ipc", "net" };
+       int flags[] = {
+               CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS, CLONE_NEWIPC,
+               CLONE_NEWNET
+       };
+       int size = sizeof(ns) / sizeof(char *);
+       int i, idx = size;
+
+       for (i = 0; i < size; i++) {
+               if (strncmp(ns[i], name, strlen(ns[i])) == 0) {
+                       idx = i;
+                       break;
+               }
+       }
+
+       if (idx == size) {
+               ERROR("Invalid namespace - ns: %s", name);
+               return;
+       }
+
+       newns = open_ns(pid, ns[i]);
+
+       if (setns(newns, flags[i])) {
+               ERROR("failed to setns");
+               close(newns);
+               return;
+       }
+
+       INFO("Enter namespace - init: %d , ns: %s", pid, name);
+
+       close(newns);
+       return;
+}*/
+
+// vasum/libs/vt.c
+#include <linux/kd.h>
+#include <linux/vt.h>
+static int is_console(int fd)
+{
+       char arg;
+
+       return (isatty(fd) &&
+               (ioctl(fd, KDGKBTYPE, &arg) == 0) &&
+               ((arg == KB_101) || (arg == KB_84)));
+}
+
+static int open_console(const char *path)
+{
+       int fd;
+
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               fd = open(path, O_WRONLY);
+       }
+       if (fd < 0) {
+               fd = open(path, O_RDONLY);
+       }
+       if (fd < 0) {
+               return -1;
+       }
+
+       return fd;
+}
+
+int get_console_fd(const char *path)
+{
+       int fd;
+
+       if (path) {
+               fd = open_console(path);
+               if (fd >= 0) {
+                       return fd;
+               }
+
+               return -1;
+       }
+
+       fd = open_console("/dev/tty0");
+       if (fd >= 0) {
+               return fd;
+       }
+
+       fd = open_console("/dev/console");
+       if (fd >= 0) {
+               return fd;
+       }
+
+       for (fd = 0; fd < 3; fd++) {
+               if (is_console(fd)) {
+                       return fd;
+               }
+       }
+
+       return -1;
+}
+
+int vt_switch_terminal(int id)
+{
+       int fd, ret = -1;
+
+       fd = get_console_fd(NULL);
+       if (fd < 0) {
+               return -1;
+       }
+
+       if (ioctl(fd, VT_ACTIVATE, id) < 0) {
+               goto out;
+       }
+
+       if (ioctl(fd, VT_WAITACTIVE, id) < 0) {
+               goto out;
+       }
+
+       ret = 0;
+ out:
+       close(fd);
+       return ret;
+}
+
+int vt_find_unused_terminal(void)
+{
+       int fd, nr = -1;
+
+       fd = get_console_fd(NULL);
+       if (fd < 0) {
+               perror("Terminal open failed");
+               return -1;
+       }
+
+       if (ioctl(fd, VT_OPENQRY, &nr) < 0) {
+               perror("VT_OPENQRY failed");
+               goto out;
+       }
+
+ out:
+       close(fd);
+
+       return nr;
+}
+
+int vt_query_active_terminal(void)
+{
+       int fd, ret = -1;
+       struct vt_stat vtstat;
+
+       fd = get_console_fd(NULL);
+       if (fd < 0) {
+               return -1;
+       }
+
+       if (ioctl(fd, VT_GETSTATE, &vtstat) < 0) {
+               goto out;
+       }
+
+       ret = vtstat.v_active;
+ out:
+       close(fd);
+       return ret;
+}
+
+// libs/parser.h
+struct unit_keyword_callback {
+    const char *name;
+    int (*func) (int nargs, char **args);
+};
+
+struct unit_parser {
+    struct unit_keyword_callback *kw;
+};
+
+int parse_stream(const char *name, struct unit_parser *parser);
+// libs/parser.c
+#define PARSER_MAXARGS 32
+
+#define T_EOF           1
+#define T_STATEMENT     2
+#define T_ARGUMENT     3
+#define T_NEWLINE       7
+#define T_NEWBLOCK      8
+
+struct parser_context {
+       struct unit_keyword_callback *kw;
+};
+
+struct parser_state {
+       char *ptr;
+       char *stmt;
+       int line;
+       int nexttoken;
+       void *context;
+};
+
+static void parser_init_state(struct parser_state *state, char *line)
+{
+       state->line = 1;
+       state->ptr = line;
+       state->nexttoken = 0;
+    state->stmt = NULL;
+    state->context = NULL;
+}
+
+static struct unit_keyword_callback *keyword_lookup(struct parser_context *ctx,
+                                                   const char *kw)
+{
+       int i;
+
+       for (i = 0; ctx->kw[i].name != NULL; i++) {
+               if (!strcmp(ctx->kw[i].name, kw)) {
+                       return &ctx->kw[i];
+               }
+       }
+
+       return NULL;
+}
+
+static int tokenize(struct parser_state *state)
+{
+       char *x = state->ptr;
+       char *s, *ss;
+
+       if (state->nexttoken) {
+               int t = state->nexttoken;
+               state->nexttoken = 0;
+               return t;
+       }
+
+ retry:
+       state->stmt = s = x;
+       ss = x + 1;
+ resume:
+       while (1) {
+               switch (*x) {
+               case 0:
+                       state->nexttoken = T_EOF;
+                       goto textdone;
+               case '\\':
+                       x++;
+                       switch (*x) {
+                       case 0:
+                               goto textdone;
+                       case 'n':
+                               *s++ = '\n';
+                               break;
+                       case 'r':
+                               *s++ = '\r';
+                               break;
+                       case 't':
+                               *s++ = '\t';
+                               break;
+                       case '\\':
+                               *s++ = '\\';
+                               break;
+                       case '\r':
+                               /* \ <cr> <lf> -> line continuation */
+                               if (x[1] != '\n') {
+                                       x++;
+                                       continue;
+                               }
+                       case '\n':
+                               /* \ <lf> -> line continuation */
+                               state->line++;
+                               x++;
+                               /* eat any extra whitespace */
+                               while ((*x == ' ') || (*x == '\t'))
+                                       x++;
+                               continue;
+                       default:
+                               /* unknown escape -- just copy */
+                               *s++ = *x++;
+                       }
+                       continue;
+               case ',':
+                       x++;
+                       goto textdone;
+               case '=':
+                       x++;
+                       if (ss == x) {
+                               goto retry;
+                       }
+                       goto textdone;
+               case ' ':
+               case '\t':
+               case '\r':
+                       x++;
+                       if (ss == x) {
+                               goto retry;
+                       }
+                       goto textdone;
+               case '\n':
+                       x++;
+                       if (ss == x) {
+                               state->ptr = x;
+                               return T_NEWLINE;
+                       }
+                       state->nexttoken = T_NEWLINE;
+                       goto textdone;
+               case '\'':
+               case '"':
+                       x++;
+                       for (;;) {
+                               switch (*x) {
+                               case 0:
+                                       /* unterminated quoted thing */
+                                       state->ptr = x;
+                                       return T_EOF;
+                               case '\'':
+                               case '"':
+                                       x++;
+                                       goto resume;
+                               default:
+                                       *s++ = *x++;
+                               }
+                       }
+                       break;
+               case '[':
+                       x++;
+                       goto resume;
+               case ']':
+                       x++;
+                       goto resume;
+               case '#':
+                       while (*x && (*x != '\n'))
+                               x++;
+                       if (*x == '\n') {
+                               state->ptr = x + 1;
+                               return T_NEWLINE;
+                       } else {
+                               state->ptr = x;
+                               return T_EOF;
+                       }
+                       break;
+               default:
+                       *s++ = *x++;
+               }
+       }
+
+ textdone:
+       state->ptr = x;
+       *s = 0;
+       return T_STATEMENT;
+}
+
+static int parse_statement(struct parser_context *ctx, int argc, char **argv,
+                          int (*func) (int argc, char **argv))
+{
+       struct parser_state state;
+       char *args[PARSER_MAXARGS];
+       int i, nargs, done, rc;
+       int ret = 0;
+    (void)ctx;
+
+       for (i = 0; i < argc; i++) {
+               done = nargs = 0;
+               parser_init_state(&state, argv[i]);
+
+               while (!done) {
+                       int token = tokenize(&state);
+                       switch (token) {
+                       case T_EOF:
+                               if (nargs && func) {
+                                       rc = func(nargs, args);
+                                       if (rc < 0) {
+                                               WARN("Key word callback error");
+                                       }
+                                       nargs = 0;
+                               }
+                               done = 1;
+                               break;
+                       case T_STATEMENT:
+                               if (nargs < PARSER_MAXARGS) {
+                                       args[nargs++] = state.stmt;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+int parse_stream_core(struct parser_context *ctx, char *s)
+{
+       struct unit_keyword_callback *kw;
+       struct parser_state state;
+       char *args[PARSER_MAXARGS];
+       int nargs, rc;
+
+       nargs = 0;
+       parser_init_state(&state, s);
+
+       for (;;) {
+               int token = tokenize(&state);
+               switch (token) {
+               case T_EOF:
+                       return 0;
+               case T_NEWLINE:
+                       if (nargs) {
+                               if ((kw = keyword_lookup(ctx, args[0])) != NULL) {
+                                       rc = parse_statement(ctx, nargs - 1,
+                                                            &args[1],
+                                                            kw->func);
+                                       if (rc < 0) {
+                                               return -EINVAL;
+                                       }
+                               }
+
+                               nargs = 0;
+                       }
+                       break;
+               case T_STATEMENT:
+                       if (nargs < PARSER_MAXARGS) {
+                               args[nargs++] = state.stmt;
+                       }
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/* reads a file, making sure it is terminated with \n \0 */
+static char *open_stream(const char *name, unsigned int *_sz)
+{
+       int sz, fd;
+       char *data = NULL;
+
+       fd = open(name, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+
+       sz = lseek(fd, 0, SEEK_END);
+       if (sz < 0)
+               goto oops;
+
+       if (lseek(fd, 0, SEEK_SET) != 0)
+               goto oops;
+
+       data = (char *)malloc(sz + 2);
+       if (data == 0)
+               goto oops;
+
+       if (read(fd, data, sz) != sz)
+               goto oops;
+
+       close(fd);
+
+       data[sz] = '\n';
+       data[sz + 1] = 0;
+       if (_sz)
+               *_sz = sz;
+
+       return data;
+
+ oops:
+       close(fd);
+       if (data != 0)
+               free(data);
+
+       return NULL;
+}
+
+int parse_stream(const char *name, struct unit_parser *parser)
+{
+       char *stream;
+       struct parser_context *ctx;
+
+       ctx = (struct parser_context *)malloc(sizeof(struct parser_context));
+       if (ctx == NULL) {
+               return -ENOMEM;
+       }
+
+       ctx->kw = parser->kw;
+
+       /* File open & return file context */
+       stream = open_stream(name, NULL);
+       if (stream == NULL) {
+               free(ctx);
+               return -1;
+       }
+
+       parse_stream_core(ctx, stream);
+
+       free(stream);
+       free(ctx);
+
+       return 0;
+}
+
+// dummy-ops
+static int dummy_create_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/,
+                            const char * /*template*/, int  /*flags*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_destroy_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/, int  /*force*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_start_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_shutdown_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/, int  /*force*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_lock_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/, int  /*shutdown*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_unlock_zone(vsm_context_h  /*ctx*/, const char * /*zone_name*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_set_foreground(vsm_zone_h  zone)
+{
+       if (zone == NULL)
+               return -VSM_ERROR_INVALID;
+
+       if (zone->parent == zone) {
+               return VSM_ERROR_NONE;
+       }
+       return -VSM_ERROR_NO_OBJECT;
+}
+
+static vsm_zone_h dummy_get_foreground(vsm_context_h  ctx)
+{
+       if (ctx == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       return ctx->root_zone;
+}
+
+static int dummy_iterate_zone(vsm_context_h  ctx, vsm_zone_iter_cb  callback, void *user_data)
+{
+       if( callback) {
+               callback(ctx->root_zone, user_data);
+       }
+       return VSM_ERROR_NONE;
+}
+
+static vsm_zone_h dummy_lookup_zone_by_name(vsm_context_h ctx, const char *name)
+{
+       if (strcmp(name, "") != 0) {
+               errno = ESRCH;
+               return NULL;
+       }
+
+       return ctx->root_zone;
+}
+
+static vsm_zone_h dummy_lookup_zone_by_pid(vsm_context_h ctx, pid_t  /*pid*/)
+{
+       if (ctx == NULL)
+               return NULL;
+
+       return ctx->root_zone;
+}
+
+static int dummy_attach_zone(vsm_context_h ctx, const char *zone_name,
+                            vsm_attach_command_s * command,
+                            vsm_attach_options_s * opts,
+                            pid_t * attached_process)
+{
+       pid_t pid;
+       struct vsm_attach_options_s options;
+
+       if (command == NULL || command->exec == NULL || zone_name == NULL) {
+               ERROR("Invalid arguments");
+               ctx->error = VSM_ERROR_INVALID;
+               return -VSM_ERROR_INVALID;
+       }
+
+       if (strcmp("", zone_name) != 0) {
+               ctx->error = VSM_ERROR_INVALID;
+               return -VSM_ERROR_INVALID;
+       }
+
+       if (opts == NULL) {
+               opts = &options;
+               opts->uid = getuid();
+               opts->gid = getgid();
+               opts->env_num = 0;
+               opts->extra_env = NULL;
+       }
+
+       pid = fork();
+       if (pid == 0) {
+               if (opts->extra_env != NULL) {
+                       while (*opts->extra_env)
+                               putenv(*opts->extra_env++);
+               }
+
+               if (getuid() == 0 && opts->uid != 0) {
+                       if (setuid(opts->uid) != 0) {
+                               ERROR("Failed to set uid : %d", opts->uid);
+                       }
+               } else {
+                       WARN("setuid() is not permitted");
+               }
+
+               if (getgid() == 0 && opts->gid != 0) {
+                       if (setgid(opts->gid) != 0) {
+                               ERROR("Failed to set gid : %d", opts->gid);
+                       }
+               } else {
+                       WARN("setgid() is not permitted");
+               }
+
+               if (execvp(command->exec, command->argv) < 0) {
+                       ERROR("exevp failed : %s, %s", command->exec,
+                             strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+       } else {
+               *attached_process = pid;
+       }
+
+       return VSM_ERROR_NONE;
+}
+
+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;
+       int ret, status;
+
+       ret = dummy_attach_zone(ctx, zone_name, command, opts, &pid);
+       if (ret != VSM_ERROR_NONE) {
+               ERROR("API Failed.");
+               return ret;
+       }
+
+       status = wait_for_pid_status(pid);
+       if (status == -1) {
+               ctx->error = VSM_ERROR_GENERIC;
+               return -VSM_ERROR_GENERIC;
+       }
+
+       INFO("attached process extied : pid - %d, exit code : %d", pid,
+            WEXITSTATUS(status));
+
+       return status;
+}
+
+static vsm_zone_h dummy_join_zone(vsm_zone_h zone)
+{
+       if (zone == NULL) {
+               errno = EINVAL;
+               return NULL;
+       }
+       if (zone != zone->parent) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       return zone;
+}
+
+static int dummy_is_equivalent_zone(vsm_context_h  /*ctx*/, pid_t  /*pid*/)
+{
+       return 1;
+}
+
+static int dummy_get_host_pid(vsm_zone_h zone, pid_t pid)
+{
+       if(zone == zone->parent)
+               return pid;
+
+       return -VSM_ERROR_NO_OBJECT;
+}
+
+static int dummy_grant_device(vsm_zone_h  /*zone*/, const char * /*path*/, uint32_t  /*flags*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_revoke_device(vsm_zone_h  /*zone*/, const char * /*path*/)
+{
+       return -VSM_ERROR_NOT_SUPPORTED;
+}
+
+static int dummy_declare_file(vsm_context_h  /*ctx*/, vsm_fso_type_t  /*ftype*/,
+                             const char * /*path*/, int  /*flags*/, vsm_mode_t  /*mode*/)
+{
+       return VSM_ERROR_NONE;
+}
+
+static int dummy_declare_link(vsm_context_h  /*ctx*/, const char *source,
+                             const char * /*target*/)
+{
+       int ret;
+
+       ret = access(source, F_OK);
+       if (ret != 0)
+               return -VSM_ERROR_NO_OBJECT;
+
+       return VSM_ERROR_NONE;
+}
+
+struct vasum_ops dummy_ops;
+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;
+       dummy_ops.shutdown_zone = dummy_shutdown_zone;
+       dummy_ops.lock_zone = dummy_lock_zone;
+       dummy_ops.unlock_zone = dummy_unlock_zone;
+       dummy_ops.set_foreground = dummy_set_foreground;
+       dummy_ops.get_foreground = dummy_get_foreground;
+       dummy_ops.iterate_zone = dummy_iterate_zone;
+       dummy_ops.lookup_zone_by_name = dummy_lookup_zone_by_name;
+       dummy_ops.lookup_zone_by_pid = dummy_lookup_zone_by_pid;
+       dummy_ops.attach_zone = dummy_attach_zone;
+       dummy_ops.attach_zone_wait = dummy_attach_zone_wait;
+       dummy_ops.join_zone = dummy_join_zone;
+       dummy_ops.is_equivalent_zone = dummy_is_equivalent_zone;
+       dummy_ops.get_host_pid = dummy_get_host_pid;
+       dummy_ops.grant_device = dummy_grant_device;
+       dummy_ops.revoke_device = dummy_revoke_device;
+       dummy_ops.declare_file = dummy_declare_file;
+       dummy_ops.declare_link = dummy_declare_link;
+    return 0;
+}
+int dummy_ops_init_i = dummy_ops_init();
+
+} //extern "C"
diff --git a/client/wrapper-compat.h b/client/wrapper-compat.h
new file mode 100644 (file)
index 0000000..90b44fb
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Krzysztof Dynowski <k.dynowski@samsung.com>
+ *
+ *  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  Krzysztof Dynowski (k.dynowski@samsung.com)
+ * @brief   Vasum old API compatibility functions
+ */
+
+#ifndef __CLIENT_WRAPPER_COMPAT__
+#define __CLIENT_WRAPPER_COMPAT__
+
+#include "vasum.h"
+#include <sys/epoll.h>
+
+extern "C" {
+typedef int (*fp_create_zone) (vsm_context_h ctx, const char *zone_name,
+                   const char *template_name, int flag);
+typedef int (*fp_destroy_zone) (vsm_context_h ctx, const char *zone_name,
+                int force);
+typedef int (*fp_start_zone) (vsm_context_h ctx, const char *zone_name);
+typedef int (*fp_shutdown_zone) (vsm_context_h ctx, const char *zone_name,
+                 int force);
+typedef int (*fp_lock_zone) (vsm_context_h ctx, const char *zone_name,
+                 int shutdown);
+typedef int (*fp_unlock_zone) (vsm_context_h ctx, const char *zone_name);
+typedef int (*fp_set_foreground) (vsm_zone_h zone);
+typedef vsm_zone_h(*fp_get_foreground) (vsm_context_h ctx);
+typedef int (*fp_iterate_zone) (vsm_context_h ctx, vsm_zone_iter_cb callback,
+                void *user_data);
+typedef vsm_zone_h(*fp_lookup_zone_by_name) (vsm_context_h ctx,
+                         const char *name);
+typedef vsm_zone_h(*fp_lookup_zone_by_pid) (vsm_context_h ctx, pid_t pid);
+typedef int (*fp_attach_zone) (vsm_context_h ctx, const char *zone_name,
+                   vsm_attach_command_s * command,
+                   vsm_attach_options_s * opt,
+                   pid_t * attached_process);
+typedef int (*fp_attach_zone_wait) (vsm_context_h ctx, const char *zone_name,
+                    vsm_attach_command_s * command,
+                    vsm_attach_options_s * opt);
+typedef vsm_zone_h(*fp_join_zone) (vsm_zone_h zone);
+typedef int (*fp_is_equivalent_zone) (vsm_context_h ctx, pid_t pid);
+typedef int (*fp_get_host_pid) (vsm_zone_h zone, pid_t pid);
+typedef int (*fp_grant_device) (vsm_zone_h zone, const char *path,
+                uint32_t flags);
+typedef int (*fp_revoke_device) (vsm_zone_h zone, const char *path);
+typedef int (*fp_declare_file) (vsm_context_h ctx, vsm_fso_type_t ftype,
+                const char *path, int flags, vsm_mode_t mode);
+typedef int (*fp_declare_link) (vsm_context_h ctx, const char *source,
+                const char *target);
+struct vasum_ops {
+    fp_create_zone create_zone;
+    fp_destroy_zone destroy_zone;
+    fp_start_zone start_zone;
+    fp_shutdown_zone shutdown_zone;
+    fp_lock_zone lock_zone;
+    fp_unlock_zone unlock_zone;
+    fp_set_foreground set_foreground;
+    fp_get_foreground get_foreground;
+    fp_iterate_zone iterate_zone;
+    fp_lookup_zone_by_name lookup_zone_by_name;
+    fp_lookup_zone_by_pid lookup_zone_by_pid;
+    fp_attach_zone attach_zone;
+    fp_attach_zone_wait attach_zone_wait;
+    fp_join_zone join_zone;
+    fp_get_host_pid get_host_pid;
+    fp_is_equivalent_zone is_equivalent_zone;
+    fp_grant_device grant_device;
+    fp_revoke_device revoke_device;
+    fp_declare_file declare_file;
+    fp_declare_link declare_link;
+};
+
+#define SERVICEPATH "\0/domain-control/service.sock"
+struct mainloop {
+    int     epfd;
+    pthread_mutex_t ml_mutex;
+    pthread_rwlock_t lock;
+    struct adt_list watches;
+};
+struct mxe_emple;
+struct mxe_endpoint;
+struct mxe_emple {
+    int signature;
+    int refcnt;
+    void *callback;
+    void *data;
+    struct mxe_proxy *proxy;
+    struct adt_list queue;
+};
+struct mxe_engine {
+    void *data;
+    struct mainloop *mainloop;
+    pthread_rwlock_t endpoint_lock;
+    struct adt_list endpoints;
+};
+struct mxe_endpoint {
+    int fd;
+    int type;
+    struct mxe_engine *engine;
+    pthread_rwlock_t queue_lock;
+    pthread_mutex_t rd_mutex;
+    pthread_mutex_t wr_mutex;
+    struct adt_list queue;
+    struct adt_list list;
+};
+
+typedef enum {
+    ML_EVT_IN   = EPOLLIN,
+    ML_EVT_OUT  = EPOLLOUT,
+    ML_EVT_RDHUP    = EPOLLRDHUP,
+    ML_EVT_ERROR    = EPOLLERR,
+    ML_EVT_HUP  = EPOLLHUP,
+    ML_EVT_ET   = EPOLLET
+}mainloop_event;
+
+typedef struct vsm_context {
+    struct mxe_endpoint *signal_channel;
+    struct mxe_endpoint *manage_method_channel;
+    struct mxe_endpoint *unpriv_method_channel;
+    vsm_error_e error;
+    pthread_rwlock_t lock;
+    struct adt_list listeners;
+    struct vsm_zone *root_zone;
+    struct vsm_zone *foreground_zone;
+    struct adt_list sc_listeners;
+    struct adt_list ev_listeners;
+    const struct vasum_ops *vsm_ops;
+} vsm_context_s;
+
+typedef struct vsm_zone {
+    struct vsm_zone *parent;
+    char *name;
+    char *type;
+    int terminal;
+    vsm_zone_state_t state;
+    char *rootfs_path;
+    pthread_rwlock_t lock;
+    struct adt_list children;
+    struct adt_list devices;
+    struct adt_list netdevs;
+    void *user_data;
+    struct adt_list list;
+    struct vsm_context *ctx;
+    int id;
+} vsm_zone_s;
+
+typedef struct vsm_netdev {
+    struct vsm_zone *zone;
+    char *name;
+    vsm_netdev_type_t type;
+    struct adt_list list;
+} vsm_netdev_s;
+
+
+typedef int (*dev_enumerator)(int type, int major, int minor, void *data);
+typedef int (*mainloop_callback)(int fd, mainloop_event event, void *data, struct mainloop *mainloop);
+
+struct mainloop *mainloop_create(void);
+struct mxe_endpoint *mxe_create_client(struct mxe_engine *engine, const char * /*addr*/);
+struct mxe_engine *mxe_prepare_engine(struct mainloop *mainloop, void *data);
+
+int wait_for_pid_status(pid_t  pid);
+
+int vsm_add_state_changed_callback(vsm_context_h  /*ctx*/, vsm_zone_state_changed_cb  /*callback*/, void * /*user_data*/);
+int vsm_del_state_changed_callback(vsm_context_h  /*ctx*/, int  /*id*/);
+const char * vsm_get_zone_rootpath(vsm_zone_h  /*zone*/);
+const char * vsm_get_zone_name(vsm_zone_h  /*zone*/);
+int vsm_is_host_zone(vsm_zone_h  /*zone*/);
+vsm_zone_h vsm_join_zone(vsm_zone_h zone);
+int vsm_canonicalize_path(const char *input_path, char **output_path);
+
+} //extern "C"
+
+#endif
index dfb0385..adca814 100644 (file)
@@ -102,7 +102,6 @@ void EventPoll::removeFD(const int fd)
 }
 
 bool EventPoll::dispatchIteration(const int timeoutMs)
-
 {
     for (;;) {
         epoll_event event;
index 64c3662..c2b6eb9 100644 (file)
@@ -10,6 +10,7 @@
 %define tty_group tty
 
 Name:           vasum
+Epoch:          1
 Version:        0.1.1
 Release:        0
 Source0:        %{name}-%{version}.tar.gz
@@ -27,6 +28,7 @@ BuildRequires:  pkgconfig(libsystemd-daemon)
 BuildRequires:  pkgconfig(sqlite3)
 Requires(post): libcap-tools
 Requires:       bridge-utils
+Requires:       libjson >= 0.10
 
 %description
 This package provides a daemon used to manage zones - start, stop and switch
@@ -115,7 +117,8 @@ fi
 %package client
 Summary:          Vasum Client
 Group:            Development/Libraries
-Requires:         vasum = %{version}-%{release}
+Requires:         vasum = %{epoch}:%{version}-%{release}
+Obsoletes:        vasum < 1:0
 Requires(post):   /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 
@@ -125,7 +128,9 @@ Library interface to the vasum daemon
 %files client
 %manifest packaging/libvasum-client.manifest
 %defattr(644,root,root,755)
-%attr(755,root,root) %{_libdir}/libvasum.so.0.0.1
+%attr(755,root,root) %{_libdir}/libvasum-client.so.0.1.1
+%{_libdir}/libvasum-client.so.0
+%attr(755,root,root) %{_libdir}/libvasum.so.0.1.1
 %{_libdir}/libvasum.so.0
 
 %post client -p /sbin/ldconfig
@@ -146,6 +151,7 @@ Development package including the header files for the client library
 %files devel
 %manifest packaging/vasum.manifest
 %defattr(644,root,root,755)
+%{_libdir}/libvasum-client.so
 %{_libdir}/libvasum.so
 %{_includedir}/vasum
 %{_libdir}/pkgconfig/vasum.pc
index 20ae2f9..65646ea 100644 (file)
@@ -23,6 +23,8 @@ FILE(GLOB_RECURSE project_SRCS *.cpp *.hpp)
 FILE(GLOB_RECURSE common_SRCS ${COMMON_FOLDER}/*.cpp ${COMMON_FOLDER}/*.hpp)
 FILE(GLOB         server_SRCS ${SERVER_FOLDER}/*.cpp ${SERVER_FOLDER}/*.hpp)
 FILE(GLOB         client_SRCS ${CLIENT_FOLDER}/*.cpp ${CLIENT_FOLDER}/*.h)
+FILE(GLOB         client_SRCS_rm ${CLIENT_FOLDER}/vasum-wrapper*.cpp)
+LIST(REMOVE_ITEM client_SRCS ${client_SRCS_rm})
 FILE(GLOB         socket_test_SRCS ${SOCKET_TEST_FOLDER}/*.cpp ${SOCKET_TEST_FOLDER}/*.hpp)
 
 FILE(GLOB         main_SRC ${SERVER_FOLDER}/main.cpp)
@@ -41,7 +43,7 @@ ADD_EXECUTABLE(${UT_SERVER_CODENAME} ${project_SRCS} ${common_SRCS} ${server_SRC
 ADD_EXECUTABLE("vasum-client-c-api-compile-test" client/client-c-api-compile-test.c)
 
 ## A stub mini-service to test socket functionality
-ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS})
+ADD_EXECUTABLE(${SOCKET_TEST_CODENAME} ${socket_test_SRCS} ${common_SRCS} ${client_SRCS})
 
 
 ## Link libraries ##############################################################