On 06/07/2011 02:34 PM, Michal Hocko wrote:
> There is no general rule on which permissions make sense for files in
> different subsystems. Nevertheless the kernel creates those files with
> the maximum allowed permissions for owner so we should use its part as
> an umask for group and others permissions as well.
> This means that if we specify 777 for file_mode we will end up having
> same permissions as owner what ever they are.
>
> The primary intelligence is implemented in cg_chmod_path function which
> takes an argument which says whether user permissions should be used
> as a template.
>
> This patch adds and exports cgroup_set_permissions which sets
> permissions of all cgroup files according to cgroup data structure. It
> uses cg_chmod_recursive_controller and cg_chmod_path internally.
>
> Example:
> /etc/cgconfig.conf:
> mount {
> cpu = /cgroup/cpuctl/;
> }
>
> group devel {
> perm {
> task {
> uid = root;
> gid = cgroup;
> fperm = 770;
> }
> admin {
> uid = root;
> gid = cgroup;
> dperm = 775;
> fperm = 770;
> }
> }
> cpu {
> cpu.shares = 5120;
> }
> }
>
> cd /cgroup/cpuctl/devel/
> ls -la
> drwxrwxr-x 2 root cgroup 0 May 19 16:42 .
> drwxr-xr-x 4 root root 0 May 19 16:14 ..
> -rw-rw---- 1 root cgroup 0 May 19 16:42 cgroup.clone_children
> --w--w---- 1 root cgroup 0 May 19 16:42 cgroup.event_control
> -r--r----- 1 root cgroup 0 May 19 16:42 cgroup.procs
> -rw-rw---- 1 root cgroup 0 May 19 16:42 cpu.rt_period_us
> -rw-rw---- 1 root cgroup 0 May 19 16:42 cpu.rt_runtime_us
> -rw-rw---- 1 root cgroup 0 May 19 16:42 cpu.shares
> -rw-rw---- 1 root cgroup 0 May 19 16:42 notify_on_release
> -rw-rw---- 1 root cgroup 0 May 19 16:42 tasks
>
> Signed-off-by: Michal Hocko <[email protected]>
> ---
> include/libcgroup/groups.h | 8 ++++
> src/api.c | 80
> +++++++++++++++++++++++++++++++++-----------
> src/libcgroup-internal.h | 11 ++++++
> src/libcgroup.map | 2 +-
> src/tools/cgcreate.c | 5 ++-
> 5 files changed, 83 insertions(+), 23 deletions(-)
>
> diff --git a/include/libcgroup/groups.h b/include/libcgroup/groups.h
> index 61f18a0..3271c52 100644
> --- a/include/libcgroup/groups.h
> +++ b/include/libcgroup/groups.h
> @@ -341,6 +341,14 @@ int cgroup_get_uid_gid(struct cgroup *cgroup, uid_t
> *tasks_uid,
> gid_t *tasks_gid, uid_t *control_uid, gid_t *control_gid);
>
> /**
> + * Sets file permissions of the group's control and tasks files according
> + * to the configuration stored in the given @c cgroup structure.
> + * @param path Path to the group.
> + * @param cgroup
> + */
> +int cgroup_set_permissions(const char *path, struct cgroup *cgroup);
I got probably misunderstood, what I wanted was
cgroup_set_permissions(struct cgroup *cgroup,
mode_t control_fperm,
mode_t control_dperm,
mode_t task_fperm);
which would just set the values in the struct cgroup and
cgroup_create_cgroup() would just use them, similarly to
cgroup_set_uid_gid() in wrapper.c.
> +
> +/**
> * @}
> * @name Group parameters
> * These are functions can read or modify parameter of a group.
> diff --git a/src/api.c b/src/api.c
> index 23772f3..c3d5a9d 100644
> --- a/src/api.c
> +++ b/src/api.c
> @@ -175,12 +175,47 @@ static int cg_chown_recursive(char **path, uid_t owner,
> gid_t group)
> return ret;
> }
>
> +int cg_chmod_path(const char *path, mode_t mode, int owner_is_umask)
> +{
> + struct stat buf;
> + mode_t mask = -1U;
> +
> + if (owner_is_umask) {
> + mode_t umask, gmask, omask;
> +
> + /*
> + * Use owner permissions as an umask for group and others
> + * permissions because we trust kernel to initialize owner
> + * permissions to something useful.
> + */
> + if (stat(path, &buf) == -1)
> + goto fail;
> + umask = S_IRWXU & buf.st_mode;
> + gmask = umask >> 3;
> + omask = gmask >> 3;
> +
> + mask = umask|gmask|omask;
> + }
> +
> + if (chmod(path, mode & mask))
> + goto fail;
> +
> + return 0;
> +
> +fail:
> + last_errno = errno;
> + return ECGOTHER;
> +}
> +
> int cg_chmod_file(FTS *fts, FTSENT *ent, mode_t dir_mode,
> - int dirm_change, mode_t file_mode, int filem_change)
> + int dirm_change, mode_t file_mode, int filem_change,
> + int owner_is_umask)
> {
> int ret = 0;
> const char *filename = fts->fts_path;
> +
> cgroup_dbg("chmod: seeing file %s\n", filename);
> +
> switch (ent->fts_info) {
> case FTS_ERR:
> errno = ent->fts_errno;
> @@ -190,20 +225,16 @@ int cg_chmod_file(FTS *fts, FTSENT *ent, mode_t
> dir_mode,
> case FTS_DNR:
> case FTS_DP:
> if (dirm_change)
> - ret = chmod(filename, dir_mode);
> + ret = cg_chmod_path(filename, dir_mode, owner_is_umask);
> break;
> case FTS_F:
> case FTS_NSOK:
> case FTS_NS:
> case FTS_DEFAULT:
> if (filem_change)
> - ret = chmod(filename, file_mode);
> + ret = cg_chmod_path(filename, file_mode,
> owner_is_umask);
> break;
> }
> - if (ret < 0) {
> - last_errno = errno;
> - ret = ECGOTHER;
> - }
> return ret;
> }
>
> @@ -212,7 +243,7 @@ int cg_chmod_file(FTS *fts, FTSENT *ent, mode_t dir_mode,
> * TODO: Need to decide a better place to put this function.
> */
> static int cg_chmod_recursive_controller(char *path, mode_t dir_mode,
> - int dirm_change, mode_t file_mode, int filem_change)
> + int dirm_change, mode_t file_mode, int filem_change, int
> owner_is_umask)
> {
> int ret = 0;
> int final_ret =0;
> @@ -239,7 +270,7 @@ static int cg_chmod_recursive_controller(char *path,
> mode_t dir_mode,
> break;
> }
> ret = cg_chmod_file(fts, ent, dir_mode, dirm_change,
> - file_mode, filem_change);
> + file_mode, filem_change, owner_is_umask);
> if (ret) {
> last_errno = errno;
> final_ret = ECGOTHER;
> @@ -269,7 +300,7 @@ int cg_chmod_recursive(struct cgroup *cgroup, mode_t
> dir_mode,
> break;
> }
> ret = cg_chmod_recursive_controller(path, dir_mode, dirm_change,
> - file_mode, filem_change);
> + file_mode, filem_change, 0);
> if (ret)
> final_ret = ret;
> }
> @@ -277,6 +308,23 @@ int cg_chmod_recursive(struct cgroup *cgroup, mode_t
> dir_mode,
> return final_ret;
> }
>
> +int cgroup_set_permissions(const char *path, struct cgroup *cgroup)
> +{
> + int error;
> +
> + error = cg_chmod_recursive_controller(path,
> + cgroup->control_dperm,
> + cgroup->control_dperm != NO_PERMS,
> + cgroup->control_fperm,
> + cgroup->control_fperm != NO_PERMS,
> + 1);
api.c:320:4: warning: passing argument 1 of
'cg_chmod_recursive_controller' discards 'const' qualifier from pointer
target type [enabled by default]
> +
> + if (!error && cgroup->task_fperm != NO_PERMS)
> + error = cg_chmod_path(path, cgroup->task_fperm, 1);
> +
> + return error;
> +
> +}
> static char *cgroup_basename(const char *path)
> {
> char *base;
> @@ -1475,13 +1523,8 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int
> ignore_ownership)
> cgroup_dbg("Changing ownership of %s\n", fts_path[0]);
> error = cg_chown_recursive(fts_path,
> cgroup->control_uid, cgroup->control_gid);
> - if (!error) {
> - error =
> cg_chmod_recursive_controller(fts_path[0],
> -
> cgroup->control_dperm,
> -
> cgroup->control_dperm != NO_PERMS,
> -
> cgroup->control_fperm,
> -
> cgroup->control_fperm != NO_PERMS);
> - }
> + if (!error)
> + error = cgroup_set_permissions(fts_path[0],
> cgroup);
> }
>
> if (error)
> @@ -1528,9 +1571,6 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int
> ignore_ownership)
> }
> error = chown(path, cgroup->tasks_uid,
> cgroup->tasks_gid);
> - if (!error && cgroup->task_fperm != NO_PERMS)
> - error = chmod(path, cgroup->task_fperm);
> -
> if (error) {
> last_errno = errno;
> error = ECGOTHER;
> diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
> index e79c038..b57a887 100644
> --- a/src/libcgroup-internal.h
> +++ b/src/libcgroup-internal.h
> @@ -250,6 +250,17 @@ extern int cgroup_dictionary_iterator_next(void **handle,
> */
> extern void cgroup_dictionary_iterator_end(void **handle);
>
> +/**
> + * Changes permissions for given path. If owner_is_umask is specified
> + * then it uses owner permissions as a mask for group and others permissions.
> + *
> + * @param path Patch to chmod.
> + * @param mode File permissions to set.
> + * @param owner_is_umask Flag whether path owner permissions should be used
> + * as a mask for group and others permissions.
> + */
> +int cg_chmod_path(const char *path, mode_t mode, int owner_is_umask);
> +
> __END_DECLS
>
> #endif
> diff --git a/src/libcgroup.map b/src/libcgroup.map
> index fb30801..f1afaf6 100644
> --- a/src/libcgroup.map
> +++ b/src/libcgroup.map
> @@ -101,5 +101,5 @@ CGROUP_0.38 {
> cgroup_get_subsys_mount_point_begin;
> cgroup_get_subsys_mount_point_next;
> cgroup_get_subsys_mount_point_end;
> + cgroup_set_permissions;
> } CGROUP_0.37;
> -
> diff --git a/src/tools/cgcreate.c b/src/tools/cgcreate.c
> index 7312b32..96f65da 100644
> --- a/src/tools/cgcreate.c
> +++ b/src/tools/cgcreate.c
> @@ -311,8 +311,9 @@ int main(int argc, char *argv[])
> goto err;
> }
> if (dirm_change + filem_change > 0) {
> - ret = cg_chmod_recursive(cgroup, dir_mode, dirm_change,
> - file_mode, filem_change);
> + cgroup->control_dperm = dir_mode;
> + cgroup->control_fperm = cgroup->task_fperm = file_mode;
> + ret = cgroup_set_permissions(cgroup_list[i]->path,
> cgroup);
> if (ret) {
> fprintf(stderr, "%s: can't change permission " \
> "of cgroup %s: %s\n", argv[0],
------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel