From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> --- po/POTFILES.in | 1 - src/Makefile.am | 1 - src/libvirt_private.syms | 7 +- src/lxc/lxc_controller.c | 3 +- src/qemu/qemu_driver.c | 14 ++-- src/qemu/qemu_process.c | 9 +-- src/util/processinfo.c | 189 ----------------------------------------------- src/util/processinfo.h | 34 --------- src/util/virprocess.c | 161 ++++++++++++++++++++++++++++++++++++++++ src/util/virprocess.h | 6 ++ 10 files changed, 181 insertions(+), 244 deletions(-) delete mode 100644 src/util/processinfo.c delete mode 100644 src/util/processinfo.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 18db09b..fb73807 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -138,7 +138,6 @@ src/test/test_driver.c src/uml/uml_conf.c src/uml/uml_driver.c src/util/iohelper.c -src/util/processinfo.c src/util/sexpr.c src/util/stats_linux.c src/util/storage_file.c diff --git a/src/Makefile.am b/src/Makefile.am index d9f621f..c0e35dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,6 @@ augeastest_DATA = # These files are not related to driver APIs. Simply generic # helper APIs for various purposes UTIL_SOURCES = \ - util/processinfo.c util/processinfo.h \ util/sexpr.c util/sexpr.h \ util/stats_linux.c util/stats_linux.h \ util/storage_file.c util/storage_file.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9288ad3..5f79484 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1027,11 +1027,6 @@ pciResetDevice; pciWaitForDeviceCleanup; -# processinfo.h -virProcessInfoGetAffinity; -virProcessInfoSetAffinity; - - # secret_conf.h virSecretDefFormat; virSecretDefFree; @@ -1784,8 +1779,10 @@ virPidFileWritePath; # virprocess.h virProcessAbort; +virProcessGetAffinity; virProcessKill; virProcessKillPainfully; +virProcessSetAffinity; virProcessTranslateStatus; virProcessWait; diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 8a83e71..6b6ec82 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -68,7 +68,6 @@ #include "virfile.h" #include "virpidfile.h" #include "vircommand.h" -#include "processinfo.h" #include "nodeinfo.h" #include "virrandom.h" #include "virprocess.h" @@ -542,7 +541,7 @@ static int virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl) * so use '0' to indicate our own process ID. No threads are * running at this point */ - if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0) { + if (virProcessSetAffinity(0 /* Self */, cpumapToSet) < 0) { virBitmapFree(cpumap); return -1; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 14a5e44..488c814 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -74,7 +74,7 @@ #include "node_device_conf.h" #include "virpci.h" #include "virusb.h" -#include "processinfo.h" +#include "virprocess.h" #include "libvirt_internal.h" #include "xml.h" #include "cpu/cpu.h" @@ -3881,8 +3881,8 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver, goto cleanup; } } else { - if (virProcessInfoSetAffinity(cpupids[i], - vcpupin->cpumask) < 0) { + if (virProcessSetAffinity(cpupids[i], + vcpupin->cpumask) < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, _("failed to set cpu affinity for vcpu %d"), i); @@ -4155,7 +4155,7 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, goto cleanup; } } else { - if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) { + if (virProcessSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, _("failed to set cpu affinity for vcpu %d"), vcpu); @@ -4423,7 +4423,7 @@ qemuDomainPinEmulator(virDomainPtr dom, } } } else { - if (virProcessInfoSetAffinity(pid, pcpumap) < 0) { + if (virProcessSetAffinity(pid, pcpumap) < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, "%s", _("failed to set cpu affinity for " "emulator threads")); @@ -4641,8 +4641,8 @@ qemuDomainGetVcpus(virDomainPtr dom, unsigned char *tmpmap = NULL; int tmpmapLen = 0; - if (virProcessInfoGetAffinity(priv->vcpupids[v], - &map, maxcpu) < 0) + if (virProcessGetAffinity(priv->vcpupids[v], + &map, maxcpu) < 0) goto cleanup; virBitmapToData(map, &tmpmap, &tmpmapLen); if (tmpmapLen > maplen) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b20734d..794596b 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -60,7 +60,6 @@ #include "util.h" #include "c-ctype.h" #include "nodeinfo.h" -#include "processinfo.h" #include "domain_audit.h" #include "domain_nwfilter.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 * running at this point */ - if (virProcessInfoSetAffinity(0 /* Self */, cpumapToSet) < 0) + if (virProcessSetAffinity(0 /* Self */, cpumapToSet) < 0) goto cleanup; ret = 0; @@ -2045,8 +2044,8 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn ATTRIBUTE_UNUSED, for (n = 0; n < def->cputune.nvcpupin; n++) { vcpu = def->cputune.vcpupin[n]->vcpuid; - if (virProcessInfoSetAffinity(priv->vcpupids[vcpu], - def->cputune.vcpupin[n]->cpumask) < 0) { + if (virProcessSetAffinity(priv->vcpupids[vcpu], + def->cputune.vcpupin[n]->cpumask) < 0) { goto cleanup; } } @@ -2072,7 +2071,7 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn ATTRIBUTE_UNUSED, else return 0; - ret = virProcessInfoSetAffinity(vm->pid, cpumask); + ret = virProcessSetAffinity(vm->pid, cpumask); return ret; } diff --git a/src/util/processinfo.c b/src/util/processinfo.c deleted file mode 100644 index b1db049..0000000 --- a/src/util/processinfo.c +++ /dev/null @@ -1,189 +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@xxxxxxxxxx> - */ - -#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; -} - -#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 */ diff --git a/src/util/processinfo.h b/src/util/processinfo.h deleted file mode 100644 index 0ae23c6..0000000 --- a/src/util/processinfo.h +++ /dev/null @@ -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@xxxxxxxxxx> - */ - -#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__ */ diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 8070b8b..155e4e2 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -25,6 +25,7 @@ #include <signal.h> #include <errno.h> #include <sys/wait.h> +#include <sched.h> #include "virprocess.h" #include "virterror_internal.h" @@ -300,3 +301,163 @@ virProcessKillPainfully(pid_t pid, bool force) cleanup: 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; +} + +#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 */ diff --git a/src/util/virprocess.h b/src/util/virprocess.h index d537d92..8724f64 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -25,6 +25,7 @@ # include <sys/types.h> # include "internal.h" +# include "virbitmap.h" char * virProcessTranslateStatus(int status); @@ -40,5 +41,10 @@ int virProcessKill(pid_t pid, int sig); 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__ */ -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list