close(ctdb->daemon.sd);
ctdb->daemon.sd = -1;
+ /* the client does not need to be realtime */
+ if (ctdb->do_setsched) {
+ ctdb_restore_scheduler(ctdb);
+ }
+
/* initialise ctdb */
ret = ctdb_socket_connect(ctdb);
if (ret != 0) {
return r;
}
+
+#if HAVE_SCHED_H
+#include <sched.h>
+#endif
+
/*
- if possible, make this task very high priority
+ if possible, make this task real time
*/
-void ctdb_high_priority(struct ctdb_context *ctdb)
+void ctdb_set_scheduler(struct ctdb_context *ctdb)
{
- errno = 0;
- if (nice(-20) == -1 && errno != 0) {
- DEBUG(DEBUG_WARNING,("Unable to renice self: %s\n",
- strerror(errno)));
+#if HAVE_SCHED_SETSCHEDULER
+ struct sched_param p;
+ if (ctdb->saved_scheduler_param == NULL) {
+ ctdb->saved_scheduler_param = talloc_size(ctdb, sizeof(p));
+ }
+
+ if (sched_getparam(0, (struct sched_param *)ctdb->saved_scheduler_param) == -1) {
+ DEBUG(DEBUG_ERR,("Unable to get old scheduler params\n"));
+ return;
+ }
+
+ p = *(struct sched_param *)ctdb->saved_scheduler_param;
+ p.sched_priority = 1;
+
+ if (sched_setscheduler(0, SCHED_FIFO, &p) == -1) {
+ DEBUG(DEBUG_CRIT,("Unable to set scheduler to SCHED_FIFO (%s)\n",
+ strerror(errno)));
} else {
- DEBUG(DEBUG_NOTICE,("Scheduler says I'm nice: %i\n",
- getpriority(PRIO_PROCESS, getpid())));
+ DEBUG(DEBUG_NOTICE,("Set scheduler to SCHED_FIFO\n"));
+ }
+#endif
+}
+
+/*
+ restore previous scheduler parameters
+ */
+void ctdb_restore_scheduler(struct ctdb_context *ctdb)
+{
+#if HAVE_SCHED_SETSCHEDULER
+ if (ctdb->saved_scheduler_param == NULL) {
+ ctdb_fatal(ctdb, "No saved scheduler parameters\n");
}
+ if (sched_setscheduler(0, SCHED_OTHER, (struct sched_param *)ctdb->saved_scheduler_param) == -1) {
+ ctdb_fatal(ctdb, "Unable to restore old scheduler parameters\n");
+ }
+#endif
}
/*
uint32_t recovery_master;
struct ctdb_call_state *pending_calls;
struct ctdb_client_ip *client_ip_list;
- struct trbt_tree *server_ids;
+ struct trbt_tree *server_ids;
+ bool do_setsched;
+ void *saved_scheduler_param;
const char *event_script_dir;
const char *notification_script;
const char *default_public_interface;
void ctdb_node_dead(struct ctdb_node *node);
void ctdb_node_connected(struct ctdb_node *node);
bool ctdb_blocking_freeze(struct ctdb_context *ctdb);
-void ctdb_high_priority(struct ctdb_context *ctdb);
-void ctdb_reduce_priority(struct ctdb_context *ctdb);
+void ctdb_set_scheduler(struct ctdb_context *ctdb);
+void ctdb_restore_scheduler(struct ctdb_context *ctdb);
int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
struct ctdb_req_control *c,
TDB_DATA indata,
DEBUG(DEBUG_ERR, ("Starting CTDBD as pid : %u\n", ctdbd_pid));
- ctdb_high_priority(ctdb);
+ if (ctdb->do_setsched) {
+ /* try to set us up as realtime */
+ ctdb_set_scheduler(ctdb);
+ }
/* ensure the socket is deleted on exit of the daemon */
domain_socket_name = talloc_strdup(talloc_autofree_context(), ctdb->daemon.name);
{ "dbdir-persistent", 0, POPT_ARG_STRING, &options.db_dir_persistent, 0, "directory for persistent tdb files", NULL },
{ "dbdir-state", 0, POPT_ARG_STRING, &options.db_dir_state, 0, "directory for internal state tdb files", NULL },
{ "reclock", 0, POPT_ARG_STRING, &options.recovery_lock_file, 0, "location of recovery lock file", "filename" },
- { "valgrinding", 0, POPT_ARG_NONE, &options.valgrinding, 0, "make valgrind more effective", NULL },
+ { "valgrinding", 0, POPT_ARG_NONE, &options.valgrinding, 0, "disable setscheduler SCHED_FIFO call, use mmap for tdbs", NULL },
{ "syslog", 0, POPT_ARG_NONE, &options.use_syslog, 0, "log messages to syslog", NULL },
{ "start-as-disabled", 0, POPT_ARG_NONE, &options.start_as_disabled, 0, "Node starts in disabled state", NULL },
{ "start-as-stopped", 0, POPT_ARG_NONE, &options.start_as_stopped, 0, "Node starts in stopped state", NULL },
}
ctdb->valgrinding = options.valgrinding;
+ ctdb->do_setsched = !ctdb->valgrinding;
if (options.max_persistent_check_errors < 0) {
ctdb->max_persistent_check_errors = 0xFFFFFFFFFFFFFFFFLL;