2012-07-13 11:21:27 +00:00
|
|
|
/*
|
2014-03-17 20:49:05 +00:00
|
|
|
* Copyright (C) 2010-2014 Red Hat, Inc.
|
2012-07-13 11:21:27 +00:00
|
|
|
* Copyright IBM Corp. 2008
|
|
|
|
*
|
|
|
|
* lxc_cgroup.c: LXC cgroup helpers
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2012-07-13 11:21:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "lxc_cgroup.h"
|
|
|
|
#include "lxc_container.h"
|
2020-02-17 21:29:11 +00:00
|
|
|
#include "domain_cgroup.h"
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
#include "virfile.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2016-02-01 15:50:54 +00:00
|
|
|
#include "virsystemd.h"
|
2012-07-13 11:21:27 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("lxc.lxc_cgroup");
|
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
static int virLXCCgroupSetupCpuTune(virDomainDefPtr def,
|
|
|
|
virCgroupPtr cgroup)
|
|
|
|
{
|
2014-03-04 12:56:24 +00:00
|
|
|
if (def->cputune.sharesSpecified) {
|
|
|
|
unsigned long long val;
|
|
|
|
if (virCgroupSetCpuShares(cgroup, def->cputune.shares) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2014-03-04 12:56:24 +00:00
|
|
|
|
|
|
|
if (virCgroupGetCpuShares(cgroup, &val) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2014-03-04 12:56:24 +00:00
|
|
|
def->cputune.shares = val;
|
|
|
|
}
|
2013-07-08 10:08:46 +00:00
|
|
|
|
|
|
|
if (def->cputune.quota != 0 &&
|
|
|
|
virCgroupSetCpuCfsQuota(cgroup, def->cputune.quota) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2013-07-08 10:08:46 +00:00
|
|
|
|
|
|
|
if (def->cputune.period != 0 &&
|
|
|
|
virCgroupSetCpuCfsPeriod(cgroup, def->cputune.period) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2013-07-08 10:08:46 +00:00
|
|
|
|
2019-10-21 18:18:55 +00:00
|
|
|
return 0;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 03:35:09 +00:00
|
|
|
static int virLXCCgroupSetupCpusetTune(virDomainDefPtr def,
|
|
|
|
virCgroupPtr cgroup,
|
|
|
|
virBitmapPtr nodemask)
|
|
|
|
{
|
2013-07-08 10:08:46 +00:00
|
|
|
int ret = -1;
|
2013-03-20 03:35:09 +00:00
|
|
|
char *mask = NULL;
|
2015-05-19 09:55:26 +00:00
|
|
|
virDomainNumatuneMemMode mode;
|
2013-03-20 03:35:09 +00:00
|
|
|
|
|
|
|
if (def->placement_mode != VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO &&
|
|
|
|
def->cpumask) {
|
2014-06-05 09:24:24 +00:00
|
|
|
if (!(mask = virBitmapFormat(def->cpumask)))
|
2013-03-20 03:35:09 +00:00
|
|
|
return -1;
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupSetCpusetCpus(cgroup, mask) < 0)
|
2013-03-20 03:35:09 +00:00
|
|
|
goto cleanup;
|
2015-04-03 10:11:15 +00:00
|
|
|
/* free mask to make sure we won't use it in a wrong way later */
|
|
|
|
VIR_FREE(mask);
|
2013-03-20 03:35:09 +00:00
|
|
|
}
|
|
|
|
|
2015-05-19 09:55:26 +00:00
|
|
|
if (virDomainNumatuneGetMode(def->numa, -1, &mode) < 0 ||
|
|
|
|
mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
2015-04-20 13:33:31 +00:00
|
|
|
ret = 0;
|
2014-11-10 13:53:18 +00:00
|
|
|
goto cleanup;
|
2015-04-20 13:33:31 +00:00
|
|
|
}
|
2014-11-10 13:53:18 +00:00
|
|
|
|
2015-02-11 13:54:59 +00:00
|
|
|
if (virDomainNumatuneMaybeFormatNodeset(def->numa, nodemask,
|
2014-06-26 17:46:45 +00:00
|
|
|
&mask, -1) < 0)
|
2014-06-09 13:00:22 +00:00
|
|
|
goto cleanup;
|
2013-03-20 03:35:09 +00:00
|
|
|
|
2014-06-09 13:00:22 +00:00
|
|
|
if (mask && virCgroupSetCpusetMems(cgroup, mask) < 0)
|
|
|
|
goto cleanup;
|
2013-03-20 03:35:09 +00:00
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
ret = 0;
|
2014-03-25 06:49:26 +00:00
|
|
|
cleanup:
|
2013-03-20 03:35:09 +00:00
|
|
|
VIR_FREE(mask);
|
2013-07-08 10:08:46 +00:00
|
|
|
return ret;
|
2013-03-20 03:35:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def,
|
|
|
|
virCgroupPtr cgroup)
|
|
|
|
{
|
2020-02-17 21:29:11 +00:00
|
|
|
return virDomainCgroupSetupBlkio(cgroup, def->blkio);
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virLXCCgroupSetupMemTune(virDomainDefPtr def,
|
|
|
|
virCgroupPtr cgroup)
|
|
|
|
{
|
2015-02-17 17:01:09 +00:00
|
|
|
if (virCgroupSetMemory(cgroup, virDomainDefGetMemoryInitial(def)) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2020-02-17 21:29:12 +00:00
|
|
|
return virDomainCgroupSetupMemtune(cgroup, def->mem);
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
static int virLXCCgroupGetMemSwapUsage(virCgroupPtr cgroup,
|
|
|
|
virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
|
|
|
return virCgroupGetMemSwapUsage(cgroup, &meminfo->swapusage);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virLXCCgroupGetMemSwapTotal(virCgroupPtr cgroup,
|
|
|
|
virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
|
|
|
return virCgroupGetMemSwapHardLimit(cgroup, &meminfo->swaptotal);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virLXCCgroupGetMemUsage(virCgroupPtr cgroup,
|
|
|
|
virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
unsigned long memUsage;
|
|
|
|
|
|
|
|
ret = virCgroupGetMemoryUsage(cgroup, &memUsage);
|
2018-04-25 12:42:34 +00:00
|
|
|
meminfo->memusage = (unsigned long long)memUsage;
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virLXCCgroupGetMemTotal(virCgroupPtr cgroup,
|
|
|
|
virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
|
|
|
return virCgroupGetMemoryHardLimit(cgroup, &meminfo->memtotal);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int virLXCCgroupGetMemStat(virCgroupPtr cgroup,
|
|
|
|
virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
2018-07-20 12:48:56 +00:00
|
|
|
return virCgroupGetMemoryStat(cgroup,
|
|
|
|
&meminfo->cached,
|
|
|
|
&meminfo->inactive_anon,
|
|
|
|
&meminfo->active_anon,
|
|
|
|
&meminfo->inactive_file,
|
|
|
|
&meminfo->active_file,
|
|
|
|
&meminfo->unevictable);
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo)
|
|
|
|
{
|
2013-07-08 10:08:46 +00:00
|
|
|
int ret = -1;
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
virCgroupPtr cgroup;
|
|
|
|
|
2013-07-04 15:49:24 +00:00
|
|
|
if (virCgroupNewSelf(&cgroup) < 0)
|
|
|
|
return -1;
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virLXCCgroupGetMemStat(cgroup, meminfo) < 0)
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virLXCCgroupGetMemTotal(cgroup, meminfo) < 0)
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virLXCCgroupGetMemUsage(cgroup, meminfo) < 0)
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2014-06-25 01:57:32 +00:00
|
|
|
if (virLXCCgroupGetMemSwapTotal(cgroup, meminfo) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (virLXCCgroupGetMemSwapUsage(cgroup, meminfo) < 0)
|
|
|
|
goto cleanup;
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
|
|
|
|
ret = 0;
|
2014-03-25 06:49:26 +00:00
|
|
|
cleanup:
|
2018-07-30 09:06:31 +00:00
|
|
|
virCgroupFree(&cgroup);
|
make /proc/meminfo isolate with host through fuse
with this patch,container's meminfo will be shown based on
containers' mem cgroup.
Right now,it's impossible to virtualize all values in meminfo,
I collect some values such as MemTotal,MemFree,Cached,Active,
Inactive,Active(anon),Inactive(anon),Active(file),Inactive(anon),
Active(file),Inactive(file),Unevictable,SwapTotal,SwapFree.
if I miss something, please let me know.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
2012-11-12 11:52:01 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
typedef struct _virLXCCgroupDevicePolicy virLXCCgroupDevicePolicy;
|
|
|
|
typedef virLXCCgroupDevicePolicy *virLXCCgroupDevicePolicyPtr;
|
|
|
|
|
|
|
|
struct _virLXCCgroupDevicePolicy {
|
|
|
|
char type;
|
|
|
|
int major;
|
|
|
|
int minor;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-11-23 14:46:18 +00:00
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virLXCSetupHostUSBDeviceCgroup(virUSBDevicePtr dev G_GNUC_UNUSED,
|
2012-11-23 14:46:18 +00:00
|
|
|
const char *path,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
virCgroupPtr cgroup = opaque;
|
|
|
|
|
|
|
|
VIR_DEBUG("Process path '%s' for USB device", path);
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupAllowDevicePath(cgroup, path,
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_RWM, false) < 0)
|
2012-11-23 14:46:18 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
2019-10-14 12:45:33 +00:00
|
|
|
virLXCTeardownHostUSBDeviceCgroup(virUSBDevicePtr dev G_GNUC_UNUSED,
|
2012-11-23 14:46:18 +00:00
|
|
|
const char *path,
|
|
|
|
void *opaque)
|
|
|
|
{
|
|
|
|
virCgroupPtr cgroup = opaque;
|
|
|
|
|
|
|
|
VIR_DEBUG("Process path '%s' for USB device", path);
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupDenyDevicePath(cgroup, path,
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_RWM, false) < 0)
|
2012-11-23 14:46:18 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
|
|
|
|
static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
|
|
|
|
virCgroupPtr cgroup)
|
|
|
|
{
|
2019-10-25 12:50:15 +00:00
|
|
|
int capMknod = def->caps_features[VIR_DOMAIN_PROCES_CAPS_FEATURE_MKNOD];
|
2012-07-13 11:21:27 +00:00
|
|
|
size_t i;
|
|
|
|
static virLXCCgroupDevicePolicy devices[] = {
|
|
|
|
{'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_NULL},
|
|
|
|
{'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_ZERO},
|
|
|
|
{'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_FULL},
|
|
|
|
{'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_RANDOM},
|
|
|
|
{'c', LXC_DEV_MAJ_MEMORY, LXC_DEV_MIN_URANDOM},
|
|
|
|
{'c', LXC_DEV_MAJ_TTY, LXC_DEV_MIN_TTY},
|
|
|
|
{'c', LXC_DEV_MAJ_TTY, LXC_DEV_MIN_PTMX},
|
2012-11-14 09:39:04 +00:00
|
|
|
{'c', LXC_DEV_MAJ_FUSE, LXC_DEV_MIN_FUSE},
|
2012-07-13 11:21:27 +00:00
|
|
|
{0, 0, 0}};
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupDenyAllDevices(cgroup) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2014-07-18 08:02:29 +00:00
|
|
|
/* white list mknod if CAP_MKNOD has to be kept */
|
2014-06-27 15:18:53 +00:00
|
|
|
if (capMknod == VIR_TRISTATE_SWITCH_ON) {
|
2014-07-18 08:02:29 +00:00
|
|
|
if (virCgroupAllowAllDevices(cgroup,
|
|
|
|
VIR_CGROUP_DEVICE_MKNOD) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2014-07-18 08:02:29 +00:00
|
|
|
}
|
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
for (i = 0; devices[i].type != 0; i++) {
|
|
|
|
virLXCCgroupDevicePolicyPtr dev = &devices[i];
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupAllowDevice(cgroup,
|
|
|
|
dev->type,
|
|
|
|
dev->major,
|
|
|
|
dev->minor,
|
|
|
|
VIR_CGROUP_DEVICE_RWM) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
2013-10-08 15:35:38 +00:00
|
|
|
VIR_DEBUG("Allowing any disk block devs");
|
2013-05-21 08:03:33 +00:00
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
2016-05-02 11:42:32 +00:00
|
|
|
if (virStorageSourceIsEmpty(def->disks[i]->src) ||
|
|
|
|
!virStorageSourceIsBlockLocal(def->disks[i]->src))
|
2012-11-22 14:33:48 +00:00
|
|
|
continue;
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupAllowDevicePath(cgroup,
|
2014-03-17 20:49:05 +00:00
|
|
|
virDomainDiskGetSource(def->disks[i]),
|
2014-06-24 13:15:55 +00:00
|
|
|
(def->disks[i]->src->readonly ?
|
2013-07-08 10:08:46 +00:00
|
|
|
VIR_CGROUP_DEVICE_READ :
|
|
|
|
VIR_CGROUP_DEVICE_RW) |
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_MKNOD, false) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-11-22 14:33:48 +00:00
|
|
|
}
|
|
|
|
|
2013-10-08 15:35:38 +00:00
|
|
|
VIR_DEBUG("Allowing any filesystem block devs");
|
2013-05-21 08:03:33 +00:00
|
|
|
for (i = 0; i < def->nfss; i++) {
|
2012-07-13 11:21:27 +00:00
|
|
|
if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_BLOCK)
|
|
|
|
continue;
|
|
|
|
|
2013-07-08 10:08:46 +00:00
|
|
|
if (virCgroupAllowDevicePath(cgroup,
|
2016-07-14 13:52:38 +00:00
|
|
|
def->fss[i]->src->path,
|
2013-07-08 10:08:46 +00:00
|
|
|
def->fss[i]->readonly ?
|
|
|
|
VIR_CGROUP_DEVICE_READ :
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_RW, false) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
2013-10-08 15:35:38 +00:00
|
|
|
VIR_DEBUG("Allowing any hostdev block devs");
|
2012-11-23 14:46:18 +00:00
|
|
|
for (i = 0; i < def->nhostdevs; i++) {
|
|
|
|
virDomainHostdevDefPtr hostdev = def->hostdevs[i];
|
2014-07-03 19:43:05 +00:00
|
|
|
virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
|
2013-01-14 22:11:44 +00:00
|
|
|
virUSBDevicePtr usb;
|
2012-11-23 14:46:18 +00:00
|
|
|
|
2012-11-28 16:13:27 +00:00
|
|
|
switch (hostdev->mode) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
|
|
|
|
if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
|
|
|
|
continue;
|
|
|
|
if (hostdev->missing)
|
|
|
|
continue;
|
|
|
|
|
2014-07-03 19:43:05 +00:00
|
|
|
if ((usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device,
|
2013-01-14 22:11:44 +00:00
|
|
|
NULL)) == NULL)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-11-28 16:13:27 +00:00
|
|
|
|
2014-03-13 11:58:17 +00:00
|
|
|
if (virUSBDeviceFileIterate(usb, virLXCSetupHostUSBDeviceCgroup,
|
2013-01-14 22:11:44 +00:00
|
|
|
cgroup) < 0) {
|
|
|
|
virUSBDeviceFree(usb);
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2013-02-05 15:14:46 +00:00
|
|
|
}
|
2013-01-14 22:11:44 +00:00
|
|
|
virUSBDeviceFree(usb);
|
2012-11-28 16:13:27 +00:00
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES:
|
|
|
|
switch (hostdev->source.caps.type) {
|
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE:
|
|
|
|
if (virCgroupAllowDevicePath(cgroup,
|
|
|
|
hostdev->source.caps.u.storage.block,
|
|
|
|
VIR_CGROUP_DEVICE_RW |
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_MKNOD, false) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-11-28 16:13:27 +00:00
|
|
|
break;
|
2012-11-28 18:07:47 +00:00
|
|
|
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
|
|
|
|
if (virCgroupAllowDevicePath(cgroup,
|
|
|
|
hostdev->source.caps.u.misc.chardev,
|
|
|
|
VIR_CGROUP_DEVICE_RW |
|
2016-02-16 13:43:41 +00:00
|
|
|
VIR_CGROUP_DEVICE_MKNOD, false) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-11-28 18:07:47 +00:00
|
|
|
break;
|
2012-11-28 16:13:27 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2012-11-23 14:46:18 +00:00
|
|
|
}
|
|
|
|
|
2016-02-16 12:57:10 +00:00
|
|
|
if (virCgroupAllowDevice(cgroup, 'c', LXC_DEV_MAJ_PTY, -1,
|
|
|
|
VIR_CGROUP_DEVICE_RWM) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2013-10-08 15:35:38 +00:00
|
|
|
VIR_DEBUG("Device whitelist complete");
|
|
|
|
|
2019-10-21 18:18:55 +00:00
|
|
|
return 0;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-16 16:23:45 +00:00
|
|
|
virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def,
|
2015-01-16 16:58:39 +00:00
|
|
|
pid_t initpid,
|
|
|
|
size_t nnicindexes,
|
|
|
|
int *nicindexes)
|
2012-07-13 11:21:27 +00:00
|
|
|
{
|
Change default cgroup layout for QEMU/LXC and honour XML config
Historically QEMU/LXC guests have been placed in a cgroup layout
that is
$LOCATION-OF-LIBVIRTD/libvirt/{qemu,lxc}/$VMNAME
This is bad for a number of reasons
- The cgroup hierarchy gets very deep which seriously
impacts kernel performance due to cgroups scalability
limitations.
- It is hard to setup cgroup policies which apply across
services and virtual machines, since all VMs are underneath
the libvirtd service.
To address this the default cgroup location is changed to
be
/system/$VMNAME.{lxc,qemu}.libvirt
This puts virtual machines at the same level in the hierarchy
as system services, allowing consistent policy to be setup
across all of them.
This also honours the new resource partition location from the
XML configuration, for example
<resource>
<partition>/virtualmachines/production</partitions>
</resource>
will result in the VM being placed at
/virtualmachines/production/$VMNAME.{lxc,qemu}.libvirt
NB, with the exception of the default, /system, path which
is intended to always exist, libvirt will not attempt to
auto-create the partitions in the XML. It is the responsibility
of the admin/app to configure the partitions. Later libvirt
APIs will provide a way todo this.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-04-03 10:01:49 +00:00
|
|
|
virCgroupPtr cgroup = NULL;
|
2017-07-21 13:51:03 +00:00
|
|
|
char *machineName = virLXCDomainGetMachineName(def, 0);
|
2016-02-01 15:50:54 +00:00
|
|
|
|
|
|
|
if (!machineName)
|
|
|
|
goto cleanup;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2013-07-22 12:59:28 +00:00
|
|
|
if (def->resource->partition[0] != '/') {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("Resource partition '%s' must start with '/'"),
|
|
|
|
def->resource->partition);
|
|
|
|
goto cleanup;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|
2013-07-22 12:59:28 +00:00
|
|
|
|
2016-02-01 15:50:54 +00:00
|
|
|
if (virCgroupNewMachine(machineName,
|
2013-07-22 16:11:09 +00:00
|
|
|
"lxc",
|
|
|
|
def->uuid,
|
|
|
|
NULL,
|
2015-01-16 16:23:45 +00:00
|
|
|
initpid,
|
2013-07-22 16:11:09 +00:00
|
|
|
true,
|
2015-01-16 16:58:39 +00:00
|
|
|
nnicindexes, nicindexes,
|
2013-07-22 16:11:09 +00:00
|
|
|
def->resource->partition,
|
|
|
|
-1,
|
2019-05-22 23:12:14 +00:00
|
|
|
0,
|
2016-01-14 16:01:50 +00:00
|
|
|
&cgroup) < 0)
|
2013-07-22 12:59:28 +00:00
|
|
|
goto cleanup;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2014-02-24 12:23:33 +00:00
|
|
|
/* setup control group permissions for user namespace */
|
|
|
|
if (def->idmap.uidmap) {
|
|
|
|
if (virCgroupSetOwner(cgroup,
|
|
|
|
def->idmap.uidmap[0].target,
|
|
|
|
def->idmap.gidmap[0].target,
|
|
|
|
(1 << VIR_CGROUP_CONTROLLER_SYSTEMD)) < 0) {
|
2018-07-30 09:06:31 +00:00
|
|
|
virCgroupFree(&cgroup);
|
2014-02-24 12:23:33 +00:00
|
|
|
cgroup = NULL;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-25 06:49:26 +00:00
|
|
|
cleanup:
|
2016-02-01 15:50:54 +00:00
|
|
|
VIR_FREE(machineName);
|
|
|
|
|
2013-03-14 12:47:28 +00:00
|
|
|
return cgroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int virLXCCgroupSetup(virDomainDefPtr def,
|
2013-03-20 03:35:09 +00:00
|
|
|
virCgroupPtr cgroup,
|
|
|
|
virBitmapPtr nodemask)
|
2013-03-14 12:47:28 +00:00
|
|
|
{
|
2012-07-13 11:21:27 +00:00
|
|
|
if (virLXCCgroupSetupCpuTune(def, cgroup) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
2013-03-20 03:35:09 +00:00
|
|
|
if (virLXCCgroupSetupCpusetTune(def, cgroup, nodemask) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2013-03-20 03:35:09 +00:00
|
|
|
|
2012-07-13 11:21:27 +00:00
|
|
|
if (virLXCCgroupSetupBlkioTune(def, cgroup) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
|
|
|
if (virLXCCgroupSetupMemTune(def, cgroup) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-07-13 11:21:27 +00:00
|
|
|
|
|
|
|
if (virLXCCgroupSetupDeviceACL(def, cgroup) < 0)
|
2019-10-21 18:18:55 +00:00
|
|
|
return -1;
|
2012-11-23 10:42:18 +00:00
|
|
|
|
2019-10-21 18:18:55 +00:00
|
|
|
return 0;
|
2012-07-13 11:21:27 +00:00
|
|
|
}
|