]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
This patch adds permission change function
authorIvana Hutarova Varekova <varekova@redhat.com>
Wed, 10 Nov 2010 15:08:20 +0000 (16:08 +0100)
committerJan Safranek <jsafrane@redhat.com>
Wed, 10 Nov 2010 15:08:20 +0000 (16:08 +0100)
int cg_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode,
       int dirm_change, mode_t file_mode, int filem_change);

It changes the directory and files permissions to the given values.
If dirm_change is nonzero, then directory permissions will be set to the second parameter
dir_mode.
If filem_change is nonzero, then directory permissions will be set to the second parameter
file_mode.

CHANGELOG v2:
* fix the return value check for cg_chmod_file procedure

CHANGELOG v1:
* improve the patch description and typo in comment
* fix the problems jsafrane reported

Signed-off-by: Ivana Hutarova Varekova<varekova@redhat.com>
Signed-off-by: Jan Safranek <jsafrane@redhat.com>
include/libcgroup/groups.h
src/api.c
src/libcgroup.map

index d212ec023e05ca87a6b75d386554088288e244be..c87805ff98c5880b2b83531990b8dcbcc55530b7 100644 (file)
@@ -518,6 +518,17 @@ char *cgroup_get_value_name(struct cgroup_controller *controller, int index);
  */
 int cgroup_get_procs(char *name, char *controller, pid_t **pids, int *size);
 
+/**
+ * Change permission of files and directories of given group
+ * @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_chmod_recursive(struct cgroup *cgroup, mode_t dir_mode,
+       int dirm_change, mode_t file_mode, int filem_change);
+
 /**
  * @}
  * @}
index 6e79db00d850a9087f78b6046337ffc47b4cae44..1d2d1118b509b3ff49d26643fa6b979bca4b68bb 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -171,6 +171,95 @@ static int cg_chown_recursive(char **path, uid_t owner, gid_t group)
        return ret;
 }
 
+int cg_chmod_file(FTS *fts, FTSENT *ent, mode_t dir_mode,
+       int dirm_change, mode_t file_mode, int filem_change)
+{
+       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;
+               break;
+       case FTS_D:
+       case FTS_DC:
+       case FTS_DNR:
+       case FTS_DP:
+               if (dirm_change)
+                       ret = chmod(filename, dir_mode);
+               break;
+       case FTS_F:
+       case FTS_NSOK:
+       case FTS_NS:
+       case FTS_DEFAULT:
+               if (filem_change)
+                       ret = chmod(filename, file_mode);
+               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 ret = 0;
+       int final_ret =0;
+       FTS *fts;
+       char *fts_path[2];
+       char *path = NULL;
+
+       fts_path[0] = (char *)malloc(FILENAME_MAX);
+       if (!fts_path[0]) {
+               last_errno = errno;
+               return ECGOTHER;
+       }
+       fts_path[1] = NULL;
+       path = fts_path[0];
+       cgroup_dbg("chmod: path is %s\n", path);
+
+       if (!cg_build_path(cgroup->name, path,
+                       cgroup->controller[0]->name)) {
+               final_ret = ECGFAIL;
+               goto err;
+       }
+
+       fts = fts_open(fts_path, FTS_PHYSICAL | FTS_NOCHDIR |
+                       FTS_NOSTAT, NULL);
+       if (fts == NULL) {
+               last_errno = errno;
+               final_ret = ECGOTHER;
+               goto err;
+       }
+       while (1) {
+               FTSENT *ent;
+               ent = fts_read(fts);
+               if (!ent) {
+                       cgroup_dbg("fts_read failed\n");
+                       break;
+               }
+               ret = cg_chmod_file(fts, ent, dir_mode, dirm_change,
+                       file_mode, filem_change);
+               if (ret) {
+                       last_errno = errno;
+                       final_ret = ECGOTHER;
+               }
+       }
+       fts_close(fts);
+
+err:
+       free(fts_path[0]);
+       return final_ret;
+}
+
+
 static char *cgroup_basename(const char *path)
 {
        char *base;
index 60970cacb512f6880bcd5ad1949cac585cb51b8f..2a3439f3aeb5b3cb63a5b49065ff1c4584e9e220 100644 (file)
@@ -94,4 +94,5 @@ CGROUP_0.37 {
        cgroup_read_value_begin;
        cgroup_read_value_next;
        cgroup_read_value_end;
+       cg_chmod_recursive;
 } CGROUP_0.36;