On Fri 20-05-11 14:25:17, Jan Safranek wrote: > On 05/19/2011 09:37 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. > > NACK, this will change semantics of public function > cg_chmod_recursive(). I know, it's stupid copy/paste, but please create > new function cg_copymod_recursive (or cpmod or whatever) :(
What about this? --- >From 32b904c0998cee3687526bef1b8a36aa47ad674d Mon Sep 17 00:00:00 2001 From: Michal Hocko <mho...@suse.cz> Date: Fri, 20 May 2011 16:31:59 +0200 Subject: [PATCH] chmod_file: Introduce intelligent file permissions setting 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. This patch adds cg_chmod_path which can be used for non recursive permissions setting for path names and cg_owner_mask_chmod_recursive owner permissions aware variant of cg_chmod_recursive. /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 <mho...@suse.cz> --- include/libcgroup/groups.h | 22 +++++++++++++ src/api.c | 73 ++++++++++++++++++++++++++++++++++--------- src/tools/cgcreate.c | 2 +- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/include/libcgroup/groups.h b/include/libcgroup/groups.h index 61f18a0..ebad462 100644 --- a/include/libcgroup/groups.h +++ b/include/libcgroup/groups.h @@ -536,6 +536,28 @@ int cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, int dirm_change, mode_t file_mode, int filem_change); /** + * Change permission of files and directories of given group and uses + * owner permissions as a mask for group and others permissions + * @param cgroup The cgroup which permissions should be changed + * @param dir_mode The permission mode of group directory + * @param dirm_change Denotes whether the directory change should be done + * @param file_mode The permission mode of group files + * @param filem_change Denotes whether the directory change should be done + */ +int cg_owner_mask_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, + int dirm_change, mode_t file_mode, int filem_change); + +/** 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); + +/** * @} * @} */ diff --git a/src/api.c b/src/api.c index 289431a..fa6d0e4 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,29 +225,22 @@ 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; } - -/* - * TODO: Need to decide a better place to put this function. - */ -int cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, - int dirm_change, mode_t file_mode, int filem_change) +int __cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, + int dirm_change, mode_t file_mode, int filem_change, + int owner_is_umask) { int ret = 0; int final_ret =0; @@ -250,7 +278,7 @@ int cg_chmod_recursive(struct cgroup *cgroup, 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; @@ -263,6 +291,19 @@ err: return final_ret; } +int cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, + int dirm_change, mode_t file_mode, int filem_change) +{ + return __cg_chmod_recursive(cgroup, dir_mode, dirm_change, + file_mode, filem_change, 0); +} + +int cg_owner_mask_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode, + int dirm_change, mode_t file_mode, int filem_change) +{ + return __cg_chmod_recursive(cgroup, dir_mode, dirm_change, + file_mode, filem_change, 1); +} static char *cgroup_basename(const char *path) { @@ -1410,7 +1451,7 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) error = cg_chown_recursive(fts_path, cgroup->control_uid, cgroup->control_gid); if (!error) { - error = cg_chmod_recursive(cgroup, + error = cg_owner_mask_chmod_recursive(cgroup, cgroup->control_dperm, cgroup->control_dperm != NO_PERMS, cgroup->control_fperm, @@ -1463,7 +1504,7 @@ 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); + error = cg_chmod_path(path, cgroup->task_fperm, 1); if (error) { last_errno = errno; diff --git a/src/tools/cgcreate.c b/src/tools/cgcreate.c index a2a21b2..30a42a9 100644 --- a/src/tools/cgcreate.c +++ b/src/tools/cgcreate.c @@ -311,7 +311,7 @@ int main(int argc, char *argv[]) goto err; } if (dirm_change + filem_change > 0) { - ret = cg_chmod_recursive(cgroup, dir_mode, dirm_change, + ret = cg_owner_mask_chmod_recursive(cgroup, dir_mode, dirm_change, file_mode, filem_change); if (ret) { fprintf(stderr, "%s: can't change permission " \ -- 1.7.4.4 -- Michal Hocko SUSE Labs SUSE LINUX s.r.o. Lihovarska 1060/12 190 00 Praha 9 Czech Republic ------------------------------------------------------------------------------ What Every C/C++ and Fortran developer Should Know! Read this article and learn how Intel has extended the reach of its next-generation tools to help Windows* and Linux* C/C++ and Fortran developers boost performance applications - including clusters. http://p.sf.net/sfu/intel-dev2devmay _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel