VERSION: Disable GIT_SNAPSHOT for the Samba 4.18.0rc1 release.
[Samba.git] / ctdb / common / system.c
blob05a95647233c4c5461ccf0f9feb1926605997e6c
1 /*
2 common system utilities
4 Copyright (C) Amitay Isaacs 2014
5 Copyright (C) Martin Schwenke 2014
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "replace.h"
22 #include "system/filesys.h"
23 #include "system/shmem.h"
24 #include "system/network.h"
26 #include <talloc.h>
27 #include <libgen.h>
29 #include "lib/util/debug.h"
31 #include "protocol/protocol.h"
33 #include "common/logging.h"
34 #include "common/system.h"
36 #ifdef HAVE_SCHED_H
37 #include <sched.h>
38 #endif
40 #ifdef HAVE_PROCINFO_H
41 #include <procinfo.h>
42 #endif
45 if possible, make this task real time
47 bool set_scheduler(void)
49 #ifdef _AIX_
50 #ifdef HAVE_THREAD_SETSCHED
51 struct thrdentry64 te;
52 tid64_t ti;
54 ti = 0ULL;
55 if (getthrds64(getpid(), &te, sizeof(te), &ti, 1) != 1) {
56 DEBUG(DEBUG_ERR, ("Unable to get thread information\n"));
57 return false;
60 if (thread_setsched(te.ti_tid, 0, SCHED_RR) == -1) {
61 DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_RR (%s)\n",
62 strerror(errno)));
63 return false;
64 } else {
65 return true;
67 #endif
68 #else /* no AIX */
69 #ifdef HAVE_SCHED_SETSCHEDULER
70 struct sched_param p;
72 p.sched_priority = 1;
74 if (sched_setscheduler(0, SCHED_FIFO, &p) == -1) {
75 DEBUG(DEBUG_CRIT,("Unable to set scheduler to SCHED_FIFO (%s)\n",
76 strerror(errno)));
77 return false;
78 } else {
79 return true;
81 #endif
82 #endif
83 DEBUG(DEBUG_CRIT,("No way to set real-time priority.\n"));
84 return false;
88 reset scheduler from real-time to normal scheduling
90 void reset_scheduler(void)
92 #ifdef _AIX_
93 #ifdef HAVE_THREAD_SETSCHED
94 struct thrdentry64 te;
95 tid64_t ti;
97 ti = 0ULL;
98 if (getthrds64(getpid(), &te, sizeof(te), &ti, 1) != 1) {
99 DEBUG(DEBUG_ERR, ("Unable to get thread information\n"));
101 if (thread_setsched(te.ti_tid, 0, SCHED_OTHER) == -1) {
102 DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_OTHER\n"));
104 #endif
105 #else /* no AIX */
106 #ifdef HAVE_SCHED_SETSCHEDULER
107 struct sched_param p;
109 p.sched_priority = 0;
110 if (sched_setscheduler(0, SCHED_OTHER, &p) == -1) {
111 DEBUG(DEBUG_ERR, ("Unable to set scheduler to SCHED_OTHER\n"));
113 #endif
114 #endif
117 /* we don't lock future pages here; it would increase the chance that
118 * we'd fail to mmap later on. */
119 void lockdown_memory(bool valgrinding)
121 #if defined(HAVE_MLOCKALL) && !defined(_AIX_)
122 /* Extra stack, please! */
123 char dummy[10000];
124 memset(dummy, 0, sizeof(dummy));
126 if (valgrinding) {
127 return;
130 /* Ignore when running in local daemons mode */
131 if (getuid() != 0) {
132 return;
135 /* Avoid compiler optimizing out dummy. */
136 mlock(dummy, sizeof(dummy));
137 if (mlockall(MCL_CURRENT) != 0) {
138 DEBUG(DEBUG_WARNING,("Failed to lockdown memory: %s'\n",
139 strerror(errno)));
141 #endif
144 void ctdb_wait_for_process_to_exit(pid_t pid)
146 while (kill(pid, 0) == 0 || errno != ESRCH) {
147 sleep(5);
151 #ifdef HAVE_IF_NAMEINDEX
153 bool ctdb_sys_check_iface_exists(const char *iface)
155 struct if_nameindex *ifnis, *ifni;
156 bool found = false;
158 ifnis = if_nameindex();
159 if (ifnis == NULL) {
160 DBG_ERR("Failed to retrieve interface list\n");
161 return false;
164 for (ifni = ifnis;
165 ifni->if_index != 0 || ifni->if_name != NULL;
166 ifni++) {
167 int cmp = strcmp(iface, ifni->if_name);
168 if (cmp == 0) {
169 found = true;
170 goto done;
174 done:
175 if_freenameindex(ifnis);
177 return found;
180 #else /* HAVE_IF_NAMEINDEX */
182 bool ctdb_sys_check_iface_exists(const char *iface)
184 /* Not implemented: Interface always considered present */
185 return true;
188 #endif /* HAVE_IF_NAMEINDEX */
190 #ifdef HAVE_PEERCRED
192 int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
194 struct ucred cr;
195 socklen_t crl = sizeof(struct ucred);
196 int ret;
198 ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crl);
199 if (ret == 0) {
200 *peer_pid = cr.pid;
201 } else {
202 *peer_pid = -1;
204 return ret;
207 #else /* HAVE_PEERCRED */
209 #ifdef _AIX_
211 int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
213 struct peercred_struct cr;
214 socklen_t crl = sizeof(struct peercred_struct);
215 int ret;
217 ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl);
218 if (ret == 0) {
219 *peer_pid = cr.pid;
220 } else {
221 *peer_pid = -1;
223 return ret;
226 #else /* _AIX_ */
228 int ctdb_get_peer_pid(const int fd, pid_t *peer_pid)
230 /* Not implemented */
231 *peer_pid = -1;
232 return ENOSYS;
235 #endif /* _AIX_ */
237 #endif /* HAVE_PEERCRED */