Quoting Christian Seiler (christ...@iwakd.de):
> Add funbction to mount cgroup filesystem hierarchy into the container,
> allowing only access to the parts that the container should have access
> to, but none else.
> 
> Signed-off-by: Christian Seiler <christ...@iwakd.de>

Acked-by: Serge E. Hallyn <serge.hal...@ubuntu.com>

This looks good to me.  As I say it's not working for me, but the patch
itself looks fine.

> ---
>  src/lxc/cgroup.c |  127 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/cgroup.h |    2 +
>  2 files changed, 129 insertions(+)
> 
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index ad95fc4..876c60c 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -34,6 +34,7 @@
>  #include <sys/stat.h>
>  #include <sys/param.h>
>  #include <sys/inotify.h>
> +#include <sys/mount.h>
>  #include <netinet/in.h>
>  #include <net/if.h>
>  
> @@ -1200,6 +1201,132 @@ int lxc_setup_cgroup_devices(struct lxc_handler *h, 
> struct lxc_list *cgroup_sett
>       return do_setup_cgroup(h, cgroup_settings, true);
>  }
>  
> +int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info 
> *base_info)
> +{
> +     size_t bufsz = strlen(root) + sizeof("/sys/fs/cgroup");
> +     char *path = NULL;
> +     char **parts = NULL;
> +     char *dirname = NULL;
> +     char *abs_path = NULL;
> +     char *abs_path2 = NULL;
> +     struct cgroup_process_info *info;
> +     int r, saved_errno = 0;
> +
> +     path = calloc(1, bufsz);
> +     if (!path)
> +             return -1;
> +     snprintf(path, bufsz, "%s/sys/fs/cgroup", root);
> +     r = mount("cgroup_root", path, "tmpfs", 
> MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME, "size=10240k,mode=755");
> +     if (r < 0) {
> +             SYSERROR("could not mount tmpfs to /sys/fs/cgroup in the 
> container");
> +             return -1;
> +     }
> +
> +     /* now mount all the hierarchies we care about */
> +     for (info = base_info; info; info = info->next) {
> +             size_t subsystem_count, i;
> +             struct cgroup_mount_point *mp = info->designated_mount_point;
> +             if (!mp)
> +                     mp = lxc_cgroup_find_mount_point(info->hierarchy, 
> info->cgroup_path, true);
> +             if (!mp) {
> +                     SYSERROR("could not find original mount point for 
> cgroup hierarchy while trying to mount cgroup filesystem");
> +                     goto out_error;
> +             }
> +
> +             subsystem_count = lxc_array_len((void 
> **)info->hierarchy->subsystems);
> +             parts = calloc(subsystem_count + 1, sizeof(char *));
> +             if (!parts)
> +                     goto out_error;
> +
> +             for (i = 0; i < subsystem_count; i++) {
> +                     if (!strncmp(info->hierarchy->subsystems[i], "name=", 
> 5))
> +                             parts[i] = info->hierarchy->subsystems[i] + 5;
> +                     else
> +                             parts[i] = info->hierarchy->subsystems[i];
> +             }
> +             dirname = lxc_string_join(",", (const char **)parts, false);
> +             if (!dirname)
> +                     goto out_error;
> +
> +             /* create subsystem directory */
> +             abs_path = lxc_append_paths(path, dirname);
> +             if (!abs_path)
> +                     goto out_error;
> +             r = mkdir_p(abs_path, 0755);
> +             if (r < 0 && errno != EEXIST) {
> +                     SYSERROR("could not create cgroup subsystem directory 
> /sys/fs/cgroup/%s", dirname);
> +                     goto out_error;
> +             }
> +
> +             /* create path for container's cgroup */
> +             abs_path2 = lxc_append_paths(abs_path, info->cgroup_path);
> +             if (!abs_path2)
> +                     goto out_error;
> +             r = mkdir_p(abs_path2, 0755);
> +             if (r < 0 && errno != EEXIST) {
> +                     SYSERROR("could not create cgroup directory 
> /sys/fs/cgroup/%s%s", dirname, info->cgroup_path);
> +                     goto out_error;
> +             }
> +
> +             free(abs_path);
> +             abs_path = NULL;
> +
> +             /* bind-mount container's cgroup to that directory */
> +             abs_path = cgroup_to_absolute_path(mp, info->cgroup_path, NULL);
> +             if (!abs_path)
> +                     goto out_error;
> +             r = mount(abs_path, abs_path2, "none", MS_BIND, 0);
> +             if (r < 0) {
> +                     SYSERROR("error bind-mounting %s to %s", abs_path, 
> abs_path2);
> +                     goto out_error;
> +             }
> +
> +             free(abs_path);
> +             free(abs_path2);
> +             abs_path = NULL;
> +             abs_path2 = NULL;
> +
> +             /* add symlinks for every single subsystem */
> +             if (subsystem_count > 1) {
> +                     for (i = 0; i < subsystem_count; i++) {
> +                             abs_path = lxc_append_paths(path, parts[i]);
> +                             if (!abs_path)
> +                                     goto out_error;
> +                             r = symlink(dirname, abs_path);
> +                             if (r < 0)
> +                                     WARN("could not create symlink %s -> %s 
> in /sys/fs/cgroup of container", parts[i], dirname);
> +                             free(abs_path);
> +                             abs_path = NULL;
> +                     }
> +             }
> +             free(dirname);
> +             free(parts);
> +             dirname = NULL;
> +             parts = NULL;
> +     }
> +
> +     /* try to remount the tmpfs readonly, since the container shouldn't
> +      * change anything (this will also make sure that trying to create
> +      * new cgroups outside the allowed area fails with an error instead
> +      * of simply causing this to create directories in the tmpfs itself)
> +      */
> +     mount(NULL, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
> +
> +     free(path);
> +
> +     return 0;
> +
> +out_error:
> +     saved_errno = errno;
> +     free(path);
> +     free(dirname);
> +     free(parts);
> +     free(abs_path);
> +     free(abs_path2);
> +     errno = saved_errno;
> +     return -1;
> +}
> +
>  int lxc_cgroup_nrtasks_handler(struct lxc_handler *handler)
>  {
>       struct cgroup_process_info *info = handler->cgroup;
> diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h
> index 2555390..ad9d596 100644
> --- a/src/lxc/cgroup.h
> +++ b/src/lxc/cgroup.h
> @@ -160,6 +160,8 @@ struct lxc_list;
>  extern int lxc_setup_cgroup_without_devices(struct lxc_handler *h, struct 
> lxc_list *cgroup_settings);
>  extern int lxc_setup_cgroup_devices(struct lxc_handler *h, struct lxc_list 
> *cgroup_settings);
>  
> +extern int lxc_setup_mount_cgroup(const char *root, struct 
> cgroup_process_info *base_info);
> +
>  extern int lxc_cgroup_nrtasks_handler(struct lxc_handler *handler);
>  
>  #endif
> -- 
> 1.7.10.4
> 
> 
> ------------------------------------------------------------------------------
> How ServiceNow helps IT people transform IT departments:
> 1. Consolidate legacy IT systems to a single system of record for IT
> 2. Standardize and globalize service processes across IT
> 3. Implement zero-touch automation to replace manual, redundant tasks
> http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. Consolidate legacy IT systems to a single system of record for IT
2. Standardize and globalize service processes across IT
3. Implement zero-touch automation to replace manual, redundant tasks
http://pubads.g.doubleclick.net/gampad/clk?id=51271111&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