Adding block/char devices to running container is a common operation so provide a common implementation for users to consume.
changes since v2; * removed duplicated code Signed-off-by: S.Çağlar Onur <cag...@10ur.org> --- src/lxc/lxccontainer.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lxc/lxccontainer.h | 9 ++++++ 2 files changed, 93 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 05ca643..c21bc96 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -62,6 +62,8 @@ #endif #endif +#define MAX_BUFFER 4096 + lxc_log_define(lxc_container, lxc); static bool file_exists(char *f) @@ -2920,6 +2922,86 @@ static bool lxcapi_may_control(struct lxc_container *c) return lxc_try_cmd(c->name, c->config_path) == 0; } +static bool add_remove_device_node(struct lxc_container *c, char *src_path, bool add) +{ + int ret; + struct stat st; + char value[MAX_BUFFER]; + char dest_path[MAXPATHLEN]; + + /* make sure container is running */ + if (!c->is_running(c)) { + ERROR("container is not running"); + return false; + } + + /* prepare dest_path */ + ret = snprintf(dest_path, MAXPATHLEN, "/proc/%d/root%s", c->init_pid(c), src_path); + if (ret < 0 || ret >= MAXPATHLEN) + return false; + + if (add) { + /* make sure that we can access src_path */ + if(access(src_path, F_OK) < 0 || stat(src_path, &st) < 0) + return false; + } else { + /* make sure that we can access dest_path */ + if(access(dest_path, F_OK) < 0 || stat(dest_path, &st) < 0) + return false; + } + + /* continue if path is character device or block device */ + if S_ISCHR(st.st_mode) + ret = snprintf(value, MAX_BUFFER, "c %d:%d rwm", major(st.st_rdev), minor(st.st_rdev)); + else if S_ISBLK(st.st_mode) + ret = snprintf(value, MAX_BUFFER, "b %d:%d rwm", major(st.st_rdev), minor(st.st_rdev)); + else + return false; + + /* check snprintf return code */ + if (ret < 0 || ret >= MAX_BUFFER) + return false; + + /* remove dest_path if it exists */ + if(access(dest_path, F_OK) == 0) { + if (unlink(dest_path) < 0) { + ERROR("unlink failed"); + return false; + } + } + + if (add) { + /* create the device node */ + if (mknod(dest_path, st.st_mode, st.st_rdev) < 0) { + ERROR("mknod failed"); + return false; + } + + /* add to device list */ + if (!c->set_cgroup_item(c, "devices.allow", value)) { + ERROR("set_cgroup_item failed while adding the device node"); + return false; + } + } else { + /* remove from device list */ + if (!c->set_cgroup_item(c, "devices.deny", value)) { + ERROR("set_cgroup_item failed while removing the device node"); + return false; + } + } + return true; +} + +static bool lxcapi_add_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, true); +} + +static bool lxcapi_remove_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, false); +} + static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) { va_list ap; @@ -3041,6 +3123,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c->snapshot_restore = lxcapi_snapshot_restore; c->snapshot_destroy = lxcapi_snapshot_destroy; c->may_control = lxcapi_may_control; + c->add_device_node = lxcapi_add_device_node; + c->remove_device_node = lxcapi_remove_device_node; /* we'll allow the caller to update these later */ if (lxc_log_init(NULL, "none", NULL, "lxc_container", 0, c->config_path)) { diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 486035a..a94de9a 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -236,6 +236,15 @@ struct lxc_container { * and the caller may not access it. Return true otherwise. */ bool (*may_control)(struct lxc_container *c); + + /* + * Returns true if given device succesfully added to container + */ + bool (*add_device_node)(struct lxc_container *c, char *path); + /* + * Returns true if given device succesfully removed from container + */ + bool (*remove_device_node)(struct lxc_container *c, char *path); }; struct lxc_snapshot { -- 1.8.3.2 ------------------------------------------------------------------------------ DreamFactory - Open Source REST & JSON Services for HTML5 & Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471&iu=/4140/ostg.clktrk _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel