[libvirt] [PATCH] BSD: implement virProcess{Get,Set}Affinity

Roman Bogorodskiy bogorodskiy at gmail.com
Sat Jan 25 16:11:01 UTC 2014


Implement virProcess{Get,Set}Affinity() using cpuset_getaffinity()
and cpuset_setaffinity() calls. Quick search showed that they are
only available on FreeBSD, so placed it inside existing #ifdef
blocks for FreeBSD instead of adding configure checks.
---
 src/util/virprocess.c | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 9fc3207..827143c 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -34,6 +34,7 @@
 
 #ifdef __FreeBSD__
 # include <sys/param.h>
+# include <sys/cpuset.h>
 # include <sys/sysctl.h>
 # include <sys/user.h>
 #endif
@@ -461,23 +462,49 @@ realloc:
 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"));
+    size_t i;
+    cpuset_t mask;
+    bool set = false;
+
+    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 (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
+                           sizeof(mask), &mask) != 0) {
+        virReportSystemError(errno,
+                             _("cannot set CPU affinity on process %d"), pid);
         return -1;
     }
 
     return 0;
 }
 
-int virProcessGetAffinity(pid_t pid ATTRIBUTE_UNUSED,
+int virProcessGetAffinity(pid_t pid,
                           virBitmapPtr *map,
                           int maxcpu)
 {
+    size_t i;
+    cpuset_t mask;
+
     if (!(*map = virBitmapNew(maxcpu)))
         return -1;
-    virBitmapSetAll(*map);
+
+    CPU_ZERO(&mask);
+    if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 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));
 
     return 0;
 }
-- 
1.8.4.3




More information about the libvir-list mailing list