]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Add virProcessSetScheduler() function for scheduler settings
authorMartin Kletzander <mkletzan@redhat.com>
Thu, 8 Jan 2015 14:36:54 +0000 (15:36 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Wed, 11 Feb 2015 16:30:06 +0000 (17:30 +0100)
This function uses sched_setscheduler() function so it works with
processes and threads as well (even threads not created by us, which is
what we'll need in the future).

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
configure.ac
src/libvirt_private.syms
src/util/virprocess.c
src/util/virprocess.h

index 99a22834347ee52290c05b41fce31d7f8b207638..b3e99e780ce90723454020e56b9ff82715996174 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 
-dnl Copyright (C) 2005-2014 Red Hat, Inc.
+dnl Copyright (C) 2005-2015 Red Hat, Inc.
 dnl
 dnl This library is free software; you can redistribute it and/or
 dnl modify it under the terms of the GNU Lesser General Public
@@ -275,7 +275,7 @@ dnl and various less common threadsafe functions
 AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \
   getmntent_r getpwuid_r getuid kill mmap newlocale posix_fallocate \
   posix_memalign prlimit regexec sched_getaffinity setgroups setns \
-  setrlimit symlink sysctlbyname getifaddrs])
+  setrlimit symlink sysctlbyname getifaddrs sched_setscheduler])
 
 dnl Availability of pthread functions. Because of $LIB_PTHREAD, we
 dnl cannot use AC_CHECK_FUNCS_ONCE. LIB_PTHREAD and LIBMULTITHREAD
index 3b4ff41ed84a823dd419578e51b7e3a8405d31d4..bff9a0bf38a79b6fac7d4dfb83a2645a9524319a 100644 (file)
@@ -1916,11 +1916,14 @@ virProcessGetStartTime;
 virProcessKill;
 virProcessKillPainfully;
 virProcessRunInMountNamespace;
+virProcessSchedPolicyTypeFromString;
+virProcessSchedPolicyTypeToString;
 virProcessSetAffinity;
 virProcessSetMaxFiles;
 virProcessSetMaxMemLock;
 virProcessSetMaxProcesses;
 virProcessSetNamespaces;
+virProcessSetScheduler;
 virProcessTranslateStatus;
 virProcessWait;
 
index d0a1500cf2dfca7c3258a6e2bdfa068f84138d36..b3e5435c0ed0061ef891a6711a146c9926cea3b9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * virprocess.c: interaction with processes
  *
- * Copyright (C) 2010-2014 Red Hat, Inc.
+ * Copyright (C) 2010-2015 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
@@ -32,7 +32,9 @@
 # include <sys/time.h>
 # include <sys/resource.h>
 #endif
-#include <sched.h>
+#if HAVE_SCHED_SETSCHEDULER
+# include <sched.h>
+#endif
 
 #if defined(__FreeBSD__) || HAVE_BSD_CPU_AFFINITY
 # include <sys/param.h>
@@ -104,6 +106,13 @@ static inline int setns(int fd ATTRIBUTE_UNUSED, int nstype ATTRIBUTE_UNUSED)
 }
 #endif
 
+VIR_ENUM_IMPL(virProcessSchedPolicy, VIR_PROC_POLICY_LAST,
+              "none",
+              "batch",
+              "idle",
+              "fifo",
+              "rr");
+
 /**
  * virProcessTranslateStatus:
  * @status: child exit status to translate
@@ -1052,3 +1061,99 @@ virProcessExitWithStatus(int status)
     }
     exit(value);
 }
+
+#if HAVE_SCHED_SETSCHEDULER
+
+static int
+virProcessSchedTranslatePolicy(virProcessSchedPolicy policy)
+{
+    switch (policy) {
+    case VIR_PROC_POLICY_NONE:
+        return SCHED_OTHER;
+
+    case VIR_PROC_POLICY_BATCH:
+        return SCHED_BATCH;
+
+    case VIR_PROC_POLICY_IDLE:
+        return SCHED_IDLE;
+
+    case VIR_PROC_POLICY_FIFO:
+        return SCHED_FIFO;
+
+    case VIR_PROC_POLICY_RR:
+        return SCHED_RR;
+
+    case VIR_PROC_POLICY_LAST:
+        /* nada */
+        break;
+    }
+
+    return -1;
+}
+
+int
+virProcessSetScheduler(pid_t pid, virProcessSchedPolicy policy, int priority)
+{
+    struct sched_param param = {0};
+    int pol = virProcessSchedTranslatePolicy(policy);
+
+    VIR_DEBUG("pid=%d, policy=%d, priority=%u", pid, policy, priority);
+
+    if (!policy)
+        return 0;
+
+    if (pol == SCHED_FIFO || pol == SCHED_RR) {
+        int min = 0;
+        int max = 0;
+
+        if ((min = sched_get_priority_min(pol)) < 0) {
+            virReportSystemError(errno, "%s",
+                                 _("Cannot get minimum scheduler "
+                                   "priority value"));
+            return -1;
+        }
+
+        if ((max = sched_get_priority_max(pol)) < 0) {
+            virReportSystemError(errno, "%s",
+                                 _("Cannot get maximum scheduler "
+                                   "priority value"));
+            return -1;
+        }
+
+        if (priority < min || priority > max) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Scheduler priority %d out of range [%d, %d]"),
+                           priority, min, max);
+            return -1;
+        }
+
+        param.sched_priority = priority;
+    }
+
+    if (sched_setscheduler(pid, pol, &param) < 0) {
+        virReportSystemError(errno,
+                             _("Cannot set scheduler parameters for pid %d"),
+                             pid);
+        return -1;
+    }
+
+    return 0;
+}
+
+#else /* ! HAVE_SCHED_SETSCHEDULER */
+
+int
+virProcessSetScheduler(pid_t pid ATTRIBUTE_UNUSED,
+                       int policy,
+                       int priority ATTRIBUTE_UNUSED)
+{
+    if (!policy)
+        return 0;
+
+    virReportSystemError(ENOSYS, "%s",
+                         _("Process CPU scheduling is not supported "
+                           "on this platform"));
+    return -1;
+}
+
+#endif /* !HAVE_SCHED_SETSCHEDULER */
index bcaede58a9797ae858045e2768e8d8dfc2665860..c812882980b7d1df444bfa233c470b5703700885 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * virprocess.h: interaction with processes
  *
- * Copyright (C) 2010-2014 Red Hat, Inc.
+ * Copyright (C) 2010-2015 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
 
 # include "internal.h"
 # include "virbitmap.h"
+# include "virutil.h"
+
+typedef enum {
+    VIR_PROC_POLICY_NONE = 0,
+    VIR_PROC_POLICY_BATCH,
+    VIR_PROC_POLICY_IDLE,
+    VIR_PROC_POLICY_FIFO,
+    VIR_PROC_POLICY_RR,
+
+    VIR_PROC_POLICY_LAST
+} virProcessSchedPolicy;
+
+VIR_ENUM_DECL(virProcessSchedPolicy);
 
 char *
 virProcessTranslateStatus(int status);
@@ -73,4 +86,9 @@ typedef int (*virProcessNamespaceCallback)(pid_t pid, void *opaque);
 int virProcessRunInMountNamespace(pid_t pid,
                                   virProcessNamespaceCallback cb,
                                   void *opaque);
+
+int virProcessSetScheduler(pid_t pid,
+                           virProcessSchedPolicy policy,
+                           int priority);
+
 #endif /* __VIR_PROCESS_H__ */