Bug Summary

File:build-scan/../src/core/automount.c
Warning:line 678, column 24
Potential leak of memory pointed to by 'data'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name automount.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/core/libcore.a.p -I src/core -I ../src/core -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/libmount -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/core/automount.c
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
36static 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
43struct expire_data {
44 int dev_autofs_fd;
45 int ioctl_fd;
46};
47
48static 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
57DEFINE_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
59static int open_dev_autofs(Manager *m);
60static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
61static int automount_start_expire(Automount *a);
62static void automount_stop_expire(Automount *a);
63static int automount_send_ready(Automount *a, Set *tokens, int status);
64
65static 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
76static 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
101static 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
116static 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
129static 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
141static 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
159static 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
185static 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
201static 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
234static 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
253static 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
292static 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
311static 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
325static 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(&param);
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)))
, &param) < 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
350static 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
376static 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(&param);
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)))
, &param) < 0)
387 return -errno(*__errno_location ());
388
389 major = param.protover.version;
390
391 init_autofs_dev_ioctl(&param);
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)))
, &param) < 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
403static 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(&param);
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)))
, &param) < 0)
419 return -errno(*__errno_location ());
420
421 return 0;
422}
423
424static 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(&param);
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)))
, &param) < 0)
440 return -errno(*__errno_location ());
441
442 return 0;
443}
444
445static 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
487static 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
549static 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
627fail:
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
641static 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(&param);
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)))
, &param);
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
662static 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)
;
1
Taking false branch
2
Loop condition is false. Exiting loop
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)
;
3
Assuming 'source' is equal to field 'expire_event_source'
4
Taking false branch
5
Loop condition is false. Exiting loop
669
670 data = new0(struct expire_data, 1)((struct expire_data*) calloc((1), sizeof(struct expire_data)
))
;
6
Memory is allocated
671 if (!data)
7
Assuming 'data' is non-null
8
Taking false branch
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);
9
'?' condition is true
677 if (data->dev_autofs_fd < 0)
10
Assuming field 'dev_autofs_fd' is < 0
11
Taking true branch
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"); })
;
12
Potential leak of memory pointed to by 'data'
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
693static 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
725static 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
734static 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
788fail:
789 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
790}
791
792static 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
826static 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
836static 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
862static 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
940static 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
946static 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
952static 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
964static 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
1049fail:
1050 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
1051 return 0;
1052}
1053
1054static 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
1060static 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
1071static 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
1080static 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
1087DEFINE_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
1089const 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};