On Tue, Nov 12, 2013 at 10:47:06PM -0500, S.Çağlar Onur wrote:
> 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
> 

lxc-device which currently implements something like that as a tool in
python also lets the user set an alternate path inside the container.
Can we have the C API offer the same feature so I can use the new API
instead of keeping my own implementation?

> 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

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
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

Reply via email to