<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 18, 2018 at 5:45 PM, Pavel Hrdina <span dir="ltr"><<a href="mailto:phrdina@redhat.com" target="_blank">phrdina@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Signed-off-by: Pavel Hrdina <<a href="mailto:phrdina@redhat.com" target="_blank">phrdina@redhat.com</a>><br></blockquote><div><br></div><div>Reviewed-by: Fabiano Fidêncio <<a href="mailto:fidencio@redhat.com" target="_blank">fidencio@redhat.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
 src/util/vircgroup.c        | 138 ++----------------------------<wbr>-<br>
 src/util/vircgroupbackend.h |  14 ++++<br>
 src/util/vircgroupv1.c      | 158 ++++++++++++++++++++++++++++++<wbr>++++++<br>
 3 files changed, 180 insertions(+), 130 deletions(-)<br>
<br>
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c<br>
index f5b2a14df9..7557fc5576 100644<br>
--- a/src/util/vircgroup.c<br>
+++ b/src/util/vircgroup.c<br>
@@ -237,82 +237,6 @@ virCgroupPartitionEscape(char **path)<br>
 }<br>
<br>
<br>
-static int<br>
-virCgroupResolveMountLink(con<wbr>st char *mntDir,<br>
-                          const char *typeStr,<br>
-                          virCgroupControllerPtr controller)<br>
-{<br>
-    VIR_AUTOFREE(char *) linkSrc = NULL;<br>
-    VIR_AUTOFREE(char *) tmp = NULL;<br>
-    char *dirName;<br>
-    struct stat sb;<br>
-<br>
-    if (VIR_STRDUP(tmp, mntDir) < 0)<br>
-        return -1;<br>
-<br>
-    dirName = strrchr(tmp, '/');<br>
-    if (!dirName) {<br>
-        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
-                       _("Missing '/' separator in cgroup mount '%s'"), tmp);<br>
-        return -1;<br>
-    }<br>
-<br>
-    if (!strchr(dirName + 1, ','))<br>
-        return 0;<br>
-<br>
-    *dirName = '\0';<br>
-    if (virAsprintf(&linkSrc, "%s/%s", tmp, typeStr) < 0)<br>
-        return -1;<br>
-    *dirName = '/';<br>
-<br>
-    if (lstat(linkSrc, &sb) < 0) {<br>
-        if (errno == ENOENT) {<br>
-            VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s",<br>
-                     typeStr, tmp, linkSrc);<br>
-        } else {<br>
-            virReportSystemError(errno, _("Cannot stat %s"), linkSrc);<br>
-            return -1;<br>
-        }<br>
-    } else {<br>
-        if (!S_ISLNK(sb.st_mode)) {<br>
-            VIR_WARN("Expecting a symlink at %s for controller %s",<br>
-                     linkSrc, typeStr);<br>
-        } else {<br>
-            VIR_STEAL_PTR(controller->link<wbr>Point, linkSrc);<br>
-        }<br>
-    }<br>
-<br>
-    return 0;<br>
-}<br>
-<br>
-<br>
-static bool<br>
-virCgroupMountOptsMatchContro<wbr>ller(const char *mntOpts,<br>
-                                  const char *typeStr)<br>
-{<br>
-    const char *tmp = mntOpts;<br>
-    int typeLen = strlen(typeStr);<br>
-<br>
-    while (tmp) {<br>
-        const char *next = strchr(tmp, ',');<br>
-        int len;<br>
-        if (next) {<br>
-            len = next - tmp;<br>
-            next++;<br>
-        } else {<br>
-            len = strlen(tmp);<br>
-        }<br>
-<br>
-        if (typeLen == len && STREQLEN(typeStr, tmp, len))<br>
-            return true;<br>
-<br>
-        tmp = next;<br>
-    }<br>
-<br>
-    return false;<br>
-}<br>
-<br>
-<br>
 /*<br>
  * Process /proc/mounts figuring out what controllers are<br>
  * mounted and where<br>
@@ -320,7 +244,6 @@ virCgroupMountOptsMatchControl<wbr>ler(const char *mntOpts,<br>
 static int<br>
 virCgroupDetectMounts(virCgro<wbr>upPtr group)<br>
 {<br>
-    size_t i;<br>
     FILE *mounts = NULL;<br>
     struct mntent entry;<br>
     char buf[CGROUP_MAX_VAL];<br>
@@ -333,34 +256,11 @@ virCgroupDetectMounts(virCgrou<wbr>pPtr group)<br>
     }<br>
<br>
     while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {<br>
-        if (STRNEQ(entry.mnt_type, "cgroup"))<br>
-            continue;<br>
-<br>
-        for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {<br>
-            const char *typestr = virCgroupControllerTypeToStrin<wbr>g(i);<br>
-<br>
-            if (virCgroupMountOptsMatchContro<wbr>ller(entry.mnt_opts, typestr)) {<br>
-                /* Note that the lines in /proc/mounts have the same<br>
-                 * order than the mount operations, and that there may<br>
-                 * be duplicates due to bind mounts. This means<br>
-                 * that the same mount point may be processed more than<br>
-                 * once. We need to save the results of the last one,<br>
-                 * and we need to be careful to release the memory used<br>
-                 * by previous processing. */<br>
-                virCgroupControllerPtr controller = &group->controllers[i];<br>
-<br>
-                VIR_FREE(controller->mountPoin<wbr>t);<br>
-                VIR_FREE(controller->linkPoint<wbr>);<br>
-                if (VIR_STRDUP(controller->mountP<wbr>oint, entry.mnt_dir) < 0)<br>
-                    goto cleanup;<br>
-<br>
-                /* If it is a co-mount it has a filename like "cpu,cpuacct"<br>
-                 * and we must identify the symlink path */<br>
-                if (virCgroupResolveMountLink(ent<wbr>ry.mnt_dir, typestr,<br>
-                                              controller) < 0) {<br>
-                    goto cleanup;<br>
-                }<br>
-            }<br>
+        if (group->backend->detectMounts(<wbr>group,<br>
+                                         entry.mnt_type,<br>
+                                         entry.mnt_opts,<br>
+                                         entry.mnt_dir) < 0) {<br>
+            goto cleanup;<br>
         }<br>
     }<br>
<br>
@@ -434,7 +334,6 @@ virCgroupDetectPlacement(virCg<wbr>roupPtr group,<br>
                          pid_t pid,<br>
                          const char *path)<br>
 {<br>
-    size_t i;<br>
     FILE *mapping  = NULL;<br>
     char line[1024];<br>
     int ret = -1;<br>
@@ -474,30 +373,9 @@ virCgroupDetectPlacement(virCg<wbr>roupPtr group,<br>
         controllers++;<br>
         selfpath++;<br>
<br>
-        for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {<br>
-            const char *typestr = virCgroupControllerTypeToStrin<wbr>g(i);<br>
-<br>
-            if (virCgroupMountOptsMatchContro<wbr>ller(controllers, typestr) &&<br>
-                group->controllers[i].mountPoi<wbr>nt != NULL &&<br>
-                group->controllers[i].placemen<wbr>t == NULL) {<br>
-                /*<br>
-                 * selfpath == "/" + path="" -> "/"<br>
-                 * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"<br>
-                 * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"<br>
-                 */<br>
-                if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {<br>
-                    if (VIR_STRDUP(group->controllers<wbr>[i].placement,<br>
-                                   selfpath) < 0)<br>
-                        goto cleanup;<br>
-                } else {<br>
-                    if (virAsprintf(&group->controlle<wbr>rs[i].placement,<br>
-                                    "%s%s%s", selfpath,<br>
-                                    (STREQ(selfpath, "/") ||<br>
-                                     STREQ(path, "") ? "" : "/"),<br>
-                                    path) < 0)<br>
-                        goto cleanup;<br>
-                }<br>
-            }<br>
+        if (group->backend->detectPlaceme<wbr>nt(group, path, controllers,<br>
+                                            selfpath) < 0) {<br>
+            goto cleanup;<br>
         }<br>
     }<br>
<br>
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h<br>
index 81ee597fc8..fadc7efdcf 100644<br>
--- a/src/util/vircgroupbackend.h<br>
+++ b/src/util/vircgroupbackend.h<br>
@@ -45,6 +45,18 @@ typedef int<br>
 (*virCgroupCopyMountsCB)(virC<wbr>groupPtr group,<br>
                          virCgroupPtr parent);<br>
<br>
+typedef int<br>
+(*virCgroupDetectMountsCB)(vi<wbr>rCgroupPtr group,<br>
+                           const char *mntType,<br>
+                           const char *mntOpts,<br>
+                           const char *mntDir);<br>
+<br>
+typedef int<br>
+(*virCgroupDetectPlacementCB)<wbr>(virCgroupPtr group,<br>
+                              const char *path,<br>
+                              const char *controllers,<br>
+                              const char *selfpath);<br>
+<br>
 struct _virCgroupBackend {<br>
     virCgroupBackendType type;<br>
<br>
@@ -52,6 +64,8 @@ struct _virCgroupBackend {<br>
     virCgroupAvailableCB available;<br>
     <wbr>virCgroupValidateMachineGroupC<wbr>B validateMachineGroup;<br>
     virCgroupCopyMountsCB copyMounts;<br>
+    virCgroupDetectMountsCB detectMounts;<br>
+    virCgroupDetectPlacementCB detectPlacement;<br>
 };<br>
 typedef struct _virCgroupBackend virCgroupBackend;<br>
 typedef virCgroupBackend *virCgroupBackendPtr;<br>
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c<br>
index 00c3349aee..2882a19be2 100644<br>
--- a/src/util/vircgroupv1.c<br>
+++ b/src/util/vircgroupv1.c<br>
@@ -23,6 +23,7 @@<br>
 #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R<br>
 # include <mntent.h><br>
 #endif<br>
+#include <sys/stat.h><br>
<br>
 #include "internal.h"<br>
<br>
@@ -37,6 +38,7 @@<br>
 #include "virlog.h"<br>
 #include "virstring.h"<br>
 #include "virsystemd.h"<br>
+#include "virerror.h"<br>
<br>
 VIR_LOG_INIT("util.cgroup");<br>
<br>
@@ -180,12 +182,168 @@ virCgroupV1CopyMounts(virCgrou<wbr>pPtr group,<br>
 }<br>
<br>
<br>
+static int<br>
+virCgroupV1ResolveMountLink(c<wbr>onst char *mntDir,<br>
+                            const char *typeStr,<br>
+                            virCgroupControllerPtr controller)<br>
+{<br>
+    VIR_AUTOFREE(char *) linkSrc = NULL;<br>
+    VIR_AUTOFREE(char *) tmp = NULL;<br>
+    char *dirName;<br>
+    struct stat sb;<br>
+<br>
+    if (VIR_STRDUP(tmp, mntDir) < 0)<br>
+        return -1;<br>
+<br>
+    dirName = strrchr(tmp, '/');<br>
+    if (!dirName) {<br>
+        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
+                       _("Missing '/' separator in cgroup mount '%s'"), tmp);<br>
+        return -1;<br>
+    }<br>
+<br>
+    if (!strchr(dirName + 1, ','))<br>
+        return 0;<br>
+<br>
+    *dirName = '\0';<br>
+    if (virAsprintf(&linkSrc, "%s/%s", tmp, typeStr) < 0)<br>
+        return -1;<br>
+    *dirName = '/';<br>
+<br>
+    if (lstat(linkSrc, &sb) < 0) {<br>
+        if (errno == ENOENT) {<br>
+            VIR_WARN("Controller %s co-mounted at %s is missing symlink at %s",<br>
+                     typeStr, tmp, linkSrc);<br>
+        } else {<br>
+            virReportSystemError(errno, _("Cannot stat %s"), linkSrc);<br>
+            return -1;<br>
+        }<br>
+    } else {<br>
+        if (!S_ISLNK(sb.st_mode)) {<br>
+            VIR_WARN("Expecting a symlink at %s for controller %s",<br>
+                     linkSrc, typeStr);<br>
+        } else {<br>
+            VIR_STEAL_PTR(controller->link<wbr>Point, linkSrc);<br>
+        }<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
+<br>
+static bool<br>
+virCgroupV1MountOptsMatchCont<wbr>roller(const char *mntOpts,<br>
+                                    const char *typeStr)<br>
+{<br>
+    const char *tmp = mntOpts;<br>
+    int typeLen = strlen(typeStr);<br>
+<br>
+    while (tmp) {<br>
+        const char *next = strchr(tmp, ',');<br>
+        int len;<br>
+        if (next) {<br>
+            len = next - tmp;<br>
+            next++;<br>
+        } else {<br>
+            len = strlen(tmp);<br>
+        }<br>
+<br>
+        if (typeLen == len && STREQLEN(typeStr, tmp, len))<br>
+            return true;<br>
+<br>
+        tmp = next;<br>
+    }<br>
+<br>
+    return false;<br>
+}<br>
+<br>
+<br>
+static int<br>
+virCgroupV1DetectMounts(virCg<wbr>roupPtr group,<br>
+                        const char *mntType,<br>
+                        const char *mntOpts,<br>
+                        const char *mntDir)<br>
+{<br>
+    size_t i;<br>
+<br>
+    if (STRNEQ(mntType, "cgroup"))<br>
+        return 0;<br>
+<br>
+    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {<br>
+        const char *typestr = virCgroupV1ControllerTypeToStr<wbr>ing(i);<br>
+<br>
+        if (virCgroupV1MountOptsMatchCont<wbr>roller(mntOpts, typestr)) {<br>
+            /* Note that the lines in /proc/mounts have the same<br>
+             * order than the mount operations, and that there may<br>
+             * be duplicates due to bind mounts. This means<br>
+             * that the same mount point may be processed more than<br>
+             * once. We need to save the results of the last one,<br>
+             * and we need to be careful to release the memory used<br>
+             * by previous processing. */<br>
+            virCgroupControllerPtr controller = &group->controllers[i];<br>
+<br>
+            VIR_FREE(controller->mountPoin<wbr>t);<br>
+            VIR_FREE(controller->linkPoint<wbr>);<br>
+            if (VIR_STRDUP(controller->mountP<wbr>oint, mntDir) < 0)<br>
+                return -1;<br>
+<br>
+            /* If it is a co-mount it has a filename like "cpu,cpuacct"<br>
+             * and we must identify the symlink path */<br>
+            if (virCgroupV1ResolveMountLink(m<wbr>ntDir, typestr, controller) < 0)<br>
+                return -1;<br>
+        }<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
+<br>
+static int<br>
+virCgroupV1DetectPlacement(vi<wbr>rCgroupPtr group,<br>
+                           const char *path,<br>
+                           const char *controllers,<br>
+                           const char *selfpath)<br>
+{<br>
+    size_t i;<br>
+<br>
+    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {<br>
+        const char *typestr = virCgroupV1ControllerTypeToStr<wbr>ing(i);<br>
+<br>
+        if (virCgroupV1MountOptsMatchCont<wbr>roller(controllers, typestr) &&<br>
+            group->controllers[i].mountPoi<wbr>nt != NULL &&<br>
+            group->controllers[i].placemen<wbr>t == NULL) {<br>
+            /*<br>
+             * selfpath == "/" + path="" -> "/"<br>
+             * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"<br>
+             * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"<br>
+             */<br>
+            if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {<br>
+                if (VIR_STRDUP(group->controllers<wbr>[i].placement,<br>
+                               selfpath) < 0)<br>
+                    return -1;<br>
+            } else {<br>
+                if (virAsprintf(&group->controlle<wbr>rs[i].placement,<br>
+                                "%s%s%s", selfpath,<br>
+                                (STREQ(selfpath, "/") ||<br>
+                                 STREQ(path, "") ? "" : "/"),<br>
+                                path) < 0)<br>
+                    return -1;<br>
+            }<br>
+        }<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
+<br>
 virCgroupBackend virCgroupV1Backend = {<br>
     .type = VIR_CGROUP_BACKEND_TYPE_V1,<br>
<br>
     .available = virCgroupV1Available,<br>
     .validateMachineGroup = virCgroupV1ValidateMachineGrou<wbr>p,<br>
     .copyMounts = virCgroupV1CopyMounts,<br>
+    .detectMounts = virCgroupV1DetectMounts,<br>
+    .detectPlacement = virCgroupV1DetectPlacement,<br>
 };<br>
<span class="m_-6780130000516924107HOEnZb"><font color="#888888"> <br>
<br>
-- <br>
2.17.1<br>
<br>
--<br>
libvir-list mailing list<br>
<a href="mailto:libvir-list@redhat.com" target="_blank">libvir-list@redhat.com</a><br>
<a href="https://www.redhat.com/mailman/listinfo/libvir-list" rel="noreferrer" target="_blank">https://www.redhat.com/mailman<wbr>/listinfo/libvir-list</a><br>
</font></span></blockquote></div><br></div></div>