Ensure systemd cgroup ownership is delegated to container with userns

This function is needed for user namespaces, where we need to chmod()
the cgroup to the initial uid/gid such that systemd is allowed to
use the cgroup.

Signed-off-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Richard Weinberger 2014-02-24 12:23:33 +00:00 committed by Daniel P. Berrange
parent 8ca5f46c59
commit 6fb42d7cdc
4 changed files with 88 additions and 0 deletions

View File

@ -1067,6 +1067,7 @@ virCgroupSetMemory;
virCgroupSetMemoryHardLimit;
virCgroupSetMemorySoftLimit;
virCgroupSetMemSwapHardLimit;
virCgroupSetOwner;
virCgroupSupportsCpuBW;

View File

@ -484,6 +484,18 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
&cgroup) < 0)
goto cleanup;
/* setup control group permissions for user namespace */
if (def->idmap.uidmap) {
if (virCgroupSetOwner(cgroup,
def->idmap.uidmap[0].target,
def->idmap.gidmap[0].target,
(1 << VIR_CGROUP_CONTROLLER_SYSTEMD)) < 0) {
virCgroupFree(&cgroup);
cgroup = NULL;
goto cleanup;
}
}
cleanup:
return cgroup;
}

View File

@ -3608,6 +3608,76 @@ cleanup:
}
int virCgroupSetOwner(virCgroupPtr cgroup,
uid_t uid,
gid_t gid,
int controllers)
{
int ret = -1;
size_t i;
char *base = NULL, *entry = NULL;
DIR *dh = NULL;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
struct dirent *de;
if (!((1 << i) & controllers))
continue;
if (!cgroup->controllers[i].mountPoint)
continue;
if (virAsprintf(&base, "%s%s", cgroup->controllers[i].mountPoint,
cgroup->controllers[i].placement) < 0)
goto cleanup;
if (!(dh = opendir(base))) {
virReportSystemError(errno,
_("Unable to open dir '%s'"), base);
goto cleanup;
}
while ((de = readdir(dh)) != NULL) {
if (STREQ(de->d_name, ".") ||
STREQ(de->d_name, ".."))
continue;
if (virAsprintf(&entry, "%s/%s", base, de->d_name) < 0)
goto cleanup;
if (chown(entry, uid, gid) < 0) {
virReportSystemError(errno,
_("cannot chown '%s' to (%u, %u)"),
entry, uid, gid);
goto cleanup;
}
VIR_FREE(entry);
}
if (chown(base, uid, gid) < 0) {
virReportSystemError(errno,
_("cannot chown '%s' to (%u, %u)"),
base, uid, gid);
goto cleanup;
}
VIR_FREE(base);
closedir(dh);
dh = NULL;
}
ret = 0;
cleanup:
if (dh)
closedir(dh);
VIR_FREE(entry);
VIR_FREE(base);
return ret;
}
/**
* virCgroupSupportsCpuBW():
* Check whether the host supports CFS bandwidth.

View File

@ -249,4 +249,9 @@ int virCgroupIsolateMount(virCgroupPtr group,
bool virCgroupSupportsCpuBW(virCgroupPtr cgroup);
int virCgroupSetOwner(virCgroupPtr cgroup,
uid_t uid,
gid_t gid,
int controllers);
#endif /* __VIR_CGROUP_H__ */