
On 10.04.2013 12:08, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
If a cgroup controller is co-mounted with another, eg
/sys/fs/cgroup/cpu,cpuacct
Then it is a requirement that there exist symlinks at
/sys/fs/cgroup/cpu /sys/fs/cgroup/cpuacct
pointing to the real mount point. Add support to virCgroupPtr to detect and track these symlinks
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- src/util/vircgroup.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- src/util/vircgrouppriv.h | 5 +++++ tests/vircgroupmock.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/vircgrouptest.c | 36 +++++++++++++++++++++++------- 4 files changed, 143 insertions(+), 12 deletions(-)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 6202614..14af16e 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c
@@ -157,9 +166,46 @@ static int virCgroupDetectMounts(virCgroupPtr group) * first entry only */ if (typelen == len && STREQLEN(typestr, tmp, len) && - !group->controllers[i].mountPoint && - !(group->controllers[i].mountPoint = strdup(entry.mnt_dir))) - goto no_memory; + !group->controllers[i].mountPoint) { + char *linksrc; + struct stat sb; + char *tmp2; + + if (!(group->controllers[i].mountPoint = strdup(entry.mnt_dir))) + goto no_memory; + + tmp2 = strrchr(entry.mnt_dir, '/'); + if (!tmp2) { + errno = EINVAL; + goto error; + } + *tmp2 = '\0'; + /* If it is a co-mount it has a filename like "cpu,cpuacct" + * and we must identify the symlink path */ + if (strchr(tmp2 + 1, ',')) { + if (virAsprintf(&linksrc, "%s/%s", + entry.mnt_dir, typestr) < 0) + goto no_memory; + *tmp2 = '/'; + + if (lstat(linksrc, &sb) < 0) { + if (errno == ENOENT) { + VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s", + typestr, entry.mnt_dir, linksrc); + VIR_FREE(linksrc); + } else { + goto error; + } + } else { + if (!S_ISLNK(sb.st_mode)) { + VIR_WARN("Expecting a symlink at %s for controller %s", + linksrc, typestr); + } else { + group->controllers[i].linkPoint = linksrc; + } + } + } + } tmp = next; } } @@ -170,8 +216,10 @@ static int virCgroupDetectMounts(virCgroupPtr group) return 0;
no_memory: + errno = ENOENT;
Any reason for not returning ENOMEM here? I don't see any.
+error: VIR_FORCE_FCLOSE(mounts); - return -ENOMEM; + return -errno; }
ACK if errno fixed. Michal