提交 dacd160d 编写于 作者: J Juan Hernandez 提交者: Martin Kletzander

Avoid hidden cgroup mount points

Currently the scan of the /proc/mounts file used to find cgroup mount
points doesn't take into account that mount points may hidden by other
mount points. For, example in certain Kubernetes environments the
/proc/mounts contains the following lines:

  cgroup /sys/fs/cgroup/net_prio,net_cls cgroup ...
  tmpfs /sys/fs/cgroup tmpfs ...
  cgroup /sys/fs/cgroup/net_cls,net_prio cgroup ...

In this particular environment the first mount point is hidden by the
second one. The correct mount point is the third one, but libvirt will
never process it because it only checks the first mount point for each
controller (net_cls in this case). So libvirt will try to use the first
mount point, which doesn't actually exist, and the complete detection
process will fail.

To avoid that issue this patch changes the virCgroupDetectMountsFromFile
function so that when there are duplicates it takes the information from
the last line in /proc/mounts. This requires removing the previous
explicit condition to skip duplicates, and adding code to free the
memory used by the processing of duplicated lines.

Related-To: https://bugzilla.redhat.com/1468214
Related-To: https://github.com/kubevirt/libvirt/issues/4Signed-off-by: NJuan Hernandez <jhernand@redhat.com>
上级 3d52a844
...@@ -397,6 +397,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, ...@@ -397,6 +397,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
const char *typestr = virCgroupControllerTypeToString(i); const char *typestr = virCgroupControllerTypeToString(i);
int typelen = strlen(typestr); int typelen = strlen(typestr);
char *tmp = entry.mnt_opts; char *tmp = entry.mnt_opts;
struct virCgroupController *controller = &group->controllers[i];
while (tmp) { while (tmp) {
char *next = strchr(tmp, ','); char *next = strchr(tmp, ',');
int len; int len;
...@@ -406,18 +407,22 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, ...@@ -406,18 +407,22 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
} else { } else {
len = strlen(tmp); len = strlen(tmp);
} }
/* NB, the same controller can appear >1 time in mount list
* due to bind mounts from one location to another. Pick the if (typelen == len && STREQLEN(typestr, tmp, len)) {
* first entry only
*/
if (typelen == len && STREQLEN(typestr, tmp, len) &&
!group->controllers[i].mountPoint) {
char *linksrc; char *linksrc;
struct stat sb; struct stat sb;
char *tmp2; char *tmp2;
if (VIR_STRDUP(group->controllers[i].mountPoint, /* Note that the lines in /proc/mounts have the same
entry.mnt_dir) < 0) * order than the mount operations, and that there may
* be duplicates due to bind mounts. This means
* that the same mount point may be processed more than
* once. We need to save the results of the last one,
* and we need to be careful to release the memory used
* by previous processing. */
VIR_FREE(controller->mountPoint);
VIR_FREE(controller->linkPoint);
if (VIR_STRDUP(controller->mountPoint, entry.mnt_dir) < 0)
goto error; goto error;
tmp2 = strrchr(entry.mnt_dir, '/'); tmp2 = strrchr(entry.mnt_dir, '/');
...@@ -453,7 +458,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group, ...@@ -453,7 +458,7 @@ virCgroupDetectMountsFromFile(virCgroupPtr group,
VIR_WARN("Expecting a symlink at %s for controller %s", VIR_WARN("Expecting a symlink at %s for controller %s",
linksrc, typestr); linksrc, typestr);
} else { } else {
group->controllers[i].linkPoint = linksrc; controller->linkPoint = linksrc;
} }
} }
} }
......
rootfs / rootfs rw 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,nosuid,relatime,size=10240k,nr_inodes=1006404,mode=755 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=000 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
/dev/sda1 / ext4 rw,noatime,data=ordered 0 0
tmpfs /run tmpfs rw,nodev,relatime,size=812296k,mode=755 0 0
mqueue /dev/mqueue mqueue rw,nosuid,nodev,noexec,relatime 0 0
shm /dev/shm tmpfs rw,nosuid,nodev,noexec,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,nosuid,nodev,noexec,relatime 0 0
cgroup_root /sys/fs/cgroup tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k,mode=755 0 0
openrc /sys/fs/cgroup/openrc cgroup rw,nosuid,nodev,noexec,relatime,release_agent=/lib64/rc/sh/cgroup-release-agent.sh,name=openrc 0 0
cpuset /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cpuset /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cpu /sys/fs/cgroup/cpu cgroup rw,nosuid,nodev,noexec,relatime,cpu 0 0
cpuacct /some/random/location/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
cpuacct /sys/fs/cgroup/cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct 0 0
memory /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
devices /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
freezer /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
blkio /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
perf_event /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
hugetlb /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,nosuid,nodev,noexec,relatime 0 0
freezer /some/random/location/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cpu /sys/fs/cgroup/cpu
cpuacct /sys/fs/cgroup/cpuacct
cpuset /sys/fs/cgroup/cpuset
memory /sys/fs/cgroup/memory
devices /sys/fs/cgroup/devices
freezer /some/random/location/freezer
blkio /sys/fs/cgroup/blkio
net_cls <null>
perf_event /sys/fs/cgroup/perf_event
name=systemd <null>
...@@ -885,6 +885,7 @@ mymain(void) ...@@ -885,6 +885,7 @@ mymain(void)
DETECT_MOUNTS("cgroups3"); DETECT_MOUNTS("cgroups3");
DETECT_MOUNTS("all-in-one"); DETECT_MOUNTS("all-in-one");
DETECT_MOUNTS("no-cgroups"); DETECT_MOUNTS("no-cgroups");
DETECT_MOUNTS("kubevirt");
if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0) if (virTestRun("New cgroup for self", testCgroupNewForSelf, NULL) < 0)
ret = -1; ret = -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册