/* common system utilities Copyright (C) Amitay Isaacs 2014 Copyright (C) Martin Schwenke 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 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, see . */ #include "replace.h" #include "system/filesys.h" #include "system/shmem.h" #include "system/network.h" #include #include #include "lib/util/debug.h" #include "protocol/protocol.h" #include "common/logging.h" #include "common/system.h" #ifdef HAVE_SCHED_H #include #endif #ifdef HAVE_PROCINFO_H #include #endif /* if possible, make this task real time */ bool set_scheduler(void) { #ifdef _AIX_ #ifdef HAVE_THREAD_SETSCHED struct thrdentry64 te; tid64_t ti; ti = 0ULL; if (getthrds64(getpid(), &te, sizeof(te), &ti, 1) != 1) { DEBUG(DEBUG_ERR, ("Unable to get thread information\n")); return false; } if (thread_setsched(te.ti_tid, 0, SCHED_RR) == -1) { DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_RR (%s)\n", strerror(errno))); return false; } else { return true; } #endif #else /* no AIX */ #ifdef HAVE_SCHED_SETSCHEDULER struct sched_param p; 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))); return false; } else { return true; } #endif #endif DEBUG(DEBUG_CRIT,("No way to set real-time priority.\n")); return false; } /* reset scheduler from real-time to normal scheduling */ void reset_scheduler(void) { #ifdef _AIX_ #ifdef HAVE_THREAD_SETSCHED struct thrdentry64 te; tid64_t ti; ti = 0ULL; if (getthrds64(getpid(), &te, sizeof(te), &ti, 1) != 1) { DEBUG(DEBUG_ERR, ("Unable to get thread information\n")); } if (thread_setsched(te.ti_tid, 0, SCHED_OTHER) == -1) { DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_OTHER\n")); } #endif #else /* no AIX */ #ifdef HAVE_SCHED_SETSCHEDULER struct sched_param p; p.sched_priority = 0; if (sched_setscheduler(0, SCHED_OTHER, &p) == -1) { DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_OTHER\n")); } #endif #endif } /* we don't lock future pages here; it would increase the chance that * we'd fail to mmap later on. */ void lockdown_memory(bool valgrinding) { #if defined(HAVE_MLOCKALL) && !defined(_AIX_) /* Extra stack, please! */ char dummy[10000]; memset(dummy, 0, sizeof(dummy)); if (valgrinding) { return; } /* Ignore when running in local daemons mode */ if (getuid() != 0) { return; } /* Avoid compiler optimizing out dummy. */ mlock(dummy, sizeof(dummy)); if (mlockall(MCL_CURRENT) != 0) { DEBUG(DEBUG_WARNING,("Failed to lockdown memory: %s'\n", strerror(errno))); } #endif } void ctdb_wait_for_process_to_exit(pid_t pid) { while (kill(pid, 0) == 0 || errno != ESRCH) { sleep(5); } } #ifdef HAVE_IF_NAMEINDEX bool ctdb_sys_check_iface_exists(const char *iface) { struct if_nameindex *ifnis, *ifni; bool found = false; ifnis = if_nameindex(); if (ifnis == NULL) { DBG_ERR("Failed to retrieve interface list\n"); return false; } for (ifni = ifnis; ifni->if_index != 0 || ifni->if_name != NULL; ifni++) { int cmp = strcmp(iface, ifni->if_name); if (cmp == 0) { found = true; goto done; } } done: if_freenameindex(ifnis); return found; } #else /* HAVE_IF_NAMEINDEX */ bool ctdb_sys_check_iface_exists(const char *iface) { /* Not implemented: Interface always considered present */ return true; } #endif /* HAVE_IF_NAMEINDEX */ #ifdef HAVE_PEERCRED int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) { struct ucred cr; socklen_t crl = sizeof(struct ucred); int ret; ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crl); if (ret == 0) { *peer_pid = cr.pid; } else { *peer_pid = -1; } return ret; } #else /* HAVE_PEERCRED */ #ifdef _AIX_ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) { struct peercred_struct cr; socklen_t crl = sizeof(struct peercred_struct); int ret; ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl); if (ret == 0) { *peer_pid = cr.pid; } else { *peer_pid = -1; } return ret; } #else /* _AIX_ */ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) { /* Not implemented */ *peer_pid = -1; return ENOSYS; } #endif /* _AIX_ */ #endif /* HAVE_PEERCRED */