<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>