Merge processinfo.{c,h} into virprocess.{c,h}

This commit is contained in:
Daniel P. Berrange 2012-12-13 14:58:41 +00:00
parent 3ddddd98c3
commit f56c773bf8
10 changed files with 209 additions and 272 deletions

View File

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

View File

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

View File

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

View File

@ -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;
} }

View File

@ -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,8 +3880,8 @@ 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"),
i); i);
@ -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,8 +4640,8 @@ 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);
if (tmpmapLen > maplen) if (tmpmapLen > maplen)

View File

@ -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,8 +2044,8 @@ 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;
} }

View File

@ -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 */

View File

@ -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__ */

View File

@ -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 */

View File

@ -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__ */