Blob Blame History Raw
From a008448efb2b1d45c432867caf08f0bcf2b4b9b0 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Fri, 7 Jul 2017 17:49:46 +0200
Subject: [PATCH] main: Add option to set priority

Option -P takes numeric value with same meaning
as nice or values min / max, meaning maximal / minimal priority (so
minimal / maximal nice value).

Scheduler / priority setting is moved in code so it is now executed
after logsys is configured so errors are logged.

Setting maximal priority is also used as fallback when realtime
scheduling is requested and sched_setscheduler fails.

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
---
 exec/main.c    |   71 ++++++++++++++++++++++++++++++++++++++++++++------------
 man/corosync.8 |   22 +++++++++++++----
 2 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/exec/main.c b/exec/main.c
index 0d381c2..60c01a4 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -862,8 +862,10 @@ static void timer_function_scheduler_timeout (void *data)
 }
 
 
-static void corosync_setscheduler (void)
+static int corosync_set_rr_scheduler (void)
 {
+	int ret_val = 0;
+
 #if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX) && defined(HAVE_SCHED_SETSCHEDULER)
 	int res;
 
@@ -880,6 +882,7 @@ static void corosync_setscheduler (void)
 #ifdef HAVE_QB_LOG_THREAD_PRIORITY_SET
 			qb_log_thread_priority_set (SCHED_OTHER, 0);
 #endif
+			ret_val = -1;
 		} else {
 
 			/*
@@ -901,11 +904,15 @@ static void corosync_setscheduler (void)
 		LOGSYS_PERROR (errno, LOGSYS_LEVEL_WARNING,
 			"Could not get maximum scheduler priority");
 		sched_priority = 0;
+		ret_val = -1;
 	}
 #else
 	log_printf(LOGSYS_LEVEL_WARNING,
 		"The Platform is missing process priority setting features.  Leaving at default.");
+	ret_val = -1;
 #endif
+
+	return (ret_val);
 }
 
 
@@ -1132,29 +1139,48 @@ int main (int argc, char **argv, char **envp)
 	const char *error_string;
 	struct totem_config totem_config;
 	int res, ch;
-	int background, setprio, testonly;
+	int background, sched_rr, prio, testonly;
 	struct stat stat_out;
 	enum e_corosync_done flock_err;
 	uint64_t totem_config_warnings;
 	struct scheduler_pause_timeout_data scheduler_pause_timeout_data;
+	long int tmpli;
+	char *ep;
 
 	/* default configuration
 	 */
 	background = 1;
-	setprio = 1;
+	sched_rr = 1;
+	prio = 0;
 	testonly = 0;
 
-	while ((ch = getopt (argc, argv, "fprtv")) != EOF) {
+	while ((ch = getopt (argc, argv, "fP:prtv")) != EOF) {
 
 		switch (ch) {
 			case 'f':
 				background = 0;
 				break;
 			case 'p':
-				setprio = 0;
+				sched_rr = 0;
+				break;
+			case 'P':
+				if (strcmp(optarg, "max") == 0) {
+					prio = INT_MIN;
+				} else if (strcmp(optarg, "min") == 0) {
+					prio = INT_MAX;
+				} else {
+					tmpli = strtol(optarg, &ep, 10);
+					if (errno != 0 || *ep != '\0' || tmpli > INT_MAX || tmpli < INT_MIN) {
+						fprintf(stderr, "Priority value %s is invalid", optarg);
+						logsys_system_fini();
+						return EXIT_FAILURE;
+					}
+
+					prio = tmpli;
+				}
 				break;
 			case 'r':
-				setprio = 1;
+				sched_rr = 1;
 				break;
 			case 't':
 				testonly = 1;
@@ -1170,8 +1196,9 @@ int main (int argc, char **argv, char **envp)
 				fprintf(stderr, \
 					"usage:\n"\
 					"        -f     : Start application in foreground.\n"\
-					"        -p     : Do not set process priority.\n"\
+					"        -p     : Do not set realtime scheduling.\n"\
 					"        -r     : Set round robin realtime scheduling (default).\n"\
+					"        -P num : Set priority of process (no effect when -r is used)\n"\
 					"        -t     : Test configuration and exit.\n"\
 					"        -v     : Display version and SVN revision of Corosync and exit.\n");
 				logsys_system_fini();
@@ -1179,14 +1206,6 @@ int main (int argc, char **argv, char **envp)
 		}
 	}
 
-	/*
-	 * Set round robin realtime scheduling with priority 99
-	 * Lock all memory to avoid page faults which may interrupt
-	 * application healthchecking
-	 */
-	if (setprio) {
-		corosync_setscheduler ();
-	}
 
 	/*
 	 * Other signals are registered later via qb_loop_signal_add
@@ -1293,6 +1312,24 @@ int main (int argc, char **argv, char **envp)
 		corosync_exit_error (COROSYNC_DONE_EXIT);
 	}
 
+	/*
+	 * Set round robin realtime scheduling with priority 99
+	 */
+	if (sched_rr) {
+		if (corosync_set_rr_scheduler () != 0) {
+			prio = INT_MIN;
+		} else {
+			prio = 0;
+		}
+	}
+
+	if (prio != 0) {
+		if (setpriority(PRIO_PGRP, 0, prio) != 0) {
+			LOGSYS_PERROR(errno, LOGSYS_LEVEL_WARNING,
+				"Could not set priority %d", prio);
+		}
+	}
+
 	ip_version = totem_config.ip_version;
 
 	totem_config.totem_memb_ring_id_create_or_load = corosync_ring_id_create_or_load;
@@ -1319,6 +1356,10 @@ int main (int argc, char **argv, char **envp)
 		corosync_tty_detach ();
 	}
 
+	/*
+	 * Lock all memory to avoid page faults which may interrupt
+	 * application healthchecking
+	 */
 	corosync_mlockall ();
 
 	corosync_poll_handle = qb_loop_create ();
diff --git a/man/corosync.8 b/man/corosync.8
index 89ab771..dc596d1 100644
--- a/man/corosync.8
+++ b/man/corosync.8
@@ -1,5 +1,5 @@
 .\"/*
-.\" * Copyright (C) 2010 Red Hat, Inc.
+.\" * Copyright (C) 2010-2017 Red Hat, Inc.
 .\" *
 .\" * All rights reserved.
 .\" *
@@ -31,11 +31,11 @@
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
 .\" */
-.TH COROSYNC 8 2010-05-30
+.TH COROSYNC 8 2017-07-07
 .SH NAME
 corosync \- The Corosync Cluster Engine.
 .SH SYNOPSIS
-.B "corosync [\-f] [\-p] [\-r] [\-t] [\-v]"
+.B "corosync [\-f] [\-P num] [\-p] [\-r] [\-t] [\-v]"
 .SH DESCRIPTION
 .B corosync
 Corosync provides clustering infrastructure such as membership, messaging and quorum.
@@ -45,10 +45,22 @@ Corosync provides clustering infrastructure such as membership, messaging and qu
 Start application in foreground.
 .TP
 .B -p
-Do not set process priority.
+Do not set realtime scheduling.
 .TP
+.B -P
+Set priority of process. Has effect only when
 .B -r
-Set round robin realtime scheduling (default).
+is not used. Can be ether numeric value with similar meaning as
+.BR nice (1)
+or
+.B max
+/
+.B min
+meaning maximal / minimal priority (so minimal / maximal nice value).
+.TP
+.B -r
+Set round robin realtime scheduling with maximal priority (default). When setting
+of scheduler fails, fallback to set maximal priority.
 .TP
 .B -t
 Test configuration and then exit.
-- 
1.7.1