On 10.04.2013 12:08, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)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(a)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