[chrony-dev] Re: [PATCH] sys_posix: support SCHED_FIFO and mlockall on more OSs

[ Thread Index | Date Index | More chrony.tuxfamily.org/chrony-dev Archives ]


Attached to avoid line wrap issues again.

-Stefan
From f2c8a92dea463f5203021d18cfec5edb92438d9f Mon Sep 17 00:00:00 2001
From: "Stefan R. Filipek" <srfilipek@xxxxxxxxx>
Date: Mon, 8 Apr 2019 20:41:03 -0400
Subject: [PATCH] sys_posix: support SCHED_FIFO and mlockall on more OSs

Real-time scheduling and memory locking is available on posix compliant
OSs. This patch centralizes this functionality and brings support to
FreeBSD, NetBSD, and Solaris.
---
 configure   |  31 +++++++++++----
 sys.c       |  12 ++++--
 sys_linux.c |  67 --------------------------------
 sys_posix.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 sys_posix.h |  36 +++++++++++++++++
 5 files changed, 177 insertions(+), 78 deletions(-)
 create mode 100644 sys_posix.c
 create mode 100644 sys_posix.h

diff --git a/configure b/configure
index c434127..b458ab3 100755
--- a/configure
+++ b/configure
@@ -396,7 +396,7 @@ SYSTEM=${OPERATINGSYSTEM}-${MACHINE}
 
 case $OPERATINGSYSTEM in
     Linux)
-        EXTRA_OBJECTS="sys_generic.o sys_linux.o sys_timex.o"
+        EXTRA_OBJECTS="sys_generic.o sys_linux.o sys_timex.o sys_posix.o"
         [ $try_libcap != "0" ] && try_libcap=1
         try_rtc=1
         [ $try_seccomp != "0" ] && try_seccomp=1
@@ -405,14 +405,18 @@ case $OPERATINGSYSTEM in
         try_lockmem=1
         try_phc=1
         add_def LINUX
+        add_def POSIX
         echo "Configuring for " $SYSTEM
     ;;
     FreeBSD)
         # recvmmsg() seems to be broken on FreeBSD 11.0 and it's just
         # a wrapper around recvmsg()
         try_recvmmsg=0
-        EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
+        EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o sys_posix.o"
+        try_setsched=1
+        try_lockmem=1
         add_def FREEBSD
+        add_def POSIX
         if [ $feat_droproot = "1" ]; then
           add_def FEAT_PRIVDROP
           priv_ops="ADJUSTTIME ADJUSTTIMEX SETTIME BINDSOCKET"
@@ -420,9 +424,12 @@ case $OPERATINGSYSTEM in
         echo "Configuring for $SYSTEM"
     ;;
     NetBSD)
-        EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o"
+        EXTRA_OBJECTS="sys_generic.o sys_netbsd.o sys_timex.o sys_posix.o"
         try_clockctl=1
+        try_setsched=1
+        try_lockmem=1
         add_def NETBSD
+        add_def POSIX
         echo "Configuring for $SYSTEM"
     ;;
     Darwin)
@@ -446,10 +453,13 @@ case $OPERATINGSYSTEM in
         echo "Configuring for macOS (" $SYSTEM "macOS version" $VERSION ")"
     ;;
     SunOS)
-        EXTRA_OBJECTS="sys_generic.o sys_solaris.o sys_timex.o"
+        EXTRA_OBJECTS="sys_generic.o sys_solaris.o sys_timex.o sys_posix.o"
         EXTRA_LIBS="-lsocket -lnsl -lresolv"
         EXTRA_CLI_LIBS="-lsocket -lnsl -lresolv"
+        try_setsched=1
+        try_lockmem=1
         add_def SOLARIS
+        add_def POSIX
         # These are needed to have msg_control in struct msghdr
         add_def __EXTENSIONS__
         add_def _XOPEN_SOURCE 1
@@ -800,13 +810,20 @@ fi
 if [ $try_lockmem = "1" ] && \
   test_code \
     'mlockall()' \
-    'sys/mman.h sys/resource.h' '' '' '
-     struct rlimit rlim;
-     setrlimit(RLIMIT_MEMLOCK, &rlim);
+    'sys/mman.h' '' '' '
      mlockall(MCL_CURRENT|MCL_FUTURE);'
 then
   add_def HAVE_MLOCKALL
 fi
+if [ $try_lockmem = "1" ] && \
+  test_code \
+    'setrlimit(RLIMIT_MEMLOCK, ...)' \
+    'sys/resource.h' '' '' '
+     struct rlimit rlim;
+     setrlimit(RLIMIT_MEMLOCK, &rlim);'
+then
+  add_def HAVE_SETRLIMIT_MEMLOCK
+fi
 
 if [ $feat_forcednsretry = "1" ]
 then
diff --git a/sys.c b/sys.c
index 2c42db1..7201250 100644
--- a/sys.c
+++ b/sys.c
@@ -43,6 +43,10 @@
 #include "sys_macosx.h"
 #endif
 
+#if defined(POSIX)
+#include "sys_posix.h"
+#endif
+
 /* ================================================== */
 
 static int null_driver;
@@ -124,8 +128,8 @@ void SYS_EnableSystemCallFilter(int level)
 
 void SYS_SetScheduler(int SchedPriority)
 {
-#if defined(LINUX) && defined(HAVE_PTHREAD_SETSCHEDPARAM)
-  SYS_Linux_SetScheduler(SchedPriority);
+#if defined(POSIX) && defined(HAVE_PTHREAD_SETSCHEDPARAM)
+  SYS_Posix_SetScheduler(SchedPriority);
 #elif defined(MACOSX)
   SYS_MacOSX_SetScheduler(SchedPriority);
 #else
@@ -137,8 +141,8 @@ void SYS_SetScheduler(int SchedPriority)
 
 void SYS_LockMemory(void)
 {
-#if defined(LINUX) && defined(HAVE_MLOCKALL)
-  SYS_Linux_MemLockAll(1);
+#if defined(POSIX) && defined(HAVE_MLOCKALL)
+  SYS_Posix_MemLockAll(1);
 #else
   LOG_FATAL("memory locking not supported");
 #endif
diff --git a/sys_linux.c b/sys_linux.c
index 9e4ab3f..898dc7a 100644
--- a/sys_linux.c
+++ b/sys_linux.c
@@ -33,16 +33,6 @@
 
 #include <sys/utsname.h>
 
-#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
-#  include <pthread.h>
-#  include <sched.h>
-#endif
-
-#if defined(HAVE_MLOCKALL)
-#  include <sys/mman.h>
-#include <sys/resource.h>
-#endif
-
 #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
 #include <linux/ptp_clock.h>
 #endif
@@ -633,63 +623,6 @@ add_failed:
 
 /* ================================================== */
 
-#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
-  /* Install SCHED_FIFO real-time scheduler with specified priority */
-void SYS_Linux_SetScheduler(int SchedPriority)
-{
-  int pmax, pmin;
-  struct sched_param sched;
-
-  if (SchedPriority < 1 || SchedPriority > 99) {
-    LOG_FATAL("Bad scheduler priority: %d", SchedPriority);
-  } else {
-    sched.sched_priority = SchedPriority;
-    pmax = sched_get_priority_max(SCHED_FIFO);
-    pmin = sched_get_priority_min(SCHED_FIFO);
-    if ( SchedPriority > pmax ) {
-      sched.sched_priority = pmax;
-    }
-    else if ( SchedPriority < pmin ) {
-      sched.sched_priority = pmin;
-    }
-    if ( pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched) == -1 ) {
-      LOG(LOGS_ERR, "pthread_setschedparam() failed");
-    }
-    else {
-      DEBUG_LOG("Enabled SCHED_FIFO with priority %d",
-          sched.sched_priority);
-    }
-  }
-}
-#endif /* HAVE_PTHREAD_SETSCHEDPARAM  */
-
-#if defined(HAVE_MLOCKALL)
-/* Lock the process into RAM so that it will never be swapped out */ 
-void SYS_Linux_MemLockAll(int LockAll)
-{
-  struct rlimit rlim;
-  if (LockAll == 1 ) {
-    /* Make sure that we will be able to lock all the memory we need */
-    /* even after dropping privileges.  This does not actually reaerve any memory */
-    rlim.rlim_max = RLIM_INFINITY;
-    rlim.rlim_cur = RLIM_INFINITY;
-    if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
-      LOG(LOGS_ERR, "setrlimit() failed: not locking into RAM");
-    }
-    else {
-      if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
-	LOG(LOGS_ERR, "mlockall() failed");
-      }
-      else {
-	DEBUG_LOG("Successfully locked into RAM");
-      }
-    }
-  }
-}
-#endif /* HAVE_MLOCKALL */
-
-/* ================================================== */
-
 int
 SYS_Linux_CheckKernelVersion(int req_major, int req_minor)
 {
diff --git a/sys_posix.c b/sys_posix.c
new file mode 100644
index 0000000..77720c3
--- /dev/null
+++ b/sys_posix.c
@@ -0,0 +1,109 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow  1997-2003
+ * Copyright (C) John G. Hasler  2009
+ * Copyright (C) Miroslav Lichvar  2009-2012, 2014-2018
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ **********************************************************************
+
+  =======================================================================
+
+  This is the module is for POSIX compliant operating systems.
+
+  */
+
+#include "config.h"
+
+#include "sysincl.h"
+
+#include <sys/utsname.h>
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
+#  include <pthread.h>
+#  include <sched.h>
+#endif
+
+#if defined(HAVE_MLOCKALL)
+#  include <sys/mman.h>
+#  include <sys/resource.h>
+#endif
+
+#include "sys_posix.h"
+#include "conf.h"
+#include "local.h"
+#include "logging.h"
+#include "util.h"
+
+/* ================================================== */
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
+  /* Install SCHED_FIFO real-time scheduler with specified priority */
+void SYS_Posix_SetScheduler(int SchedPriority)
+{
+  int pmax, pmin;
+  struct sched_param sched;
+
+  if (SchedPriority < 1 || SchedPriority > 99) {
+    LOG_FATAL("Bad scheduler priority: %d", SchedPriority);
+  } else {
+    sched.sched_priority = SchedPriority;
+    pmax = sched_get_priority_max(SCHED_FIFO);
+    pmin = sched_get_priority_min(SCHED_FIFO);
+    if ( SchedPriority > pmax ) {
+      sched.sched_priority = pmax;
+    }
+    else if ( SchedPriority < pmin ) {
+      sched.sched_priority = pmin;
+    }
+    if ( pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched) == -1 ) {
+      LOG(LOGS_ERR, "pthread_setschedparam() failed");
+    }
+    else {
+      DEBUG_LOG("Enabled SCHED_FIFO with priority %d",
+          sched.sched_priority);
+    }
+  }
+}
+#endif /* HAVE_PTHREAD_SETSCHEDPARAM  */
+
+/* ================================================== */
+
+#if defined(HAVE_MLOCKALL)
+/* Lock the process into RAM so that it will never be swapped out */
+void SYS_Posix_MemLockAll(int LockAll)
+{
+  if (LockAll == 1 ) {
+#if defined(HAVE_SETRLIMIT_MEMLOCK)
+    // Try to reserve as much as we can
+    struct rlimit rlim;
+    rlim.rlim_max = RLIM_INFINITY;
+    rlim.rlim_cur = RLIM_INFINITY;
+    if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
+      LOG(LOGS_ERR, "setrlimit() failed");
+    }
+#endif
+    if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
+      LOG(LOGS_ERR, "mlockall() failed");
+    }
+    else {
+      DEBUG_LOG("Successfully locked into RAM");
+    }
+  }
+}
+#endif /* HAVE_MLOCKALL */
+
diff --git a/sys_posix.h b/sys_posix.h
new file mode 100644
index 0000000..2138c16
--- /dev/null
+++ b/sys_posix.h
@@ -0,0 +1,36 @@
+/*
+  chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow  1997-2003
+ * Copyright (C) John G. Hasler  2009
+ * Copyright (C) Miroslav Lichvar  2009-2012, 2014-2018
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ **********************************************************************
+
+  =======================================================================
+
+  The header file for shared Posix functionality
+  */
+
+#ifndef GOT_SYS_POSIX_H
+#define GOT_SYS_POSIX_H
+
+extern void SYS_Posix_MemLockAll(int LockAll);
+
+extern void SYS_Posix_SetScheduler(int SchedPriority);
+
+#endif  /* GOT_SYS_POSIX_H */
-- 
2.21.0



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/