File: | build-scan/../src/core/automount.c |
Warning: | line 678, column 24 Potential leak of memory pointed to by 'data' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <errno(*__errno_location ()).h> | |||
4 | #include <fcntl.h> | |||
5 | #include <limits.h> | |||
6 | #include <linux1/auto_dev-ioctl.h> | |||
7 | #include <linux1/auto_fs4.h> | |||
8 | #include <sys/epoll.h> | |||
9 | #include <sys/mount.h> | |||
10 | #include <sys/stat.h> | |||
11 | #include <unistd.h> | |||
12 | ||||
13 | #include "alloc-util.h" | |||
14 | #include "async.h" | |||
15 | #include "automount.h" | |||
16 | #include "bus-error.h" | |||
17 | #include "bus-util.h" | |||
18 | #include "dbus-automount.h" | |||
19 | #include "fd-util.h" | |||
20 | #include "format-util.h" | |||
21 | #include "io-util.h" | |||
22 | #include "label.h" | |||
23 | #include "mkdir.h" | |||
24 | #include "mount-util.h" | |||
25 | #include "mount.h" | |||
26 | #include "parse-util.h" | |||
27 | #include "path-util.h" | |||
28 | #include "process-util.h" | |||
29 | #include "special.h" | |||
30 | #include "stdio-util.h" | |||
31 | #include "string-table.h" | |||
32 | #include "string-util.h" | |||
33 | #include "unit-name.h" | |||
34 | #include "unit.h" | |||
35 | ||||
36 | static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = { | |||
37 | [AUTOMOUNT_DEAD] = UNIT_INACTIVE, | |||
38 | [AUTOMOUNT_WAITING] = UNIT_ACTIVE, | |||
39 | [AUTOMOUNT_RUNNING] = UNIT_ACTIVE, | |||
40 | [AUTOMOUNT_FAILED] = UNIT_FAILED | |||
41 | }; | |||
42 | ||||
43 | struct expire_data { | |||
44 | int dev_autofs_fd; | |||
45 | int ioctl_fd; | |||
46 | }; | |||
47 | ||||
48 | static inline void expire_data_free(struct expire_data *data) { | |||
49 | if (!data) | |||
50 | return; | |||
51 | ||||
52 | safe_close(data->dev_autofs_fd); | |||
53 | safe_close(data->ioctl_fd); | |||
54 | free(data); | |||
55 | } | |||
56 | ||||
57 | DEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data*, expire_data_free)static inline void expire_data_freep(struct expire_data* *p) { if (*p) expire_data_free(*p); }; | |||
58 | ||||
59 | static int open_dev_autofs(Manager *m); | |||
60 | static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata); | |||
61 | static int automount_start_expire(Automount *a); | |||
62 | static void automount_stop_expire(Automount *a); | |||
63 | static int automount_send_ready(Automount *a, Set *tokens, int status); | |||
64 | ||||
65 | static void automount_init(Unit *u) { | |||
66 | Automount *a = AUTOMOUNT(u); | |||
67 | ||||
68 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/automount.c", 68, __PRETTY_FUNCTION__ ); } while (0); | |||
69 | assert(u->load_state == UNIT_STUB)do { if ((__builtin_expect(!!(!(u->load_state == UNIT_STUB )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("u->load_state == UNIT_STUB" ), "../src/core/automount.c", 69, __PRETTY_FUNCTION__); } while (0); | |||
70 | ||||
71 | a->pipe_fd = -1; | |||
72 | a->directory_mode = 0755; | |||
73 | UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->ignore_on_isolate = true1; | |||
74 | } | |||
75 | ||||
76 | static void unmount_autofs(Automount *a) { | |||
77 | int r; | |||
78 | ||||
79 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 79, __PRETTY_FUNCTION__ ); } while (0); | |||
80 | ||||
81 | if (a->pipe_fd < 0) | |||
82 | return; | |||
83 | ||||
84 | a->pipe_event_source = sd_event_source_unref(a->pipe_event_source); | |||
85 | a->pipe_fd = safe_close(a->pipe_fd); | |||
86 | ||||
87 | /* If we reload/reexecute things we keep the mount point around */ | |||
88 | if (!IN_SET(UNIT(a)->manager->exit_code, MANAGER_RELOAD, MANAGER_REEXECUTE)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MANAGER_RELOAD, MANAGER_REEXECUTE})/sizeof (int)]; switch(({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? & (_u_)->meta : ((void*)0); _w_; })->manager->exit_code ) { case MANAGER_RELOAD: case MANAGER_REEXECUTE: _found = 1; break ; default: break; } _found; })) { | |||
89 | ||||
90 | automount_send_ready(a, a->tokens, -EHOSTDOWN112); | |||
91 | automount_send_ready(a, a->expire_tokens, -EHOSTDOWN112); | |||
92 | ||||
93 | if (a->where) { | |||
94 | r = repeat_unmount(a->where, MNT_DETACHMNT_DETACH); | |||
95 | if (r < 0) | |||
96 | log_error_errno(r, "Failed to unmount: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/automount.c", 96, __func__, "Failed to unmount: %m" ) : -abs(_e); }); | |||
97 | } | |||
98 | } | |||
99 | } | |||
100 | ||||
101 | static void automount_done(Unit *u) { | |||
102 | Automount *a = AUTOMOUNT(u); | |||
103 | ||||
104 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 104, __PRETTY_FUNCTION__ ); } while (0); | |||
105 | ||||
106 | unmount_autofs(a); | |||
107 | ||||
108 | a->where = mfree(a->where); | |||
109 | ||||
110 | a->tokens = set_free(a->tokens); | |||
111 | a->expire_tokens = set_free(a->expire_tokens); | |||
112 | ||||
113 | a->expire_event_source = sd_event_source_unref(a->expire_event_source); | |||
114 | } | |||
115 | ||||
116 | static int automount_add_trigger_dependencies(Automount *a) { | |||
117 | Unit *x; | |||
118 | int r; | |||
119 | ||||
120 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 120, __PRETTY_FUNCTION__ ); } while (0); | |||
121 | ||||
122 | r = unit_load_related_unit(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), ".mount", &x); | |||
123 | if (r < 0) | |||
124 | return r; | |||
125 | ||||
126 | return unit_add_two_dependencies(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), UNIT_BEFORE, UNIT_TRIGGERS, x, true1, UNIT_DEPENDENCY_IMPLICIT); | |||
127 | } | |||
128 | ||||
129 | static int automount_add_mount_dependencies(Automount *a) { | |||
130 | _cleanup_free___attribute__((cleanup(freep))) char *parent = NULL((void*)0); | |||
131 | ||||
132 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 132, __PRETTY_FUNCTION__ ); } while (0); | |||
133 | ||||
134 | parent = dirname_malloc(a->where); | |||
135 | if (!parent) | |||
136 | return -ENOMEM12; | |||
137 | ||||
138 | return unit_require_mounts_for(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), parent, UNIT_DEPENDENCY_IMPLICIT); | |||
139 | } | |||
140 | ||||
141 | static int automount_add_default_dependencies(Automount *a) { | |||
142 | int r; | |||
143 | ||||
144 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 144, __PRETTY_FUNCTION__ ); } while (0); | |||
145 | ||||
146 | if (!UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->default_dependencies) | |||
147 | return 0; | |||
148 | ||||
149 | if (!MANAGER_IS_SYSTEM(UNIT(a)->manager)((({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager)->unit_file_scope == UNIT_FILE_SYSTEM )) | |||
150 | return 0; | |||
151 | ||||
152 | r = unit_add_two_dependencies_by_name(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET"umount.target", NULL((void*)0), true1, UNIT_DEPENDENCY_DEFAULT); | |||
153 | if (r < 0) | |||
154 | return r; | |||
155 | ||||
156 | return 0; | |||
157 | } | |||
158 | ||||
159 | static int automount_verify(Automount *a) { | |||
160 | _cleanup_free___attribute__((cleanup(freep))) char *e = NULL((void*)0); | |||
161 | int r; | |||
162 | ||||
163 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 163, __PRETTY_FUNCTION__ ); } while (0); | |||
164 | ||||
165 | if (UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->load_state != UNIT_LOADED) | |||
166 | return 0; | |||
167 | ||||
168 | if (path_equal(a->where, "/")) { | |||
169 | log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 169, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Cannot have an automount unit for the root directory. Refusing." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), 0, "../src/core/automount.c", 169, __func__, "Cannot have an automount unit for the root directory. Refusing." ); }); | |||
170 | return -ENOEXEC8; | |||
171 | } | |||
172 | ||||
173 | r = unit_name_from_path(a->where, ".automount", &e); | |||
174 | if (r < 0) | |||
175 | return log_unit_error_errno(UNIT(a), r, "Failed to generate unit name from path: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 175, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to generate unit name from path: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), r, "../src/core/automount.c", 175, __func__, "Failed to generate unit name from path: %m" ); }); | |||
176 | ||||
177 | if (!unit_has_name(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), e)) { | |||
178 | log_unit_error(UNIT(a), "Where= setting doesn't match unit name. Refusing.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 178, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Where= setting doesn't match unit name. Refusing." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), 0, "../src/core/automount.c", 178, __func__, "Where= setting doesn't match unit name. Refusing." ); }); | |||
179 | return -ENOEXEC8; | |||
180 | } | |||
181 | ||||
182 | return 0; | |||
183 | } | |||
184 | ||||
185 | static int automount_set_where(Automount *a) { | |||
186 | int r; | |||
187 | ||||
188 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 188, __PRETTY_FUNCTION__ ); } while (0); | |||
189 | ||||
190 | if (a->where) | |||
191 | return 0; | |||
192 | ||||
193 | r = unit_name_to_path(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->id, &a->where); | |||
194 | if (r < 0) | |||
195 | return r; | |||
196 | ||||
197 | path_simplify(a->where, false0); | |||
198 | return 1; | |||
199 | } | |||
200 | ||||
201 | static int automount_load(Unit *u) { | |||
202 | Automount *a = AUTOMOUNT(u); | |||
203 | int r; | |||
204 | ||||
205 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/automount.c", 205, __PRETTY_FUNCTION__ ); } while (0); | |||
206 | assert(u->load_state == UNIT_STUB)do { if ((__builtin_expect(!!(!(u->load_state == UNIT_STUB )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("u->load_state == UNIT_STUB" ), "../src/core/automount.c", 206, __PRETTY_FUNCTION__); } while (0); | |||
207 | ||||
208 | /* Load a .automount file */ | |||
209 | r = unit_load_fragment_and_dropin(u); | |||
210 | if (r < 0) | |||
211 | return r; | |||
212 | ||||
213 | if (u->load_state == UNIT_LOADED) { | |||
214 | r = automount_set_where(a); | |||
215 | if (r < 0) | |||
216 | return r; | |||
217 | ||||
218 | r = automount_add_trigger_dependencies(a); | |||
219 | if (r < 0) | |||
220 | return r; | |||
221 | ||||
222 | r = automount_add_mount_dependencies(a); | |||
223 | if (r < 0) | |||
224 | return r; | |||
225 | ||||
226 | r = automount_add_default_dependencies(a); | |||
227 | if (r < 0) | |||
228 | return r; | |||
229 | } | |||
230 | ||||
231 | return automount_verify(a); | |||
232 | } | |||
233 | ||||
234 | static void automount_set_state(Automount *a, AutomountState state) { | |||
235 | AutomountState old_state; | |||
236 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 236, __PRETTY_FUNCTION__ ); } while (0); | |||
237 | ||||
238 | old_state = a->state; | |||
239 | a->state = state; | |||
240 | ||||
241 | if (state != AUTOMOUNT_RUNNING) | |||
242 | automount_stop_expire(a); | |||
243 | ||||
244 | if (!IN_SET(state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING})/sizeof (int)]; switch(state) { case AUTOMOUNT_WAITING: case AUTOMOUNT_RUNNING : _found = 1; break; default: break; } _found; })) | |||
245 | unmount_autofs(a); | |||
246 | ||||
247 | if (state != old_state) | |||
248 | log_unit_debug(UNIT(a), "Changed %s -> %s", automount_state_to_string(old_state), automount_state_to_string(state))({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, 0, "../src/core/automount.c", 248, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Changed %s -> %s", automount_state_to_string (old_state), automount_state_to_string(state)) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 248, __func__, "Changed %s -> %s", automount_state_to_string (old_state), automount_state_to_string(state)); }); | |||
249 | ||||
250 | unit_notify(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), state_translation_table[old_state], state_translation_table[state], 0); | |||
251 | } | |||
252 | ||||
253 | static int automount_coldplug(Unit *u) { | |||
254 | Automount *a = AUTOMOUNT(u); | |||
255 | int r; | |||
256 | ||||
257 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 257, __PRETTY_FUNCTION__ ); } while (0); | |||
258 | assert(a->state == AUTOMOUNT_DEAD)do { if ((__builtin_expect(!!(!(a->state == AUTOMOUNT_DEAD )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("a->state == AUTOMOUNT_DEAD" ), "../src/core/automount.c", 258, __PRETTY_FUNCTION__); } while (0); | |||
259 | ||||
260 | if (a->deserialized_state == a->state) | |||
261 | return 0; | |||
262 | ||||
263 | if (IN_SET(a->deserialized_state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING})/sizeof (int)]; switch(a->deserialized_state) { case AUTOMOUNT_WAITING : case AUTOMOUNT_RUNNING: _found = 1; break; default: break; } _found; })) { | |||
264 | ||||
265 | r = automount_set_where(a); | |||
266 | if (r < 0) | |||
267 | return r; | |||
268 | ||||
269 | r = open_dev_autofs(u->manager); | |||
270 | if (r < 0) | |||
271 | return r; | |||
272 | ||||
273 | assert(a->pipe_fd >= 0)do { if ((__builtin_expect(!!(!(a->pipe_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a->pipe_fd >= 0"), "../src/core/automount.c" , 273, __PRETTY_FUNCTION__); } while (0); | |||
274 | ||||
275 | r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLINEPOLLIN, automount_dispatch_io, u); | |||
276 | if (r < 0) | |||
277 | return r; | |||
278 | ||||
279 | (void) sd_event_source_set_description(a->pipe_event_source, "automount-io"); | |||
280 | if (a->deserialized_state == AUTOMOUNT_RUNNING) { | |||
281 | r = automount_start_expire(a); | |||
282 | if (r < 0) | |||
283 | log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (4, r, "../src/core/automount.c", 283, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to start expiration timer, ignoring: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4 ))), r, "../src/core/automount.c", 283, __func__, "Failed to start expiration timer, ignoring: %m" ); }); | |||
284 | } | |||
285 | ||||
286 | automount_set_state(a, a->deserialized_state); | |||
287 | } | |||
288 | ||||
289 | return 0; | |||
290 | } | |||
291 | ||||
292 | static void automount_dump(Unit *u, FILE *f, const char *prefix) { | |||
293 | char time_string[FORMAT_TIMESPAN_MAX64]; | |||
294 | Automount *a = AUTOMOUNT(u); | |||
295 | ||||
296 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 296, __PRETTY_FUNCTION__ ); } while (0); | |||
297 | ||||
298 | fprintf(f, | |||
299 | "%sAutomount State: %s\n" | |||
300 | "%sResult: %s\n" | |||
301 | "%sWhere: %s\n" | |||
302 | "%sDirectoryMode: %04o\n" | |||
303 | "%sTimeoutIdleUSec: %s\n", | |||
304 | prefix, automount_state_to_string(a->state), | |||
305 | prefix, automount_result_to_string(a->result), | |||
306 | prefix, a->where, | |||
307 | prefix, a->directory_mode, | |||
308 | prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, a->timeout_idle_usec, USEC_PER_SEC((usec_t) 1000000ULL))); | |||
309 | } | |||
310 | ||||
311 | static void automount_enter_dead(Automount *a, AutomountResult f) { | |||
312 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 312, __PRETTY_FUNCTION__ ); } while (0); | |||
313 | ||||
314 | if (a->result == AUTOMOUNT_SUCCESS) | |||
315 | a->result = f; | |||
316 | ||||
317 | if (a->result == AUTOMOUNT_SUCCESS) | |||
318 | unit_log_success(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); | |||
319 | else | |||
320 | unit_log_failure(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), automount_result_to_string(a->result)); | |||
321 | ||||
322 | automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD); | |||
323 | } | |||
324 | ||||
325 | static int open_dev_autofs(Manager *m) { | |||
326 | struct autofs_dev_ioctl param; | |||
327 | ||||
328 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/automount.c", 328, __PRETTY_FUNCTION__ ); } while (0); | |||
329 | ||||
330 | if (m->dev_autofs_fd >= 0) | |||
331 | return m->dev_autofs_fd; | |||
332 | ||||
333 | (void) label_fix("/dev/autofs", 0); | |||
334 | ||||
335 | m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC02000000|O_RDONLY00); | |||
336 | if (m->dev_autofs_fd < 0) | |||
337 | return log_error_errno(errno, "Failed to open /dev/autofs: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/automount.c", 337, __func__ , "Failed to open /dev/autofs: %m") : -abs(_e); }); | |||
338 | ||||
339 | init_autofs_dev_ioctl(¶m); | |||
340 | if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_VERSION_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m) < 0) { | |||
341 | m->dev_autofs_fd = safe_close(m->dev_autofs_fd); | |||
342 | return -errno(*__errno_location ()); | |||
343 | } | |||
344 | ||||
345 | log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/automount.c", 345, __func__, "Autofs kernel version %i.%i" , param.ver_major, param.ver_minor) : -abs(_e); }); | |||
346 | ||||
347 | return m->dev_autofs_fd; | |||
348 | } | |||
349 | ||||
350 | static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) { | |||
351 | struct autofs_dev_ioctl *param; | |||
352 | size_t l; | |||
353 | ||||
354 | assert(dev_autofs_fd >= 0)do { if ((__builtin_expect(!!(!(dev_autofs_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("dev_autofs_fd >= 0"), "../src/core/automount.c" , 354, __PRETTY_FUNCTION__); } while (0); | |||
355 | assert(where)do { if ((__builtin_expect(!!(!(where)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("where"), "../src/core/automount.c", 355 , __PRETTY_FUNCTION__); } while (0); | |||
356 | ||||
357 | l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1; | |||
358 | param = alloca(l)__builtin_alloca (l); | |||
359 | ||||
360 | init_autofs_dev_ioctl(param); | |||
361 | param->size = l; | |||
362 | param->ioctlfd = -1; | |||
363 | param->openmount.devid = devid; | |||
364 | strcpy(param->path, where); | |||
365 | ||||
366 | if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_OPENMOUNT_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), param) < 0) | |||
367 | return -errno(*__errno_location ()); | |||
368 | ||||
369 | if (param->ioctlfd < 0) | |||
370 | return -EIO5; | |||
371 | ||||
372 | (void) fd_cloexec(param->ioctlfd, true1); | |||
373 | return param->ioctlfd; | |||
374 | } | |||
375 | ||||
376 | static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) { | |||
377 | uint32_t major, minor; | |||
378 | struct autofs_dev_ioctl param; | |||
379 | ||||
380 | assert(dev_autofs_fd >= 0)do { if ((__builtin_expect(!!(!(dev_autofs_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("dev_autofs_fd >= 0"), "../src/core/automount.c" , 380, __PRETTY_FUNCTION__); } while (0); | |||
381 | assert(ioctl_fd >= 0)do { if ((__builtin_expect(!!(!(ioctl_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ioctl_fd >= 0"), "../src/core/automount.c" , 381, __PRETTY_FUNCTION__); } while (0); | |||
382 | ||||
383 | init_autofs_dev_ioctl(¶m); | |||
384 | param.ioctlfd = ioctl_fd; | |||
385 | ||||
386 | if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_PROTOVER_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m) < 0) | |||
387 | return -errno(*__errno_location ()); | |||
388 | ||||
389 | major = param.protover.version; | |||
390 | ||||
391 | init_autofs_dev_ioctl(¶m); | |||
392 | param.ioctlfd = ioctl_fd; | |||
393 | ||||
394 | if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD)) << 0) | ((( (sizeof(struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m) < 0) | |||
395 | return -errno(*__errno_location ()); | |||
396 | ||||
397 | minor = param.protosubver.sub_version; | |||
398 | ||||
399 | log_debug("Autofs protocol version %i.%i", major, minor)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/automount.c", 399, __func__, "Autofs protocol version %i.%i" , major, minor) : -abs(_e); }); | |||
400 | return 0; | |||
401 | } | |||
402 | ||||
403 | static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, usec_t usec) { | |||
404 | struct autofs_dev_ioctl param; | |||
405 | ||||
406 | assert(dev_autofs_fd >= 0)do { if ((__builtin_expect(!!(!(dev_autofs_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("dev_autofs_fd >= 0"), "../src/core/automount.c" , 406, __PRETTY_FUNCTION__); } while (0); | |||
407 | assert(ioctl_fd >= 0)do { if ((__builtin_expect(!!(!(ioctl_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ioctl_fd >= 0"), "../src/core/automount.c" , 407, __PRETTY_FUNCTION__); } while (0); | |||
408 | ||||
409 | init_autofs_dev_ioctl(¶m); | |||
410 | param.ioctlfd = ioctl_fd; | |||
411 | ||||
412 | if (usec == USEC_INFINITY((usec_t) -1)) | |||
413 | param.timeout.timeout = 0; | |||
414 | else | |||
415 | /* Convert to seconds, rounding up. */ | |||
416 | param.timeout.timeout = DIV_ROUND_UP(usec, USEC_PER_SEC)({ const typeof((usec)) __unique_prefix_X23 = ((usec)); const typeof((((usec_t) 1000000ULL))) __unique_prefix_Y24 = ((((usec_t ) 1000000ULL))); (__unique_prefix_X23 / __unique_prefix_Y24 + !!(__unique_prefix_X23 % __unique_prefix_Y24)); }); | |||
417 | ||||
418 | if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_TIMEOUT_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m) < 0) | |||
419 | return -errno(*__errno_location ()); | |||
420 | ||||
421 | return 0; | |||
422 | } | |||
423 | ||||
424 | static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) { | |||
425 | struct autofs_dev_ioctl param; | |||
426 | ||||
427 | assert(dev_autofs_fd >= 0)do { if ((__builtin_expect(!!(!(dev_autofs_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("dev_autofs_fd >= 0"), "../src/core/automount.c" , 427, __PRETTY_FUNCTION__); } while (0); | |||
428 | assert(ioctl_fd >= 0)do { if ((__builtin_expect(!!(!(ioctl_fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("ioctl_fd >= 0"), "../src/core/automount.c" , 428, __PRETTY_FUNCTION__); } while (0); | |||
429 | ||||
430 | init_autofs_dev_ioctl(¶m); | |||
431 | param.ioctlfd = ioctl_fd; | |||
432 | ||||
433 | if (status != 0) { | |||
434 | param.fail.token = token; | |||
435 | param.fail.status = status; | |||
436 | } else | |||
437 | param.ready.token = token; | |||
438 | ||||
439 | if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_FAIL_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))) : AUTOFS_DEV_IOCTL_READY(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_READY_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m) < 0) | |||
440 | return -errno(*__errno_location ()); | |||
441 | ||||
442 | return 0; | |||
443 | } | |||
444 | ||||
445 | static int automount_send_ready(Automount *a, Set *tokens, int status) { | |||
446 | _cleanup_close___attribute__((cleanup(closep))) int ioctl_fd = -1; | |||
447 | unsigned token; | |||
448 | int r; | |||
449 | ||||
450 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 450, __PRETTY_FUNCTION__ ); } while (0); | |||
451 | assert(status <= 0)do { if ((__builtin_expect(!!(!(status <= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("status <= 0"), "../src/core/automount.c" , 451, __PRETTY_FUNCTION__); } while (0); | |||
452 | ||||
453 | if (set_isempty(tokens)) | |||
454 | return 0; | |||
455 | ||||
456 | ioctl_fd = open_ioctl_fd(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->dev_autofs_fd, a->where, a->dev_id); | |||
457 | if (ioctl_fd < 0) | |||
458 | return ioctl_fd; | |||
459 | ||||
460 | if (status != 0) | |||
461 | log_unit_debug_errno(UNIT(a), status, "Sending failure: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, status, "../src/core/automount.c", 461, __func__, _u-> manager->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Sending failure: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), status, "../src/core/automount.c" , 461, __func__, "Sending failure: %m"); }); | |||
462 | else | |||
463 | log_unit_debug(UNIT(a), "Sending success.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, 0, "../src/core/automount.c", 463, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Sending success.") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 463, __func__, "Sending success."); }); | |||
464 | ||||
465 | r = 0; | |||
466 | ||||
467 | /* Autofs thankfully does not hand out 0 as a token */ | |||
468 | while ((token = PTR_TO_UINT(set_steal_first(tokens))((unsigned int) ((uintptr_t) (set_steal_first(tokens)))))) { | |||
469 | int k; | |||
470 | ||||
471 | /* Autofs fun fact: | |||
472 | * | |||
473 | * if you pass a positive status code here, kernels | |||
474 | * prior to 4.12 will freeze! Yay! */ | |||
475 | ||||
476 | k = autofs_send_ready(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->dev_autofs_fd, | |||
477 | ioctl_fd, | |||
478 | token, | |||
479 | status); | |||
480 | if (k < 0) | |||
481 | r = k; | |||
482 | } | |||
483 | ||||
484 | return r; | |||
485 | } | |||
486 | ||||
487 | static void automount_trigger_notify(Unit *u, Unit *other) { | |||
488 | Automount *a = AUTOMOUNT(u); | |||
489 | int r; | |||
490 | ||||
491 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 491, __PRETTY_FUNCTION__ ); } while (0); | |||
492 | assert(other)do { if ((__builtin_expect(!!(!(other)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("other"), "../src/core/automount.c", 492 , __PRETTY_FUNCTION__); } while (0); | |||
493 | ||||
494 | /* Filter out invocations with bogus state */ | |||
495 | if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT) | |||
496 | return; | |||
497 | ||||
498 | /* Don't propagate state changes from the mount if we are already down */ | |||
499 | if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING})/sizeof (int)]; switch(a->state) { case AUTOMOUNT_WAITING: case AUTOMOUNT_RUNNING : _found = 1; break; default: break; } _found; })) | |||
500 | return; | |||
501 | ||||
502 | /* Propagate start limit hit state */ | |||
503 | if (other->start_limit_hit) { | |||
504 | automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT); | |||
505 | return; | |||
506 | } | |||
507 | ||||
508 | /* Don't propagate anything if there's still a job queued */ | |||
509 | if (other->job) | |||
510 | return; | |||
511 | ||||
512 | /* The mount is successfully established */ | |||
513 | if (IN_SET(MOUNT(other)->state, MOUNT_MOUNTED, MOUNT_REMOUNTING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTED, MOUNT_REMOUNTING})/sizeof (int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTED: case MOUNT_REMOUNTING: _found = 1; break; default: break; } _found ; })) { | |||
514 | (void) automount_send_ready(a, a->tokens, 0); | |||
515 | ||||
516 | r = automount_start_expire(a); | |||
517 | if (r < 0) | |||
518 | log_unit_warning_errno(UNIT(a), r, "Failed to start expiration timer, ignoring: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (4, r, "../src/core/automount.c", 518, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to start expiration timer, ignoring: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4 ))), r, "../src/core/automount.c", 518, __func__, "Failed to start expiration timer, ignoring: %m" ); }); | |||
519 | ||||
520 | automount_set_state(a, AUTOMOUNT_RUNNING); | |||
521 | } | |||
522 | ||||
523 | if (IN_SET(MOUNT(other)->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; }) | |||
524 | MOUNT_MOUNTING, MOUNT_MOUNTING_DONE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; }) | |||
525 | MOUNT_MOUNTED, MOUNT_REMOUNTING,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; }) | |||
526 | MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; }) | |||
527 | MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; }) | |||
528 | MOUNT_FAILED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_MOUNTING, MOUNT_MOUNTING_DONE, MOUNT_MOUNTED , MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL , MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILED })/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_MOUNTING : case MOUNT_MOUNTING_DONE: case MOUNT_MOUNTED: case MOUNT_REMOUNTING : case MOUNT_REMOUNTING_SIGTERM: case MOUNT_REMOUNTING_SIGKILL : case MOUNT_UNMOUNTING_SIGTERM: case MOUNT_UNMOUNTING_SIGKILL : case MOUNT_FAILED: _found = 1; break; default: break; } _found ; })) { | |||
529 | ||||
530 | (void) automount_send_ready(a, a->expire_tokens, -ENODEV19); | |||
531 | } | |||
532 | ||||
533 | if (MOUNT(other)->state == MOUNT_DEAD) | |||
534 | (void) automount_send_ready(a, a->expire_tokens, 0); | |||
535 | ||||
536 | /* The mount is in some unhappy state now, let's unfreeze any waiting clients */ | |||
537 | if (IN_SET(MOUNT(other)->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_DEAD, MOUNT_UNMOUNTING, MOUNT_REMOUNTING_SIGTERM , MOUNT_REMOUNTING_SIGKILL, MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL , MOUNT_FAILED})/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_DEAD: case MOUNT_UNMOUNTING: case MOUNT_REMOUNTING_SIGTERM : case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM : case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_FAILED: _found = 1 ; break; default: break; } _found; }) | |||
538 | MOUNT_DEAD, MOUNT_UNMOUNTING,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_DEAD, MOUNT_UNMOUNTING, MOUNT_REMOUNTING_SIGTERM , MOUNT_REMOUNTING_SIGKILL, MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL , MOUNT_FAILED})/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_DEAD: case MOUNT_UNMOUNTING: case MOUNT_REMOUNTING_SIGTERM : case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM : case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_FAILED: _found = 1 ; break; default: break; } _found; }) | |||
539 | MOUNT_REMOUNTING_SIGTERM, MOUNT_REMOUNTING_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_DEAD, MOUNT_UNMOUNTING, MOUNT_REMOUNTING_SIGTERM , MOUNT_REMOUNTING_SIGKILL, MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL , MOUNT_FAILED})/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_DEAD: case MOUNT_UNMOUNTING: case MOUNT_REMOUNTING_SIGTERM : case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM : case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_FAILED: _found = 1 ; break; default: break; } _found; }) | |||
540 | MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_DEAD, MOUNT_UNMOUNTING, MOUNT_REMOUNTING_SIGTERM , MOUNT_REMOUNTING_SIGKILL, MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL , MOUNT_FAILED})/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_DEAD: case MOUNT_UNMOUNTING: case MOUNT_REMOUNTING_SIGTERM : case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM : case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_FAILED: _found = 1 ; break; default: break; } _found; }) | |||
541 | MOUNT_FAILED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){MOUNT_DEAD, MOUNT_UNMOUNTING, MOUNT_REMOUNTING_SIGTERM , MOUNT_REMOUNTING_SIGKILL, MOUNT_UNMOUNTING_SIGTERM, MOUNT_UNMOUNTING_SIGKILL , MOUNT_FAILED})/sizeof(int)]; switch(MOUNT(other)->state) { case MOUNT_DEAD: case MOUNT_UNMOUNTING: case MOUNT_REMOUNTING_SIGTERM : case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM : case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_FAILED: _found = 1 ; break; default: break; } _found; })) { | |||
542 | ||||
543 | (void) automount_send_ready(a, a->tokens, -ENODEV19); | |||
544 | ||||
545 | automount_set_state(a, AUTOMOUNT_WAITING); | |||
546 | } | |||
547 | } | |||
548 | ||||
549 | static void automount_enter_waiting(Automount *a) { | |||
550 | _cleanup_close___attribute__((cleanup(closep))) int ioctl_fd = -1; | |||
551 | int p[2] = { -1, -1 }; | |||
552 | char name[STRLEN("systemd-")(sizeof("""systemd-""") - 1) + DECIMAL_STR_MAX(pid_t)(2+(sizeof(pid_t) <= 1 ? 3 : sizeof(pid_t) <= 2 ? 5 : sizeof (pid_t) <= 4 ? 10 : sizeof(pid_t) <= 8 ? 20 : sizeof(int [-2*(sizeof(pid_t) > 8)]))) + 1]; | |||
553 | char options[STRLEN("fd=,pgrp=,minproto=5,maxproto=5,direct")(sizeof("""fd=,pgrp=,minproto=5,maxproto=5,direct""") - 1) | |||
554 | + DECIMAL_STR_MAX(int)(2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 : sizeof (int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof(int[-2 *(sizeof(int) > 8)]))) + DECIMAL_STR_MAX(gid_t)(2+(sizeof(gid_t) <= 1 ? 3 : sizeof(gid_t) <= 2 ? 5 : sizeof (gid_t) <= 4 ? 10 : sizeof(gid_t) <= 8 ? 20 : sizeof(int [-2*(sizeof(gid_t) > 8)]))) + 1]; | |||
555 | bool_Bool mounted = false0; | |||
556 | int r, dev_autofs_fd; | |||
557 | struct stat st; | |||
558 | ||||
559 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 559, __PRETTY_FUNCTION__ ); } while (0); | |||
560 | assert(a->pipe_fd < 0)do { if ((__builtin_expect(!!(!(a->pipe_fd < 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a->pipe_fd < 0"), "../src/core/automount.c" , 560, __PRETTY_FUNCTION__); } while (0); | |||
561 | assert(a->where)do { if ((__builtin_expect(!!(!(a->where)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a->where"), "../src/core/automount.c" , 561, __PRETTY_FUNCTION__); } while (0); | |||
562 | ||||
563 | set_clear(a->tokens); | |||
564 | ||||
565 | r = unit_fail_if_noncanonical(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), a->where); | |||
566 | if (r < 0) | |||
567 | goto fail; | |||
568 | ||||
569 | (void) mkdir_p_label(a->where, 0555); | |||
570 | ||||
571 | unit_warn_if_dir_nonempty(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }), a->where); | |||
572 | ||||
573 | dev_autofs_fd = open_dev_autofs(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager); | |||
574 | if (dev_autofs_fd < 0) { | |||
575 | r = dev_autofs_fd; | |||
576 | goto fail; | |||
577 | } | |||
578 | ||||
579 | if (pipe2(p, O_NONBLOCK04000|O_CLOEXEC02000000) < 0) { | |||
580 | r = -errno(*__errno_location ()); | |||
581 | goto fail; | |||
582 | } | |||
583 | ||||
584 | xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp())do { if ((__builtin_expect(!!(!(((size_t) snprintf(options, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (options), typeof(&*(options))), sizeof(options)/sizeof(( options)[0]), ((void)0))), "fd=%i,pgrp=""%" "i"",minproto=5,maxproto=5,direct" , p[1], getpgrp()) < (__extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(options), typeof(& *(options))), sizeof(options)/sizeof((options)[0]), ((void)0) )))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("xsprintf: " "options" "[] must be big enough"), "../src/core/automount.c" , 584, __PRETTY_FUNCTION__); } while (0); | |||
585 | xsprintf(name, "systemd-"PID_FMT, getpid_cached())do { if ((__builtin_expect(!!(!(((size_t) snprintf(name, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (name), typeof(&*(name))), sizeof(name)/sizeof((name)[0]) , ((void)0))), "systemd-""%" "i", getpid_cached()) < (__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (name), typeof(&*(name))), sizeof(name)/sizeof((name)[0]) , ((void)0))))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("xsprintf: " "name" "[] must be big enough"), "../src/core/automount.c" , 585, __PRETTY_FUNCTION__); } while (0); | |||
586 | if (mount(name, a->where, "autofs", 0, options) < 0) { | |||
587 | r = -errno(*__errno_location ()); | |||
588 | goto fail; | |||
589 | } | |||
590 | ||||
591 | mounted = true1; | |||
592 | ||||
593 | p[1] = safe_close(p[1]); | |||
594 | ||||
595 | if (stat(a->where, &st) < 0) { | |||
596 | r = -errno(*__errno_location ()); | |||
597 | goto fail; | |||
598 | } | |||
599 | ||||
600 | ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev); | |||
601 | if (ioctl_fd < 0) { | |||
602 | r = ioctl_fd; | |||
603 | goto fail; | |||
604 | } | |||
605 | ||||
606 | r = autofs_protocol(dev_autofs_fd, ioctl_fd); | |||
607 | if (r < 0) | |||
608 | goto fail; | |||
609 | ||||
610 | r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, a->timeout_idle_usec); | |||
611 | if (r < 0) | |||
612 | goto fail; | |||
613 | ||||
614 | r = sd_event_add_io(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->event, &a->pipe_event_source, p[0], EPOLLINEPOLLIN, automount_dispatch_io, a); | |||
615 | if (r < 0) | |||
616 | goto fail; | |||
617 | ||||
618 | (void) sd_event_source_set_description(a->pipe_event_source, "automount-io"); | |||
619 | ||||
620 | a->pipe_fd = p[0]; | |||
621 | a->dev_id = st.st_dev; | |||
622 | ||||
623 | automount_set_state(a, AUTOMOUNT_WAITING); | |||
624 | ||||
625 | return; | |||
626 | ||||
627 | fail: | |||
628 | log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 628, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to initialize automounter: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), r, "../src/core/automount.c", 628, __func__, "Failed to initialize automounter: %m" ); }); | |||
629 | ||||
630 | safe_close_pair(p); | |||
631 | ||||
632 | if (mounted) { | |||
633 | r = repeat_unmount(a->where, MNT_DETACHMNT_DETACH); | |||
634 | if (r < 0) | |||
635 | log_error_errno(r, "Failed to unmount, ignoring: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/core/automount.c", 635, __func__, "Failed to unmount, ignoring: %m" ) : -abs(_e); }); | |||
636 | } | |||
637 | ||||
638 | automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); | |||
639 | } | |||
640 | ||||
641 | static void *expire_thread(void *p) { | |||
642 | struct autofs_dev_ioctl param; | |||
643 | _cleanup_(expire_data_freep)__attribute__((cleanup(expire_data_freep))) struct expire_data *data = (struct expire_data*)p; | |||
644 | int r; | |||
645 | ||||
646 | assert(data->dev_autofs_fd >= 0)do { if ((__builtin_expect(!!(!(data->dev_autofs_fd >= 0 )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("data->dev_autofs_fd >= 0" ), "../src/core/automount.c", 646, __PRETTY_FUNCTION__); } while (0); | |||
647 | assert(data->ioctl_fd >= 0)do { if ((__builtin_expect(!!(!(data->ioctl_fd >= 0)),0 ))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("data->ioctl_fd >= 0" ), "../src/core/automount.c", 647, __PRETTY_FUNCTION__); } while (0); | |||
648 | ||||
649 | init_autofs_dev_ioctl(¶m); | |||
650 | param.ioctlfd = data->ioctl_fd; | |||
651 | ||||
652 | do { | |||
653 | r = ioctl(data->dev_autofs_fd, AUTOFS_DEV_IOCTL_EXPIRE(((2U|1U) << (((0 +8)+8)+14)) | (((0x93)) << (0 + 8)) | (((AUTOFS_DEV_IOCTL_EXPIRE_CMD)) << 0) | ((((sizeof (struct autofs_dev_ioctl)))) << ((0 +8)+8))), ¶m); | |||
654 | } while (r >= 0); | |||
655 | ||||
656 | if (errno(*__errno_location ()) != EAGAIN11) | |||
657 | log_warning_errno(errno, "Failed to expire automount, ignoring: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/core/automount.c", 657, __func__ , "Failed to expire automount, ignoring: %m") : -abs(_e); }); | |||
658 | ||||
659 | return NULL((void*)0); | |||
660 | } | |||
661 | ||||
662 | static int automount_dispatch_expire(sd_event_source *source, usec_t usec, void *userdata) { | |||
663 | Automount *a = AUTOMOUNT(userdata); | |||
664 | _cleanup_(expire_data_freep)__attribute__((cleanup(expire_data_freep))) struct expire_data *data = NULL((void*)0); | |||
665 | int r; | |||
666 | ||||
667 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 667, __PRETTY_FUNCTION__ ); } while (0); | |||
| ||||
668 | assert(source == a->expire_event_source)do { if ((__builtin_expect(!!(!(source == a->expire_event_source )),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("source == a->expire_event_source" ), "../src/core/automount.c", 668, __PRETTY_FUNCTION__); } while (0); | |||
669 | ||||
670 | data = new0(struct expire_data, 1)((struct expire_data*) calloc((1), sizeof(struct expire_data) )); | |||
671 | if (!data) | |||
672 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/automount.c" , 672, __func__); | |||
673 | ||||
674 | data->ioctl_fd = -1; | |||
675 | ||||
676 | data->dev_autofs_fd = fcntl(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->dev_autofs_fd, F_DUPFD_CLOEXEC1030, 3); | |||
677 | if (data->dev_autofs_fd < 0) | |||
678 | return log_unit_error_errno(UNIT(a), errno, "Failed to duplicate autofs fd: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, (*__errno_location ()), "../src/core/automount.c", 678, __func__ , _u->manager->unit_log_field, _u->id, _u->manager ->invocation_log_field, _u->invocation_id_string, "Failed to duplicate autofs fd: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), (*__errno_location ()), "../src/core/automount.c", 678, __func__ , "Failed to duplicate autofs fd: %m"); }); | |||
| ||||
679 | ||||
680 | data->ioctl_fd = open_ioctl_fd(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->dev_autofs_fd, a->where, a->dev_id); | |||
681 | if (data->ioctl_fd < 0) | |||
682 | return log_unit_error_errno(UNIT(a), data->ioctl_fd, "Couldn't open autofs ioctl fd: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, data->ioctl_fd, "../src/core/automount.c", 682, __func__ , _u->manager->unit_log_field, _u->id, _u->manager ->invocation_log_field, _u->invocation_id_string, "Couldn't open autofs ioctl fd: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), data->ioctl_fd, "../src/core/automount.c", 682, __func__ , "Couldn't open autofs ioctl fd: %m"); }); | |||
683 | ||||
684 | r = asynchronous_job(expire_thread, data); | |||
685 | if (r < 0) | |||
686 | return log_unit_error_errno(UNIT(a), r, "Failed to start expire job: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 686, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to start expire job: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), r, "../src/core/automount.c", 686, __func__, "Failed to start expire job: %m" ); }); | |||
687 | ||||
688 | data = NULL((void*)0); | |||
689 | ||||
690 | return automount_start_expire(a); | |||
691 | } | |||
692 | ||||
693 | static int automount_start_expire(Automount *a) { | |||
694 | int r; | |||
695 | usec_t timeout; | |||
696 | ||||
697 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 697, __PRETTY_FUNCTION__ ); } while (0); | |||
698 | ||||
699 | if (a->timeout_idle_usec == 0) | |||
700 | return 0; | |||
701 | ||||
702 | timeout = now(CLOCK_MONOTONIC1) + MAX(a->timeout_idle_usec/3, USEC_PER_SEC)__extension__ ({ const typeof((a->timeout_idle_usec/3)) __unique_prefix_A25 = ((a->timeout_idle_usec/3)); const typeof((((usec_t) 1000000ULL ))) __unique_prefix_B26 = ((((usec_t) 1000000ULL))); __unique_prefix_A25 > __unique_prefix_B26 ? __unique_prefix_A25 : __unique_prefix_B26 ; }); | |||
703 | ||||
704 | if (a->expire_event_source) { | |||
705 | r = sd_event_source_set_time(a->expire_event_source, timeout); | |||
706 | if (r < 0) | |||
707 | return r; | |||
708 | ||||
709 | return sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_ONESHOT); | |||
710 | } | |||
711 | ||||
712 | r = sd_event_add_time( | |||
713 | UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager->event, | |||
714 | &a->expire_event_source, | |||
715 | CLOCK_MONOTONIC1, timeout, 0, | |||
716 | automount_dispatch_expire, a); | |||
717 | if (r < 0) | |||
718 | return r; | |||
719 | ||||
720 | (void) sd_event_source_set_description(a->expire_event_source, "automount-expire"); | |||
721 | ||||
722 | return 0; | |||
723 | } | |||
724 | ||||
725 | static void automount_stop_expire(Automount *a) { | |||
726 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 726, __PRETTY_FUNCTION__ ); } while (0); | |||
727 | ||||
728 | if (!a->expire_event_source) | |||
729 | return; | |||
730 | ||||
731 | (void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF); | |||
732 | } | |||
733 | ||||
734 | static void automount_enter_running(Automount *a) { | |||
735 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
736 | Unit *trigger; | |||
737 | struct stat st; | |||
738 | int r; | |||
739 | ||||
740 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 740, __PRETTY_FUNCTION__ ); } while (0); | |||
741 | ||||
742 | /* If the user masked our unit in the meantime, fail */ | |||
743 | if (UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->load_state != UNIT_LOADED) { | |||
744 | log_unit_error(UNIT(a), "Suppressing automount event since unit is no longer loaded.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 744, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Suppressing automount event since unit is no longer loaded." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), 0, "../src/core/automount.c", 744, __func__, "Suppressing automount event since unit is no longer loaded." ); }); | |||
745 | goto fail; | |||
746 | } | |||
747 | ||||
748 | /* We don't take mount requests anymore if we are supposed to | |||
749 | * shut down anyway */ | |||
750 | if (unit_stop_pending(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }))) { | |||
751 | log_unit_debug(UNIT(a), "Suppressing automount request since unit stop is scheduled.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, 0, "../src/core/automount.c", 751, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Suppressing automount request since unit stop is scheduled." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7 ))), 0, "../src/core/automount.c", 751, __func__, "Suppressing automount request since unit stop is scheduled." ); }); | |||
752 | automount_send_ready(a, a->tokens, -EHOSTDOWN112); | |||
753 | automount_send_ready(a, a->expire_tokens, -EHOSTDOWN112); | |||
754 | return; | |||
755 | } | |||
756 | ||||
757 | mkdir_p_label(a->where, a->directory_mode); | |||
758 | ||||
759 | /* Before we do anything, let's see if somebody is playing games with us? */ | |||
760 | if (lstat(a->where, &st) < 0) { | |||
761 | log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (4, (*__errno_location ()), "../src/core/automount.c", 761, __func__ , _u->manager->unit_log_field, _u->id, _u->manager ->invocation_log_field, _u->invocation_id_string, "Failed to stat automount point: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4 ))), (*__errno_location ()), "../src/core/automount.c", 761, __func__ , "Failed to stat automount point: %m"); }); | |||
762 | goto fail; | |||
763 | } | |||
764 | ||||
765 | /* The mount unit may have been explicitly started before we got the | |||
766 | * autofs request. Ack it to unblock anything waiting on the mount point. */ | |||
767 | if (!S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000)) || st.st_dev != a->dev_id) { | |||
768 | log_unit_info(UNIT(a), "Automount point already active?")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (6, 0, "../src/core/automount.c", 768, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Automount point already active?" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((6 ))), 0, "../src/core/automount.c", 768, __func__, "Automount point already active?" ); }); | |||
769 | automount_send_ready(a, a->tokens, 0); | |||
770 | return; | |||
771 | } | |||
772 | ||||
773 | trigger = UNIT_TRIGGER(UNIT(a))((Unit*) hashmap_first_key((({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }))->dependencies [UNIT_TRIGGERS])); | |||
774 | if (!trigger) { | |||
775 | log_unit_error(UNIT(a), "Unit to trigger vanished.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 775, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Unit to trigger vanished.") : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))) , 0, "../src/core/automount.c", 775, __func__, "Unit to trigger vanished." ); }); | |||
776 | goto fail; | |||
777 | } | |||
778 | ||||
779 | r = manager_add_job(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager, JOB_START, trigger, JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0)); | |||
780 | if (r < 0) { | |||
781 | log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r))({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (4, 0, "../src/core/automount.c", 781, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to queue mount startup job: %s" , bus_error_message(&error, r)) : log_internal_realm(((LOG_REALM_SYSTEMD ) << 10 | ((4))), 0, "../src/core/automount.c", 781, __func__ , "Failed to queue mount startup job: %s", bus_error_message( &error, r)); }); | |||
782 | goto fail; | |||
783 | } | |||
784 | ||||
785 | automount_set_state(a, AUTOMOUNT_RUNNING); | |||
786 | return; | |||
787 | ||||
788 | fail: | |||
789 | automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); | |||
790 | } | |||
791 | ||||
792 | static int automount_start(Unit *u) { | |||
793 | Automount *a = AUTOMOUNT(u); | |||
794 | Unit *trigger; | |||
795 | int r; | |||
796 | ||||
797 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 797, __PRETTY_FUNCTION__ ); } while (0); | |||
798 | assert(IN_SET(a->state, AUTOMOUNT_DEAD, AUTOMOUNT_FAILED))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){AUTOMOUNT_DEAD, AUTOMOUNT_FAILED})/sizeof(int )]; switch(a->state) { case AUTOMOUNT_DEAD: case AUTOMOUNT_FAILED : _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("IN_SET(a->state, AUTOMOUNT_DEAD, AUTOMOUNT_FAILED)" ), "../src/core/automount.c", 798, __PRETTY_FUNCTION__); } while (0); | |||
799 | ||||
800 | if (path_is_mount_point(a->where, NULL((void*)0), 0) > 0) { | |||
801 | log_unit_error(u, "Path %s is already a mount point, refusing start.", a->where)({ const Unit *_u = (u); _u ? log_object_internal(3, 0, "../src/core/automount.c" , 801, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Path %s is already a mount point, refusing start.", a-> where) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/core/automount.c", 801, __func__, "Path %s is already a mount point, refusing start." , a->where); }); | |||
802 | return -EEXIST17; | |||
803 | } | |||
804 | ||||
805 | trigger = UNIT_TRIGGER(u)((Unit*) hashmap_first_key((u)->dependencies[UNIT_TRIGGERS ])); | |||
806 | if (!trigger || trigger->load_state != UNIT_LOADED) { | |||
807 | log_unit_error(u, "Refusing to start, unit to trigger not loaded.")({ const Unit *_u = (u); _u ? log_object_internal(3, 0, "../src/core/automount.c" , 807, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Refusing to start, unit to trigger not loaded.") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/core/automount.c" , 807, __func__, "Refusing to start, unit to trigger not loaded." ); }); | |||
808 | return -ENOENT2; | |||
809 | } | |||
810 | ||||
811 | r = unit_start_limit_test(u); | |||
812 | if (r < 0) { | |||
813 | automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); | |||
814 | return r; | |||
815 | } | |||
816 | ||||
817 | r = unit_acquire_invocation_id(u); | |||
818 | if (r < 0) | |||
819 | return r; | |||
820 | ||||
821 | a->result = AUTOMOUNT_SUCCESS; | |||
822 | automount_enter_waiting(a); | |||
823 | return 1; | |||
824 | } | |||
825 | ||||
826 | static int automount_stop(Unit *u) { | |||
827 | Automount *a = AUTOMOUNT(u); | |||
828 | ||||
829 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 829, __PRETTY_FUNCTION__ ); } while (0); | |||
830 | assert(IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended[20 - sizeof((int[]){AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING})/sizeof (int)]; switch(a->state) { case AUTOMOUNT_WAITING: case AUTOMOUNT_RUNNING : _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)" ), "../src/core/automount.c", 830, __PRETTY_FUNCTION__); } while (0); | |||
831 | ||||
832 | automount_enter_dead(a, AUTOMOUNT_SUCCESS); | |||
833 | return 1; | |||
834 | } | |||
835 | ||||
836 | static int automount_serialize(Unit *u, FILE *f, FDSet *fds) { | |||
837 | Automount *a = AUTOMOUNT(u); | |||
838 | Iterator i; | |||
839 | void *p; | |||
840 | int r; | |||
841 | ||||
842 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 842, __PRETTY_FUNCTION__ ); } while (0); | |||
843 | assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("f"), "../src/core/automount.c", 843, __PRETTY_FUNCTION__ ); } while (0); | |||
844 | assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fds"), "../src/core/automount.c", 844, __PRETTY_FUNCTION__ ); } while (0); | |||
845 | ||||
846 | unit_serialize_item(u, f, "state", automount_state_to_string(a->state)); | |||
847 | unit_serialize_item(u, f, "result", automount_result_to_string(a->result)); | |||
848 | unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id); | |||
849 | ||||
850 | SET_FOREACH(p, a->tokens, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((a->tokens), &(i ), (void**)&(p)); ) | |||
851 | unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p)((unsigned int) ((uintptr_t) (p)))); | |||
852 | SET_FOREACH(p, a->expire_tokens, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), . next_key = ((void*)0) }); set_iterate((a->expire_tokens), & (i), (void**)&(p)); ) | |||
853 | unit_serialize_item_format(u, f, "expire-token", "%u", PTR_TO_UINT(p)((unsigned int) ((uintptr_t) (p)))); | |||
854 | ||||
855 | r = unit_serialize_item_fd(u, f, fds, "pipe-fd", a->pipe_fd); | |||
856 | if (r < 0) | |||
857 | return r; | |||
858 | ||||
859 | return 0; | |||
860 | } | |||
861 | ||||
862 | static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { | |||
863 | Automount *a = AUTOMOUNT(u); | |||
864 | int r; | |||
865 | ||||
866 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 866, __PRETTY_FUNCTION__ ); } while (0); | |||
867 | assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fds"), "../src/core/automount.c", 867, __PRETTY_FUNCTION__ ); } while (0); | |||
868 | ||||
869 | if (streq(key, "state")(strcmp((key),("state")) == 0)) { | |||
870 | AutomountState state; | |||
871 | ||||
872 | state = automount_state_from_string(value); | |||
873 | if (state < 0) | |||
874 | log_unit_debug(u, "Failed to parse state value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 874, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse state value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 874, __func__, "Failed to parse state value: %s", value); } ); | |||
875 | else | |||
876 | a->deserialized_state = state; | |||
877 | } else if (streq(key, "result")(strcmp((key),("result")) == 0)) { | |||
878 | AutomountResult f; | |||
879 | ||||
880 | f = automount_result_from_string(value); | |||
881 | if (f < 0) | |||
882 | log_unit_debug(u, "Failed to parse result value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 882, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse result value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 882, __func__, "Failed to parse result value: %s", value); } ); | |||
883 | else if (f != AUTOMOUNT_SUCCESS) | |||
884 | a->result = f; | |||
885 | ||||
886 | } else if (streq(key, "dev-id")(strcmp((key),("dev-id")) == 0)) { | |||
887 | unsigned d; | |||
888 | ||||
889 | if (safe_atou(value, &d) < 0) | |||
890 | log_unit_debug(u, "Failed to parse dev-id value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 890, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse dev-id value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 890, __func__, "Failed to parse dev-id value: %s", value); } ); | |||
891 | else | |||
892 | a->dev_id = (unsigned) d; | |||
893 | } else if (streq(key, "token")(strcmp((key),("token")) == 0)) { | |||
894 | unsigned token; | |||
895 | ||||
896 | if (safe_atou(value, &token) < 0) | |||
897 | log_unit_debug(u, "Failed to parse token value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 897, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse token value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 897, __func__, "Failed to parse token value: %s", value); } ); | |||
898 | else { | |||
899 | r = set_ensure_allocated(&a->tokens, NULL)internal_set_ensure_allocated(&a->tokens, ((void*)0) ); | |||
900 | if (r < 0) { | |||
901 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/automount.c" , 901, __func__); | |||
902 | return 0; | |||
903 | } | |||
904 | ||||
905 | r = set_put(a->tokens, UINT_TO_PTR(token)((void *) ((uintptr_t) (token)))); | |||
906 | if (r < 0) | |||
907 | log_unit_error_errno(u, r, "Failed to add token to set: %m")({ const Unit *_u = (u); _u ? log_object_internal(3, r, "../src/core/automount.c" , 907, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to add token to set: %m") : log_internal_realm(((LOG_REALM_SYSTEMD ) << 10 | ((3))), r, "../src/core/automount.c", 907, __func__ , "Failed to add token to set: %m"); }); | |||
908 | } | |||
909 | } else if (streq(key, "expire-token")(strcmp((key),("expire-token")) == 0)) { | |||
910 | unsigned token; | |||
911 | ||||
912 | if (safe_atou(value, &token) < 0) | |||
913 | log_unit_debug(u, "Failed to parse token value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 913, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse token value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 913, __func__, "Failed to parse token value: %s", value); } ); | |||
914 | else { | |||
915 | r = set_ensure_allocated(&a->expire_tokens, NULL)internal_set_ensure_allocated(&a->expire_tokens, ((void *)0) ); | |||
916 | if (r < 0) { | |||
917 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/automount.c" , 917, __func__); | |||
918 | return 0; | |||
919 | } | |||
920 | ||||
921 | r = set_put(a->expire_tokens, UINT_TO_PTR(token)((void *) ((uintptr_t) (token)))); | |||
922 | if (r < 0) | |||
923 | log_unit_error_errno(u, r, "Failed to add expire token to set: %m")({ const Unit *_u = (u); _u ? log_object_internal(3, r, "../src/core/automount.c" , 923, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to add expire token to set: %m") : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((3))), r, "../src/core/automount.c" , 923, __func__, "Failed to add expire token to set: %m"); }); | |||
924 | } | |||
925 | } else if (streq(key, "pipe-fd")(strcmp((key),("pipe-fd")) == 0)) { | |||
926 | int fd; | |||
927 | ||||
928 | if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) | |||
929 | log_unit_debug(u, "Failed to parse pipe-fd value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 929, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Failed to parse pipe-fd value: %s", value) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 929, __func__, "Failed to parse pipe-fd value: %s", value); }); | |||
930 | else { | |||
931 | safe_close(a->pipe_fd); | |||
932 | a->pipe_fd = fdset_remove(fds, fd); | |||
933 | } | |||
934 | } else | |||
935 | log_unit_debug(u, "Unknown serialization key: %s", key)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/automount.c" , 935, __func__, _u->manager->unit_log_field, _u->id , _u->manager->invocation_log_field, _u->invocation_id_string , "Unknown serialization key: %s", key) : log_internal_realm( ((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c" , 935, __func__, "Unknown serialization key: %s", key); }); | |||
936 | ||||
937 | return 0; | |||
938 | } | |||
939 | ||||
940 | static UnitActiveState automount_active_state(Unit *u) { | |||
941 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/automount.c", 941, __PRETTY_FUNCTION__ ); } while (0); | |||
942 | ||||
943 | return state_translation_table[AUTOMOUNT(u)->state]; | |||
944 | } | |||
945 | ||||
946 | static const char *automount_sub_state_to_string(Unit *u) { | |||
947 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/automount.c", 947, __PRETTY_FUNCTION__ ); } while (0); | |||
948 | ||||
949 | return automount_state_to_string(AUTOMOUNT(u)->state); | |||
950 | } | |||
951 | ||||
952 | static bool_Bool automount_may_gc(Unit *u) { | |||
953 | Unit *t; | |||
954 | ||||
955 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/core/automount.c", 955, __PRETTY_FUNCTION__ ); } while (0); | |||
956 | ||||
957 | t = UNIT_TRIGGER(u)((Unit*) hashmap_first_key((u)->dependencies[UNIT_TRIGGERS ])); | |||
958 | if (!t) | |||
959 | return true1; | |||
960 | ||||
961 | return UNIT_VTABLE(t)unit_vtable[(t)->type]->may_gc(t); | |||
962 | } | |||
963 | ||||
964 | static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) { | |||
965 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
966 | union autofs_v5_packet_union packet; | |||
967 | Automount *a = AUTOMOUNT(userdata); | |||
968 | Unit *trigger; | |||
969 | int r; | |||
970 | ||||
971 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 971, __PRETTY_FUNCTION__ ); } while (0); | |||
972 | assert(fd == a->pipe_fd)do { if ((__builtin_expect(!!(!(fd == a->pipe_fd)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd == a->pipe_fd"), "../src/core/automount.c" , 972, __PRETTY_FUNCTION__); } while (0); | |||
973 | ||||
974 | if (events != EPOLLINEPOLLIN) { | |||
975 | log_unit_error(UNIT(a), "Got invalid poll event %"PRIu32" on pipe (fd=%d)", events, fd)({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 975, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Got invalid poll event %""u"" on pipe (fd=%d)" , events, fd) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/core/automount.c", 975, __func__, "Got invalid poll event %" "u"" on pipe (fd=%d)", events, fd); }); | |||
976 | goto fail; | |||
977 | } | |||
978 | ||||
979 | r = loop_read_exact(a->pipe_fd, &packet, sizeof(packet), true1); | |||
980 | if (r < 0) { | |||
981 | log_unit_error_errno(UNIT(a), r, "Invalid read from pipe: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 981, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Invalid read from pipe: %m") : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))) , r, "../src/core/automount.c", 981, __func__, "Invalid read from pipe: %m" ); }); | |||
982 | goto fail; | |||
983 | } | |||
984 | ||||
985 | switch (packet.hdr.type) { | |||
986 | ||||
987 | case autofs_ptype_missing_direct5: | |||
988 | ||||
989 | if (packet.v5_packet.pid > 0) { | |||
990 | _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0); | |||
991 | ||||
992 | get_process_comm(packet.v5_packet.pid, &p); | |||
993 | log_unit_info(UNIT(a), "Got automount request for %s, triggered by %"PRIu32" (%s)", a->where, packet.v5_packet.pid, strna(p))({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (6, 0, "../src/core/automount.c", 993, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Got automount request for %s, triggered by %" "u"" (%s)", a->where, packet.v5_packet.pid, strna(p)) : log_internal_realm (((LOG_REALM_SYSTEMD) << 10 | ((6))), 0, "../src/core/automount.c" , 993, __func__, "Got automount request for %s, triggered by %" "u"" (%s)", a->where, packet.v5_packet.pid, strna(p)); }); | |||
994 | } else | |||
995 | log_unit_debug(UNIT(a), "Got direct mount request on %s", a->where)({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, 0, "../src/core/automount.c", 995, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Got direct mount request on %s" , a->where) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c", 995, __func__, "Got direct mount request on %s" , a->where); }); | |||
996 | ||||
997 | r = set_ensure_allocated(&a->tokens, NULL)internal_set_ensure_allocated(&a->tokens, ((void*)0) ); | |||
998 | if (r < 0) { | |||
999 | log_unit_error(UNIT(a), "Failed to allocate token set.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 999, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to allocate token set." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), 0, "../src/core/automount.c", 999, __func__, "Failed to allocate token set." ); }); | |||
1000 | goto fail; | |||
1001 | } | |||
1002 | ||||
1003 | r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token)((void *) ((uintptr_t) (packet.v5_packet.wait_queue_token)))); | |||
1004 | if (r < 0) { | |||
1005 | log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 1005, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to remember token: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), r, "../src/core/automount.c", 1005, __func__, "Failed to remember token: %m" ); }); | |||
1006 | goto fail; | |||
1007 | } | |||
1008 | ||||
1009 | automount_enter_running(a); | |||
1010 | break; | |||
1011 | ||||
1012 | case autofs_ptype_expire_direct6: | |||
1013 | log_unit_debug(UNIT(a), "Got direct umount request on %s", a->where)({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (7, 0, "../src/core/automount.c", 1013, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Got direct umount request on %s" , a->where) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/automount.c", 1013, __func__, "Got direct umount request on %s" , a->where); }); | |||
1014 | ||||
1015 | automount_stop_expire(a); | |||
1016 | ||||
1017 | r = set_ensure_allocated(&a->expire_tokens, NULL)internal_set_ensure_allocated(&a->expire_tokens, ((void *)0) ); | |||
1018 | if (r < 0) { | |||
1019 | log_unit_error(UNIT(a), "Failed to allocate token set.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 1019, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to allocate token set." ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), 0, "../src/core/automount.c", 1019, __func__, "Failed to allocate token set." ); }); | |||
1020 | goto fail; | |||
1021 | } | |||
1022 | ||||
1023 | r = set_put(a->expire_tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token)((void *) ((uintptr_t) (packet.v5_packet.wait_queue_token)))); | |||
1024 | if (r < 0) { | |||
1025 | log_unit_error_errno(UNIT(a), r, "Failed to remember token: %m")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, r, "../src/core/automount.c", 1025, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to remember token: %m" ) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3 ))), r, "../src/core/automount.c", 1025, __func__, "Failed to remember token: %m" ); }); | |||
1026 | goto fail; | |||
1027 | } | |||
1028 | ||||
1029 | trigger = UNIT_TRIGGER(UNIT(a))((Unit*) hashmap_first_key((({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }))->dependencies [UNIT_TRIGGERS])); | |||
1030 | if (!trigger) { | |||
1031 | log_unit_error(UNIT(a), "Unit to trigger vanished.")({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 1031, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Unit to trigger vanished.") : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))) , 0, "../src/core/automount.c", 1031, __func__, "Unit to trigger vanished." ); }); | |||
1032 | goto fail; | |||
1033 | } | |||
1034 | ||||
1035 | r = manager_add_job(UNIT(a)({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })->manager, JOB_STOP, trigger, JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0)); | |||
1036 | if (r < 0) { | |||
1037 | log_unit_warning(UNIT(a), "Failed to queue umount startup job: %s", bus_error_message(&error, r))({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (4, 0, "../src/core/automount.c", 1037, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Failed to queue umount startup job: %s" , bus_error_message(&error, r)) : log_internal_realm(((LOG_REALM_SYSTEMD ) << 10 | ((4))), 0, "../src/core/automount.c", 1037, __func__ , "Failed to queue umount startup job: %s", bus_error_message (&error, r)); }); | |||
1038 | goto fail; | |||
1039 | } | |||
1040 | break; | |||
1041 | ||||
1042 | default: | |||
1043 | log_unit_error(UNIT(a), "Received unknown automount request %i", packet.hdr.type)({ const Unit *_u = (({ typeof(a) _u_ = (a); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal (3, 0, "../src/core/automount.c", 1043, __func__, _u->manager ->unit_log_field, _u->id, _u->manager->invocation_log_field , _u->invocation_id_string, "Received unknown automount request %i" , packet.hdr.type) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/core/automount.c", 1043, __func__, "Received unknown automount request %i" , packet.hdr.type); }); | |||
1044 | break; | |||
1045 | } | |||
1046 | ||||
1047 | return 0; | |||
1048 | ||||
1049 | fail: | |||
1050 | automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); | |||
1051 | return 0; | |||
1052 | } | |||
1053 | ||||
1054 | static void automount_shutdown(Manager *m) { | |||
1055 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/core/automount.c", 1055, __PRETTY_FUNCTION__ ); } while (0); | |||
1056 | ||||
1057 | m->dev_autofs_fd = safe_close(m->dev_autofs_fd); | |||
1058 | } | |||
1059 | ||||
1060 | static void automount_reset_failed(Unit *u) { | |||
1061 | Automount *a = AUTOMOUNT(u); | |||
1062 | ||||
1063 | assert(a)do { if ((__builtin_expect(!!(!(a)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("a"), "../src/core/automount.c", 1063, __PRETTY_FUNCTION__ ); } while (0); | |||
1064 | ||||
1065 | if (a->state == AUTOMOUNT_FAILED) | |||
1066 | automount_set_state(a, AUTOMOUNT_DEAD); | |||
1067 | ||||
1068 | a->result = AUTOMOUNT_SUCCESS; | |||
1069 | } | |||
1070 | ||||
1071 | static bool_Bool automount_supported(void) { | |||
1072 | static int supported = -1; | |||
1073 | ||||
1074 | if (supported < 0) | |||
1075 | supported = access("/dev/autofs", F_OK0) >= 0; | |||
1076 | ||||
1077 | return supported; | |||
1078 | } | |||
1079 | ||||
1080 | static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { | |||
1081 | [AUTOMOUNT_SUCCESS] = "success", | |||
1082 | [AUTOMOUNT_FAILURE_RESOURCES] = "resources", | |||
1083 | [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", | |||
1084 | [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", | |||
1085 | }; | |||
1086 | ||||
1087 | DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult)const char *automount_result_to_string(AutomountResult i) { if (i < 0 || i >= (AutomountResult) __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(automount_result_table ), typeof(&*(automount_result_table))), sizeof(automount_result_table )/sizeof((automount_result_table)[0]), ((void)0)))) return (( void*)0); return automount_result_table[i]; } AutomountResult automount_result_from_string(const char *s) { return (AutomountResult ) string_table_lookup(automount_result_table, __extension__ ( __builtin_choose_expr( !__builtin_types_compatible_p(typeof(automount_result_table ), typeof(&*(automount_result_table))), sizeof(automount_result_table )/sizeof((automount_result_table)[0]), ((void)0))), s); }; | |||
1088 | ||||
1089 | const UnitVTable automount_vtable = { | |||
1090 | .object_size = sizeof(Automount), | |||
1091 | ||||
1092 | .sections = | |||
1093 | "Unit\0" | |||
1094 | "Automount\0" | |||
1095 | "Install\0", | |||
1096 | ||||
1097 | .init = automount_init, | |||
1098 | .load = automount_load, | |||
1099 | .done = automount_done, | |||
1100 | ||||
1101 | .coldplug = automount_coldplug, | |||
1102 | ||||
1103 | .dump = automount_dump, | |||
1104 | ||||
1105 | .start = automount_start, | |||
1106 | .stop = automount_stop, | |||
1107 | ||||
1108 | .serialize = automount_serialize, | |||
1109 | .deserialize_item = automount_deserialize_item, | |||
1110 | ||||
1111 | .active_state = automount_active_state, | |||
1112 | .sub_state_to_string = automount_sub_state_to_string, | |||
1113 | ||||
1114 | .may_gc = automount_may_gc, | |||
1115 | ||||
1116 | .trigger_notify = automount_trigger_notify, | |||
1117 | ||||
1118 | .reset_failed = automount_reset_failed, | |||
1119 | ||||
1120 | .bus_vtable = bus_automount_vtable, | |||
1121 | .bus_set_property = bus_automount_set_property, | |||
1122 | ||||
1123 | .can_transient = true1, | |||
1124 | ||||
1125 | .shutdown = automount_shutdown, | |||
1126 | .supported = automount_supported, | |||
1127 | ||||
1128 | .status_message_formats = { | |||
1129 | .finished_start_job = { | |||
1130 | [JOB_DONE] = "Set up automount %s.", | |||
1131 | [JOB_FAILED] = "Failed to set up automount %s.", | |||
1132 | }, | |||
1133 | .finished_stop_job = { | |||
1134 | [JOB_DONE] = "Unset automount %s.", | |||
1135 | [JOB_FAILED] = "Failed to unset automount %s.", | |||
1136 | }, | |||
1137 | }, | |||
1138 | }; |