s3: libsmb: Cleanup in get_dc_list()
[Samba.git] / source3 / lib / per_thread_cwd.c
blobfcec572a759c5176025d4319d0737b5157cb39a5
1 /*
2 Unix SMB/Netbios implementation.
4 Copyright (C) Ralph Boehme 2019
5 Copyright (C) Stefan Metzmacher 2019
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 "includes.h"
22 #include "system/filesys.h"
23 #include "system/threads.h"
24 #ifdef HAVE_UNSHARE_CLONE_FS
25 #include <sched.h>
26 #endif /* HAVE_UNSHARE_CLONE_FS */
28 static bool _per_thread_cwd_checked;
29 static bool _per_thread_cwd_supported;
30 #ifdef HAVE_UNSHARE_CLONE_FS
31 static __thread bool _per_thread_cwd_disabled;
32 static __thread bool _per_thread_cwd_activated;
33 #endif /* HAVE_UNSHARE_CLONE_FS */
36 * This is the first function to be called!
37 * Typically in the main() function before
38 * any threads are created.
40 * This can be called multiple times
41 * as the result is cached the first time.
43 void per_thread_cwd_check(void)
45 if (_per_thread_cwd_checked) {
46 return;
49 #ifdef HAVE_UNSHARE_CLONE_FS
51 * While unshare(CLONE_FS) is available on
52 * Linux for ages, unshare() is also
53 * used to implement containers with various
54 * per container namespaces.
56 * It's possible that the whole unshare()
57 * is blocked in order to disallow neested
58 * containers.
60 * That's why we sadly need a runtime check
61 * for this.
64 int res;
66 res = unshare(CLONE_FS);
67 if (res == 0) {
68 _per_thread_cwd_supported = true;
73 * We're in the main thread, so we should disallow
74 * per_thread_cwd_activate() here.
76 _per_thread_cwd_disabled = true;
77 #endif /* HAVE_UNSHARE_CLONE_FS */
79 _per_thread_cwd_checked = true;
83 * In order to use per_thread_cwd_supported()
84 * per_thread_cwd_check() needs to be called first!
85 * Otherwise an assert will be triggered!
87 bool per_thread_cwd_supported(void)
89 SMB_ASSERT(_per_thread_cwd_checked);
90 return _per_thread_cwd_supported;
94 * In order to use per_thread_cwd_disable()
95 * should be called after any fork() in order
96 * to mark the main thread of the process,
97 * which should disallow per_thread_cwd_activate().
99 * This can be called without calling
100 * per_thread_cwd_check() first.
102 * And it can't be called after calling
103 * per_thread_cwd_activate()!
104 * Otherwise an assert will be triggered!
106 * This can be called multiple times
107 * as the result is cached the first time.
109 void per_thread_cwd_disable(void)
111 #ifdef HAVE_UNSHARE_CLONE_FS
112 SMB_ASSERT(!_per_thread_cwd_activated);
113 if (_per_thread_cwd_disabled) {
114 return;
116 _per_thread_cwd_disabled = true;
117 #endif /* HAVE_UNSHARE_CLONE_FS */
121 * In order to use per_thread_cwd_activate()
122 * per_thread_cwd_supported() needs to be checked first!
123 * Otherwise an assert will be triggered!
125 * This MUST only be called within helper threads!
127 * That means it can't be called after calling
128 * per_thread_cwd_disable()!
129 * Otherwise an assert will be triggered!
131 * This can be called multiple times
132 * as the result is cached the first time.
134 void per_thread_cwd_activate(void)
136 SMB_ASSERT(_per_thread_cwd_checked);
137 SMB_ASSERT(_per_thread_cwd_supported);
139 #ifdef HAVE_UNSHARE_CLONE_FS
140 if (_per_thread_cwd_activated) {
141 return;
144 SMB_ASSERT(!_per_thread_cwd_disabled);
147 int ret;
148 ret = unshare(CLONE_FS);
149 SMB_ASSERT(ret == 0);
152 _per_thread_cwd_activated = true;
153 #else /* not HAVE_UNSHARE_CLONE_FS */
154 smb_panic(__location__);
155 #endif /* not HAVE_UNSHARE_CLONE_FS */