--- /dev/null
+/*
+ * 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;
+}
+
+
/*
- * 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.
#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
* @{
*/
* @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
--- /dev/null
+/*
+ * 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"