vircgroup: extract virCgroupV1BindMount

Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Pavel Hrdina 2018-08-17 10:04:20 +02:00
parent c4047141a0
commit 8dc1b6ce50
3 changed files with 120 additions and 101 deletions

View File

@ -3175,35 +3175,6 @@ virCgroupKillPainfully(virCgroupPtr group)
}
static char *
virCgroupIdentifyRoot(virCgroupPtr group)
{
char *ret = NULL;
size_t i;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *tmp;
if (!group->controllers[i].mountPoint)
continue;
if (!(tmp = strrchr(group->controllers[i].mountPoint, '/'))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not find directory separator in %s"),
group->controllers[i].mountPoint);
return NULL;
}
if (VIR_STRNDUP(ret, group->controllers[i].mountPoint,
tmp - group->controllers[i].mountPoint) < 0)
return NULL;
return ret;
}
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not find any mounted controllers"));
return NULL;
}
/**
* virCgroupGetCpuCfsQuota:
*
@ -3298,78 +3269,7 @@ int
virCgroupBindMount(virCgroupPtr group, const char *oldroot,
const char *mountopts)
{
size_t i;
VIR_AUTOFREE(char *) opts = NULL;
VIR_AUTOFREE(char *) root = NULL;
if (!(root = virCgroupIdentifyRoot(group)))
return -1;
VIR_DEBUG("Mounting cgroups at '%s'", root);
if (virFileMakePath(root) < 0) {
virReportSystemError(errno,
_("Unable to create directory %s"),
root);
return -1;
}
if (virAsprintf(&opts,
"mode=755,size=65536%s", mountopts) < 0)
return -1;
if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) {
virReportSystemError(errno,
_("Failed to mount %s on %s type %s"),
"tmpfs", root, "tmpfs");
return -1;
}
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
if (!group->controllers[i].mountPoint)
continue;
if (!virFileExists(group->controllers[i].mountPoint)) {
VIR_AUTOFREE(char *) src = NULL;
if (virAsprintf(&src, "%s%s",
oldroot,
group->controllers[i].mountPoint) < 0)
return -1;
VIR_DEBUG("Create mount point '%s'",
group->controllers[i].mountPoint);
if (virFileMakePath(group->controllers[i].mountPoint) < 0) {
virReportSystemError(errno,
_("Unable to create directory %s"),
group->controllers[i].mountPoint);
return -1;
}
if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND,
NULL) < 0) {
virReportSystemError(errno,
_("Failed to bind cgroup '%s' on '%s'"),
src, group->controllers[i].mountPoint);
return -1;
}
}
if (group->controllers[i].linkPoint) {
VIR_DEBUG("Link mount point '%s' to '%s'",
group->controllers[i].mountPoint,
group->controllers[i].linkPoint);
if (symlink(group->controllers[i].mountPoint,
group->controllers[i].linkPoint) < 0) {
virReportSystemError(errno,
_("Unable to symlink directory %s to %s"),
group->controllers[i].mountPoint,
group->controllers[i].linkPoint);
return -1;
}
}
}
return 0;
return group->backend->bindMount(group, oldroot, mountopts);
}

View File

@ -126,6 +126,11 @@ typedef int
(*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup,
int controller);
typedef int
(*virCgroupBindMountCB)(virCgroupPtr group,
const char *oldroot,
const char *mountopts);
struct _virCgroupBackend {
virCgroupBackendType type;
@ -146,6 +151,7 @@ struct _virCgroupBackend {
virCgroupRemoveCB remove;
virCgroupAddTaskCB addTask;
virCgroupHasEmptyTasksCB hasEmptyTasks;
virCgroupBindMountCB bindMount;
};
typedef struct _virCgroupBackend virCgroupBackend;
typedef virCgroupBackend *virCgroupBackendPtr;

View File

@ -24,6 +24,9 @@
# include <mntent.h>
#endif
#include <sys/stat.h>
#if defined HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
#include "internal.h"
@ -754,6 +757,115 @@ virCgroupV1HasEmptyTasks(virCgroupPtr cgroup,
}
static char *
virCgroupV1IdentifyRoot(virCgroupPtr group)
{
char *ret = NULL;
size_t i;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
char *tmp;
if (!group->controllers[i].mountPoint)
continue;
if (!(tmp = strrchr(group->controllers[i].mountPoint, '/'))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not find directory separator in %s"),
group->controllers[i].mountPoint);
return NULL;
}
if (VIR_STRNDUP(ret, group->controllers[i].mountPoint,
tmp - group->controllers[i].mountPoint) < 0)
return NULL;
return ret;
}
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not find any mounted v1 controllers"));
return NULL;
}
static int
virCgroupV1BindMount(virCgroupPtr group,
const char *oldroot,
const char *mountopts)
{
size_t i;
VIR_AUTOFREE(char *) opts = NULL;
VIR_AUTOFREE(char *) root = NULL;
if (!(root = virCgroupV1IdentifyRoot(group)))
return -1;
VIR_DEBUG("Mounting cgroups at '%s'", root);
if (virFileMakePath(root) < 0) {
virReportSystemError(errno,
_("Unable to create directory %s"),
root);
return -1;
}
if (virAsprintf(&opts,
"mode=755,size=65536%s", mountopts) < 0)
return -1;
if (mount("tmpfs", root, "tmpfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, opts) < 0) {
virReportSystemError(errno,
_("Failed to mount %s on %s type %s"),
"tmpfs", root, "tmpfs");
return -1;
}
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
if (!group->controllers[i].mountPoint)
continue;
if (!virFileExists(group->controllers[i].mountPoint)) {
VIR_AUTOFREE(char *) src = NULL;
if (virAsprintf(&src, "%s%s",
oldroot,
group->controllers[i].mountPoint) < 0)
return -1;
VIR_DEBUG("Create mount point '%s'",
group->controllers[i].mountPoint);
if (virFileMakePath(group->controllers[i].mountPoint) < 0) {
virReportSystemError(errno,
_("Unable to create directory %s"),
group->controllers[i].mountPoint);
return -1;
}
if (mount(src, group->controllers[i].mountPoint, "none", MS_BIND,
NULL) < 0) {
virReportSystemError(errno,
_("Failed to bind cgroup '%s' on '%s'"),
src, group->controllers[i].mountPoint);
return -1;
}
}
if (group->controllers[i].linkPoint) {
VIR_DEBUG("Link mount point '%s' to '%s'",
group->controllers[i].mountPoint,
group->controllers[i].linkPoint);
if (symlink(group->controllers[i].mountPoint,
group->controllers[i].linkPoint) < 0) {
virReportSystemError(errno,
_("Unable to symlink directory %s to %s"),
group->controllers[i].mountPoint,
group->controllers[i].linkPoint);
return -1;
}
}
}
return 0;
}
virCgroupBackend virCgroupV1Backend = {
.type = VIR_CGROUP_BACKEND_TYPE_V1,
@ -773,6 +885,7 @@ virCgroupBackend virCgroupV1Backend = {
.remove = virCgroupV1Remove,
.addTask = virCgroupV1AddTask,
.hasEmptyTasks = virCgroupV1HasEmptyTasks,
.bindMount = virCgroupV1BindMount,
};