Commit cbe8ef4f authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

cgroup: restore cgroup property perms as well

Signed-off-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 3c18439e
......@@ -307,6 +307,7 @@ static int read_cgroup_prop(struct cgroup_prop *property, const char *fullpath)
{
char buf[1024];
int fd, ret;
struct stat sb;
fd = open(fullpath, O_RDONLY);
if (fd == -1) {
......@@ -315,6 +316,16 @@ static int read_cgroup_prop(struct cgroup_prop *property, const char *fullpath)
return -1;
}
if (fstat(fd, &sb) < 0) {
pr_perror("failed statting cgroup prop %s", fullpath);
close(fd);
return -1;
}
property->mode = sb.st_mode;
property->uid = sb.st_uid;
property->gid = sb.st_gid;
ret = read(fd, buf, sizeof(buf) - 1);
if (ret == -1) {
pr_err("Failed scanning %s\n", fullpath);
......@@ -331,7 +342,6 @@ static int read_cgroup_prop(struct cgroup_prop *property, const char *fullpath)
property->value = xstrdup(strip(buf));
if (!property->value)
return -1;
return 0;
}
......@@ -664,10 +674,20 @@ static int dump_cg_dir_props(struct list_head *props, size_t n_props,
list_for_each_entry(prop_cur, props, list) {
cgroup_prop_entry__init(cpe);
cpe->perms = xmalloc(sizeof(*cpe->perms));
if (!cpe->perms)
goto error;
cgroup_perms__init(cpe->perms);
cpe->name = xstrdup(prop_cur->name);
cpe->value = xstrdup(prop_cur->value);
if (!cpe->name || !cpe->value)
goto error;
cpe->perms->mode = prop_cur->mode;
cpe->perms->uid = prop_cur->uid;
cpe->perms->gid = prop_cur->gid;
(*ents)[i++] = cpe++;
}
......@@ -1001,7 +1021,9 @@ static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,
char *path, int off)
{
FILE *f;
int cg;
int cg, fd;
struct stat sb;
CgroupPerms *perms = cg_prop_entry_p->perms;
if (!cg_prop_entry_p->value) {
pr_err("cg_prop_entry->value was empty when should have had a value\n");
......@@ -1022,6 +1044,38 @@ static int restore_cgroup_prop(const CgroupPropEntry * cg_prop_entry_p,
return -1;
}
fd = fileno(f);
if (fd < 0) {
fclose(f);
pr_err("bad file stream?");
return -1;
}
if (fstat(fd, &sb) < 0) {
fclose(f);
pr_perror("stat of property %s failed", path);
return -1;
}
if (perms) {
/* only chmod/chown if the perms are actually different: we aren't
* allowed to chmod some cgroup props (e.g. the read only ones), so we
* don't want to try if the perms already match.
*/
if (sb.st_mode != (mode_t) perms->mode && fchmod(fd, perms->mode) < 0) {
fclose(f);
pr_perror("chmod of %s failed", path);
return -1;
}
if ((sb.st_uid != perms->uid || sb.st_gid != perms->gid) &&
fchown(fd, perms->uid, perms->gid)) {
fclose(f);
pr_perror("chown of %s failed", path);
return -1;
}
}
if (fprintf(f, "%s", cg_prop_entry_p->value) < 0) {
fclose(f);
pr_err("Failed writing %s to %s\n", cg_prop_entry_p->value, path);
......
......@@ -17,6 +17,9 @@ struct cg_controller;
struct cgroup_prop {
char *name;
char *value;
mode_t mode;
uid_t uid;
gid_t gid;
struct list_head list;
};
......
message cgroup_perms {
required uint32 mode = 1;
required uint32 uid = 2;
required uint32 gid = 3;
}
message cgroup_prop_entry {
required string name = 1;
required string value = 2;
optional cgroup_perms perms = 3;
}
message cgroup_dir_entry {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment