mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-26 15:45:28 +00:00
Merge processinfo.{c,h} into virprocess.{c,h}
This commit is contained in:
parent
3ddddd98c3
commit
f56c773bf8
@ -139,7 +139,6 @@ src/test/test_driver.c
|
|||||||
src/uml/uml_conf.c
|
src/uml/uml_conf.c
|
||||||
src/uml/uml_driver.c
|
src/uml/uml_driver.c
|
||||||
src/util/iohelper.c
|
src/util/iohelper.c
|
||||||
src/util/processinfo.c
|
|
||||||
src/util/sexpr.c
|
src/util/sexpr.c
|
||||||
src/util/stats_linux.c
|
src/util/stats_linux.c
|
||||||
src/util/storage_file.c
|
src/util/storage_file.c
|
||||||
|
@ -53,7 +53,6 @@ augeastest_DATA =
|
|||||||
# These files are not related to driver APIs. Simply generic
|
# These files are not related to driver APIs. Simply generic
|
||||||
# helper APIs for various purposes
|
# helper APIs for various purposes
|
||||||
UTIL_SOURCES = \
|
UTIL_SOURCES = \
|
||||||
util/processinfo.c util/processinfo.h \
|
|
||||||
util/sexpr.c util/sexpr.h \
|
util/sexpr.c util/sexpr.h \
|
||||||
util/stats_linux.c util/stats_linux.h \
|
util/stats_linux.c util/stats_linux.h \
|
||||||
util/storage_file.c util/storage_file.h \
|
util/storage_file.c util/storage_file.h \
|
||||||
|
@ -1028,11 +1028,6 @@ pciResetDevice;
|
|||||||
pciWaitForDeviceCleanup;
|
pciWaitForDeviceCleanup;
|
||||||
|
|
||||||
|
|
||||||
# processinfo.h
|
|
||||||
virProcessInfoGetAffinity;
|
|
||||||
virProcessInfoSetAffinity;
|
|
||||||
|
|
||||||
|
|
||||||
# secret_conf.h
|
# secret_conf.h
|
||||||
virSecretDefFormat;
|
virSecretDefFormat;
|
||||||
virSecretDefFree;
|
virSecretDefFree;
|
||||||
@ -1794,8 +1789,10 @@ virPidFileWritePath;
|
|||||||
|
|
||||||
# virprocess.h
|
# virprocess.h
|
||||||
virProcessAbort;
|
virProcessAbort;
|
||||||
|
virProcessGetAffinity;
|
||||||
virProcessKill;
|
virProcessKill;
|
||||||
virProcessKillPainfully;
|
virProcessKillPainfully;
|
||||||
|
virProcessSetAffinity;
|
||||||
virProcessTranslateStatus;
|
virProcessTranslateStatus;
|
||||||
virProcessWait;
|
virProcessWait;
|
||||||
|
|
||||||
|
@ -67,7 +67,6 @@
|
|||||||
#include "virfile.h"
|
#include "virfile.h"
|
||||||
#include "virpidfile.h"
|
#include "virpidfile.h"
|
||||||
#include "vircommand.h"
|
#include "vircommand.h"
|
||||||
#include "processinfo.h"
|
|
||||||
#include "nodeinfo.h"
|
#include "nodeinfo.h"
|
||||||
#include "virrandom.h"
|
#include "virrandom.h"
|
||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
@ -541,7 +540,7 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
|
|||||||
* so use '0' to indicate our own process ID. No threads are
|
* so use '0' to indicate our own process ID. No threads are
|
||||||
* running at this point
|
* running at this point
|
||||||
*/
|
*/
|
||||||
if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0) {
|
if (virProcessSetAffinity(0 /* Self */, cpumapToSet) < 0) {
|
||||||
virBitmapFree(cpumap);
|
virBitmapFree(cpumap);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
#include "node_device_conf.h"
|
#include "node_device_conf.h"
|
||||||
#include "virpci.h"
|
#include "virpci.h"
|
||||||
#include "virusb.h"
|
#include "virusb.h"
|
||||||
#include "processinfo.h"
|
#include "virprocess.h"
|
||||||
#include "libvirt_internal.h"
|
#include "libvirt_internal.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "cpu/cpu.h"
|
#include "cpu/cpu.h"
|
||||||
@ -3880,7 +3880,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virProcessInfoSetAffinity(cpupids[i],
|
if (virProcessSetAffinity(cpupids[i],
|
||||||
vcpupin->cpumask) < 0) {
|
vcpupin->cpumask) < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
_("failed to set cpu affinity for vcpu %d"),
|
_("failed to set cpu affinity for vcpu %d"),
|
||||||
@ -4154,7 +4154,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) {
|
if (virProcessSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||||
_("failed to set cpu affinity for vcpu %d"),
|
_("failed to set cpu affinity for vcpu %d"),
|
||||||
vcpu);
|
vcpu);
|
||||||
@ -4422,7 +4422,7 @@ qemuDomainPinEmulator(virDomainPtr dom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virProcessInfoSetAffinity(pid, pcpumap) < 0) {
|
if (virProcessSetAffinity(pid, pcpumap) < 0) {
|
||||||
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
|
virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
|
||||||
_("failed to set cpu affinity for "
|
_("failed to set cpu affinity for "
|
||||||
"emulator threads"));
|
"emulator threads"));
|
||||||
@ -4640,7 +4640,7 @@ qemuDomainGetVcpus(virDomainPtr dom,
|
|||||||
unsigned char *tmpmap = NULL;
|
unsigned char *tmpmap = NULL;
|
||||||
int tmpmapLen = 0;
|
int tmpmapLen = 0;
|
||||||
|
|
||||||
if (virProcessInfoGetAffinity(priv->vcpupids[v],
|
if (virProcessGetAffinity(priv->vcpupids[v],
|
||||||
&map, maxcpu) < 0)
|
&map, maxcpu) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
virBitmapToData(map, &tmpmap, &tmpmapLen);
|
virBitmapToData(map, &tmpmap, &tmpmapLen);
|
||||||
|
@ -60,7 +60,6 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "c-ctype.h"
|
#include "c-ctype.h"
|
||||||
#include "nodeinfo.h"
|
#include "nodeinfo.h"
|
||||||
#include "processinfo.h"
|
|
||||||
#include "domain_audit.h"
|
#include "domain_audit.h"
|
||||||
#include "domain_nwfilter.h"
|
#include "domain_nwfilter.h"
|
||||||
#include "locking/domain_lock.h"
|
#include "locking/domain_lock.h"
|
||||||
@ -1980,7 +1979,7 @@ qemuProcessInitCpuAffinity(virQEMUDriverPtr driver,
|
|||||||
* so use '0' to indicate our own process ID. No threads are
|
* so use '0' to indicate our own process ID. No threads are
|
||||||
* running at this point
|
* running at this point
|
||||||
*/
|
*/
|
||||||
if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0)
|
if (virProcessSetAffinity(0 /* Self */, cpumapToSet) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -2045,7 +2044,7 @@ qemuProcessSetVcpuAffinities(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
for (n = 0; n < def->cputune.nvcpupin; n++) {
|
for (n = 0; n < def->cputune.nvcpupin; n++) {
|
||||||
vcpu = def->cputune.vcpupin[n]->vcpuid;
|
vcpu = def->cputune.vcpupin[n]->vcpuid;
|
||||||
|
|
||||||
if (virProcessInfoSetAffinity(priv->vcpupids[vcpu],
|
if (virProcessSetAffinity(priv->vcpupids[vcpu],
|
||||||
def->cputune.vcpupin[n]->cpumask) < 0) {
|
def->cputune.vcpupin[n]->cpumask) < 0) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -2072,7 +2071,7 @@ qemuProcessSetEmulatorAffinities(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = virProcessInfoSetAffinity(vm->pid, cpumask);
|
ret = virProcessSetAffinity(vm->pid, cpumask);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009-2010, 2012 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* License along with this library. If not, see
|
|
||||||
* <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Daniel P. Berrange <berrange@redhat.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sched.h>
|
|
||||||
|
|
||||||
#include "processinfo.h"
|
|
||||||
#include "virterror_internal.h"
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
||||||
|
|
||||||
#if HAVE_SCHED_GETAFFINITY
|
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid, virBitmapPtr map)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool set = false;
|
|
||||||
# ifdef CPU_ALLOC
|
|
||||||
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
|
||||||
int numcpus = 1024;
|
|
||||||
size_t masklen;
|
|
||||||
cpu_set_t *mask;
|
|
||||||
|
|
||||||
/* Not only may the statically allocated cpu_set_t be too small,
|
|
||||||
* but there is no way to ask the kernel what size is large enough.
|
|
||||||
* So you have no option but to pick a size, try, catch EINVAL,
|
|
||||||
* enlarge, and re-try.
|
|
||||||
*
|
|
||||||
* http://lkml.org/lkml/2009/7/28/620
|
|
||||||
*/
|
|
||||||
realloc:
|
|
||||||
masklen = CPU_ALLOC_SIZE(numcpus);
|
|
||||||
mask = CPU_ALLOC(numcpus);
|
|
||||||
|
|
||||||
if (!mask) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPU_ZERO_S(masklen, mask);
|
|
||||||
for (i = 0 ; i < virBitmapSize(map); i++) {
|
|
||||||
if (virBitmapGetBit(map, i, &set) < 0)
|
|
||||||
return -1;
|
|
||||||
if (set)
|
|
||||||
CPU_SET_S(i, masklen, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sched_setaffinity(pid, masklen, mask) < 0) {
|
|
||||||
CPU_FREE(mask);
|
|
||||||
if (errno == EINVAL &&
|
|
||||||
numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */
|
|
||||||
numcpus = numcpus << 2;
|
|
||||||
goto realloc;
|
|
||||||
}
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot set CPU affinity on process %d"), pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
CPU_FREE(mask);
|
|
||||||
# else
|
|
||||||
/* Legacy method uses a fixed size cpu mask, only allows up to 1024 cpus */
|
|
||||||
cpu_set_t mask;
|
|
||||||
|
|
||||||
CPU_ZERO(&mask);
|
|
||||||
for (i = 0 ; i < virBitmapSize(map); i++) {
|
|
||||||
if (virBitmapGetBit(map, i, &set) < 0)
|
|
||||||
return -1;
|
|
||||||
if (set)
|
|
||||||
CPU_SET(i, &mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sched_setaffinity(pid, sizeof(mask), &mask) < 0) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot set CPU affinity on process %d"), pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid,
|
|
||||||
virBitmapPtr *map,
|
|
||||||
int maxcpu)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
# ifdef CPU_ALLOC
|
|
||||||
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
|
||||||
int numcpus = 1024;
|
|
||||||
size_t masklen;
|
|
||||||
cpu_set_t *mask;
|
|
||||||
|
|
||||||
/* Not only may the statically allocated cpu_set_t be too small,
|
|
||||||
* but there is no way to ask the kernel what size is large enough.
|
|
||||||
* So you have no option but to pick a size, try, catch EINVAL,
|
|
||||||
* enlarge, and re-try.
|
|
||||||
*
|
|
||||||
* http://lkml.org/lkml/2009/7/28/620
|
|
||||||
*/
|
|
||||||
realloc:
|
|
||||||
masklen = CPU_ALLOC_SIZE(numcpus);
|
|
||||||
mask = CPU_ALLOC(numcpus);
|
|
||||||
|
|
||||||
if (!mask) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPU_ZERO_S(masklen, mask);
|
|
||||||
if (sched_getaffinity(pid, masklen, mask) < 0) {
|
|
||||||
CPU_FREE(mask);
|
|
||||||
if (errno == EINVAL &&
|
|
||||||
numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */
|
|
||||||
numcpus = numcpus << 2;
|
|
||||||
goto realloc;
|
|
||||||
}
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot get CPU affinity of process %d"), pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*map = virBitmapNew(maxcpu);
|
|
||||||
if (!*map) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < maxcpu ; i++)
|
|
||||||
if (CPU_ISSET_S(i, masklen, mask))
|
|
||||||
ignore_value(virBitmapSetBit(*map, i));
|
|
||||||
CPU_FREE(mask);
|
|
||||||
# else
|
|
||||||
/* Legacy method uses a fixed size cpu mask, only allows up to 1024 cpus */
|
|
||||||
cpu_set_t mask;
|
|
||||||
|
|
||||||
CPU_ZERO(&mask);
|
|
||||||
if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("cannot get CPU affinity of process %d"), pid);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < maxcpu ; i++)
|
|
||||||
if (CPU_ISSET(i, &mask))
|
|
||||||
ignore_value(virBitmapSetBit(*map, i));
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
|
||||||
virBitmapPtr map)
|
|
||||||
{
|
|
||||||
if (!virBitmapIsAllSet(map)) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("setting process affinity isn't supported "
|
|
||||||
"on FreeBSD yet"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
|
||||||
virBitmapPtr *map,
|
|
||||||
int maxcpu)
|
|
||||||
{
|
|
||||||
if (!(*map = virBitmapNew(maxcpu))) {
|
|
||||||
virReportOOMError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
virBitmapSetAll(*map);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* HAVE_SCHED_GETAFFINITY */
|
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
|
||||||
virBitmapPtr map ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s",
|
|
||||||
_("Process CPU affinity is not supported on this platform"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
|
||||||
virBitmapPtr *map ATTRIBUTE_UNUSED,
|
|
||||||
int maxcpu ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
virReportSystemError(ENOSYS, "%s",
|
|
||||||
_("Process CPU affinity is not supported on this platform"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_SCHED_GETAFFINITY */
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 Red Hat, Inc.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* License along with this library. If not, see
|
|
||||||
* <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Daniel P. Berrange <berrange@redhat.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __VIR_PROCESSINFO_H__
|
|
||||||
# define __VIR_PROCESSINFO_H__
|
|
||||||
|
|
||||||
# include "internal.h"
|
|
||||||
# include "virbitmap.h"
|
|
||||||
|
|
||||||
int virProcessInfoSetAffinity(pid_t pid, virBitmapPtr map);
|
|
||||||
|
|
||||||
int virProcessInfoGetAffinity(pid_t pid,
|
|
||||||
virBitmapPtr *map,
|
|
||||||
int maxcpu);
|
|
||||||
|
|
||||||
#endif /* __VIR_PROCESSINFO_H__ */
|
|
@ -25,6 +25,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
@ -300,3 +301,191 @@ virProcessKillPainfully(pid_t pid, bool force)
|
|||||||
cleanup:
|
cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if HAVE_SCHED_GETAFFINITY
|
||||||
|
|
||||||
|
int virProcessSetAffinity(pid_t pid, virBitmapPtr map)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
bool set = false;
|
||||||
|
# ifdef CPU_ALLOC
|
||||||
|
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
||||||
|
int numcpus = 1024;
|
||||||
|
size_t masklen;
|
||||||
|
cpu_set_t *mask;
|
||||||
|
|
||||||
|
/* Not only may the statically allocated cpu_set_t be too small,
|
||||||
|
* but there is no way to ask the kernel what size is large enough.
|
||||||
|
* So you have no option but to pick a size, try, catch EINVAL,
|
||||||
|
* enlarge, and re-try.
|
||||||
|
*
|
||||||
|
* http://lkml.org/lkml/2009/7/28/620
|
||||||
|
*/
|
||||||
|
realloc:
|
||||||
|
masklen = CPU_ALLOC_SIZE(numcpus);
|
||||||
|
mask = CPU_ALLOC(numcpus);
|
||||||
|
|
||||||
|
if (!mask) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPU_ZERO_S(masklen, mask);
|
||||||
|
for (i = 0 ; i < virBitmapSize(map); i++) {
|
||||||
|
if (virBitmapGetBit(map, i, &set) < 0)
|
||||||
|
return -1;
|
||||||
|
if (set)
|
||||||
|
CPU_SET_S(i, masklen, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sched_setaffinity(pid, masklen, mask) < 0) {
|
||||||
|
CPU_FREE(mask);
|
||||||
|
if (errno == EINVAL &&
|
||||||
|
numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */
|
||||||
|
numcpus = numcpus << 2;
|
||||||
|
goto realloc;
|
||||||
|
}
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot set CPU affinity on process %d"), pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
CPU_FREE(mask);
|
||||||
|
# else
|
||||||
|
/* Legacy method uses a fixed size cpu mask, only allows up to 1024 cpus */
|
||||||
|
cpu_set_t mask;
|
||||||
|
|
||||||
|
CPU_ZERO(&mask);
|
||||||
|
for (i = 0 ; i < virBitmapSize(map); i++) {
|
||||||
|
if (virBitmapGetBit(map, i, &set) < 0)
|
||||||
|
return -1;
|
||||||
|
if (set)
|
||||||
|
CPU_SET(i, &mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sched_setaffinity(pid, sizeof(mask), &mask) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot set CPU affinity on process %d"), pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virProcessGetAffinity(pid_t pid,
|
||||||
|
virBitmapPtr *map,
|
||||||
|
int maxcpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
# ifdef CPU_ALLOC
|
||||||
|
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
|
||||||
|
int numcpus = 1024;
|
||||||
|
size_t masklen;
|
||||||
|
cpu_set_t *mask;
|
||||||
|
|
||||||
|
/* Not only may the statically allocated cpu_set_t be too small,
|
||||||
|
* but there is no way to ask the kernel what size is large enough.
|
||||||
|
* So you have no option but to pick a size, try, catch EINVAL,
|
||||||
|
* enlarge, and re-try.
|
||||||
|
*
|
||||||
|
* http://lkml.org/lkml/2009/7/28/620
|
||||||
|
*/
|
||||||
|
realloc:
|
||||||
|
masklen = CPU_ALLOC_SIZE(numcpus);
|
||||||
|
mask = CPU_ALLOC(numcpus);
|
||||||
|
|
||||||
|
if (!mask) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPU_ZERO_S(masklen, mask);
|
||||||
|
if (sched_getaffinity(pid, masklen, mask) < 0) {
|
||||||
|
CPU_FREE(mask);
|
||||||
|
if (errno == EINVAL &&
|
||||||
|
numcpus < (1024 << 8)) { /* 262144 cpus ought to be enough for anyone */
|
||||||
|
numcpus = numcpus << 2;
|
||||||
|
goto realloc;
|
||||||
|
}
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot get CPU affinity of process %d"), pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*map = virBitmapNew(maxcpu);
|
||||||
|
if (!*map) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < maxcpu ; i++)
|
||||||
|
if (CPU_ISSET_S(i, masklen, mask))
|
||||||
|
ignore_value(virBitmapSetBit(*map, i));
|
||||||
|
CPU_FREE(mask);
|
||||||
|
# else
|
||||||
|
/* Legacy method uses a fixed size cpu mask, only allows up to 1024 cpus */
|
||||||
|
cpu_set_t mask;
|
||||||
|
|
||||||
|
CPU_ZERO(&mask);
|
||||||
|
if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("cannot get CPU affinity of process %d"), pid);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < maxcpu ; i++)
|
||||||
|
if (CPU_ISSET(i, &mask))
|
||||||
|
ignore_value(virBitmapSetBit(*map, i));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
|
||||||
|
int virProcessSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
|
virBitmapPtr map)
|
||||||
|
{
|
||||||
|
if (!virBitmapIsAllSet(map)) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("setting process affinity isn't supported "
|
||||||
|
"on FreeBSD yet"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virProcessGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
|
virBitmapPtr *map,
|
||||||
|
int maxcpu)
|
||||||
|
{
|
||||||
|
if (!(*map = virBitmapNew(maxcpu))) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
virBitmapSetAll(*map);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_SCHED_GETAFFINITY */
|
||||||
|
|
||||||
|
int virProcessSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
|
virBitmapPtr map ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Process CPU affinity is not supported on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virProcessGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
|
||||||
|
virBitmapPtr *map ATTRIBUTE_UNUSED,
|
||||||
|
int maxcpu ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virReportSystemError(ENOSYS, "%s",
|
||||||
|
_("Process CPU affinity is not supported on this platform"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_SCHED_GETAFFINITY */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
|
|
||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
|
# include "virbitmap.h"
|
||||||
|
|
||||||
char *
|
char *
|
||||||
virProcessTranslateStatus(int status);
|
virProcessTranslateStatus(int status);
|
||||||
@ -40,5 +41,10 @@ int virProcessKill(pid_t pid, int sig);
|
|||||||
|
|
||||||
int virProcessKillPainfully(pid_t pid, bool force);
|
int virProcessKillPainfully(pid_t pid, bool force);
|
||||||
|
|
||||||
|
int virProcessSetAffinity(pid_t pid, virBitmapPtr map);
|
||||||
|
|
||||||
|
int virProcessGetAffinity(pid_t pid,
|
||||||
|
virBitmapPtr *map,
|
||||||
|
int maxcpu);
|
||||||
|
|
||||||
#endif /* __VIR_PROCESS_H__ */
|
#endif /* __VIR_PROCESS_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user