]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/mount.c
core: annotate event sources
[thirdparty/systemd.git] / src / core / mount.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5cb5a6ff 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
5cb5a6ff 22#include <errno.h>
b08d03ff 23#include <stdio.h>
ef734fd6 24#include <sys/epoll.h>
e537352b 25#include <signal.h>
8d3ae2bd 26#include <libmount.h>
befb6d54 27#include <sys/inotify.h>
5cb5a6ff 28
c17ec25e 29#include "manager.h"
87f0e418 30#include "unit.h"
5cb5a6ff 31#include "mount.h"
b08d03ff 32#include "log.h"
20ad4cfd 33#include "sd-messages.h"
e537352b 34#include "strv.h"
49e942b2 35#include "mkdir.h"
9eb977db 36#include "path-util.h"
e537352b 37#include "mount-setup.h"
9e2f7c11 38#include "unit-name.h"
4139c1b2 39#include "dbus-mount.h"
514f4ef5 40#include "special.h"
9a57c629 41#include "exit-status.h"
d15d0333 42#include "fstab-util.h"
6482f626 43#include "formats-util.h"
5cb5a6ff 44
7d54a03a
LP
45#define RETRY_UMOUNT_MAX 32
46
4e920142
ZJS
47DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
48DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
49
f50e0a01
LP
50static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
51 [MOUNT_DEAD] = UNIT_INACTIVE,
52 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
e537352b 53 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
f50e0a01 54 [MOUNT_MOUNTED] = UNIT_ACTIVE,
032ff4af 55 [MOUNT_REMOUNTING] = UNIT_RELOADING,
f50e0a01 56 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
e537352b
LP
57 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
58 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
032ff4af
LP
59 [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
60 [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
e537352b
LP
61 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
62 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
fdf20a31 63 [MOUNT_FAILED] = UNIT_FAILED
f50e0a01 64};
5cb5a6ff 65
718db961
LP
66static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
67static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
68
affc3d83 69static bool mount_needs_network(const char *options, const char *fstype) {
d15d0333 70 if (fstab_test_option(options, "_netdev\0"))
fc676b00
ZJS
71 return true;
72
affc3d83 73 if (fstype && fstype_is_network(fstype))
fc676b00
ZJS
74 return true;
75
76 return false;
77}
78
e6a7b9f4 79static bool mount_is_network(const MountParameters *p) {
affc3d83
CL
80 assert(p);
81
82 return mount_needs_network(p->options, p->fstype);
83}
84
e6a7b9f4 85static bool mount_is_bind(const MountParameters *p) {
fc676b00
ZJS
86 assert(p);
87
d15d0333 88 if (fstab_test_option(p->options, "bind\0" "rbind\0"))
fc676b00
ZJS
89 return true;
90
d15d0333 91 if (p->fstype && STR_IN_SET(p->fstype, "bind", "rbind"))
fc676b00
ZJS
92 return true;
93
94 return false;
95}
96
e6a7b9f4 97static bool mount_is_auto(const MountParameters *p) {
fc676b00
ZJS
98 assert(p);
99
d15d0333 100 return !fstab_test_option(p->options, "noauto\0");
fc676b00
ZJS
101}
102
e6a7b9f4 103static bool needs_quota(const MountParameters *p) {
fc676b00
ZJS
104 assert(p);
105
11041c84 106 /* Quotas are not enabled on network filesystems,
340a1d23 107 * but we want them, for example, on storage connected via iscsi */
11041c84 108 if (p->fstype && fstype_is_network(p->fstype))
fc676b00
ZJS
109 return false;
110
111 if (mount_is_bind(p))
112 return false;
113
d15d0333
ZJS
114 return fstab_test_option(p->options,
115 "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
fc676b00
ZJS
116}
117
a16e1123
LP
118static void mount_init(Unit *u) {
119 Mount *m = MOUNT(u);
5cb5a6ff 120
a16e1123 121 assert(u);
ac155bb8 122 assert(u->load_state == UNIT_STUB);
a16e1123 123
1f19a534 124 m->timeout_usec = u->manager->default_timeout_start_usec;
3e5235b0
LP
125 m->directory_mode = 0755;
126
6b1dc2bd
LP
127 if (unit_has_name(u, "-.mount")) {
128 /* Don't allow start/stop for root directory */
5bcb0f2b
LP
129 u->refuse_manual_start = true;
130 u->refuse_manual_stop = true;
6b1dc2bd
LP
131 } else {
132 /* The stdio/kmsg bridge socket is on /, in order to avoid a
133 * dep loop, don't use kmsg logging for -.mount */
ac155bb8
MS
134 m->exec_context.std_output = u->manager->default_std_output;
135 m->exec_context.std_error = u->manager->default_std_error;
f6cebb3b 136 }
c3686083 137
a16e1123
LP
138 /* We need to make sure that /bin/mount is always called in
139 * the same process group as us, so that the autofs kernel
140 * side doesn't send us another mount request while we are
141 * already trying to comply its last one. */
74922904 142 m->exec_context.same_pgrp = true;
8d567588 143
a16e1123 144 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
c8f4d764 145
5bcb0f2b 146 u->ignore_on_isolate = true;
8d567588
LP
147}
148
718db961
LP
149static int mount_arm_timer(Mount *m) {
150 int r;
151
152 assert(m);
153
154 if (m->timeout_usec <= 0) {
155 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
156 return 0;
157 }
158
159 if (m->timer_event_source) {
160 r = sd_event_source_set_time(m->timer_event_source, now(CLOCK_MONOTONIC) + m->timeout_usec);
161 if (r < 0)
162 return r;
163
164 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
165 }
166
7dfbe2e3 167 r = sd_event_add_time(
6a0f1f6d
LP
168 UNIT(m)->manager->event,
169 &m->timer_event_source,
170 CLOCK_MONOTONIC,
171 now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
172 mount_dispatch_timer, m);
7dfbe2e3
TG
173 if (r < 0)
174 return r;
175
176 (void) sd_event_source_set_description(m->timer_event_source, "mount-timer");
177
178 return 0;
718db961
LP
179}
180
a16e1123 181static void mount_unwatch_control_pid(Mount *m) {
5e94833f
LP
182 assert(m);
183
184 if (m->control_pid <= 0)
185 return;
186
187 unit_unwatch_pid(UNIT(m), m->control_pid);
188 m->control_pid = 0;
189}
190
e537352b
LP
191static void mount_parameters_done(MountParameters *p) {
192 assert(p);
193
194 free(p->what);
195 free(p->options);
196 free(p->fstype);
197
198 p->what = p->options = p->fstype = NULL;
199}
200
87f0e418 201static void mount_done(Unit *u) {
ef734fd6 202 Mount *m = MOUNT(u);
034c6ed7 203
ef734fd6 204 assert(m);
034c6ed7 205
e537352b
LP
206 free(m->where);
207 m->where = NULL;
f50e0a01 208
e537352b
LP
209 mount_parameters_done(&m->parameters_proc_self_mountinfo);
210 mount_parameters_done(&m->parameters_fragment);
ef734fd6 211
613b411c 212 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
e537352b
LP
213 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
214 m->control_command = NULL;
f50e0a01 215
a16e1123 216 mount_unwatch_control_pid(m);
f50e0a01 217
718db961 218 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
f50e0a01
LP
219}
220
44a6b1b6 221_pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
cb39ed3f
LP
222 assert(m);
223
224 if (m->from_fragment)
225 return &m->parameters_fragment;
cb39ed3f
LP
226
227 return NULL;
228}
229
44a6b1b6 230_pure_ static MountParameters* get_mount_parameters(Mount *m) {
cb39ed3f
LP
231 assert(m);
232
233 if (m->from_proc_self_mountinfo)
234 return &m->parameters_proc_self_mountinfo;
235
6b1dc2bd 236 return get_mount_parameters_fragment(m);
cb39ed3f
LP
237}
238
6e2ef85b 239static int mount_add_mount_links(Mount *m) {
a57f7e2c 240 _cleanup_free_ char *parent = NULL;
5c78d8e2 241 MountParameters *pm;
ac155bb8 242 Unit *other;
a57f7e2c
LP
243 Iterator i;
244 Set *s;
b08d03ff
LP
245 int r;
246
6e2ef85b 247 assert(m);
b08d03ff 248
a57f7e2c
LP
249 if (!path_equal(m->where, "/")) {
250 /* Adds in links to other mount points that might lie further
251 * up in the hierarchy */
252 r = path_get_parent(m->where, &parent);
4f0eedb7 253 if (r < 0)
6e2ef85b 254 return r;
01f78473 255
a57f7e2c 256 r = unit_require_mounts_for(UNIT(m), parent);
4f0eedb7 257 if (r < 0)
01f78473 258 return r;
4f0eedb7 259 }
01f78473 260
a57f7e2c
LP
261 /* Adds in links to other mount points that might be needed
262 * for the source path (if this is a bind mount) to be
263 * available. */
264 pm = get_mount_parameters_fragment(m);
fc676b00
ZJS
265 if (pm && pm->what &&
266 path_is_absolute(pm->what) &&
267 !mount_is_network(pm)) {
268
a57f7e2c 269 r = unit_require_mounts_for(UNIT(m), pm->what);
4f0eedb7 270 if (r < 0)
6e2ef85b 271 return r;
4f0eedb7 272 }
b08d03ff 273
a57f7e2c
LP
274 /* Adds in links to other units that use this path or paths
275 * further down in the hierarchy */
276 s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
277 SET_FOREACH(other, s, i) {
b08d03ff 278
a57f7e2c
LP
279 if (other->load_state != UNIT_LOADED)
280 continue;
b08d03ff 281
a57f7e2c
LP
282 if (other == UNIT(m))
283 continue;
b08d03ff 284
a57f7e2c 285 r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
4f0eedb7 286 if (r < 0)
6e2ef85b 287 return r;
b08d03ff 288
a57f7e2c
LP
289 if (UNIT(m)->fragment_path) {
290 /* If we have fragment configuration, then make this dependency required */
291 r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
292 if (r < 0)
293 return r;
294 }
7c8fa05c
LP
295 }
296
297 return 0;
298}
299
173a8d04
LP
300static int mount_add_device_links(Mount *m) {
301 MountParameters *p;
5073f89f 302 bool device_wants_mount = false;
9fff8a1f 303 int r;
173a8d04
LP
304
305 assert(m);
306
06e97888 307 p = get_mount_parameters(m);
6b1dc2bd 308 if (!p)
173a8d04
LP
309 return 0;
310
9fff8a1f 311 if (!p->what)
173a8d04 312 return 0;
5c78d8e2 313
dd144c63
LP
314 if (mount_is_bind(p))
315 return 0;
316
317 if (!is_device_path(p->what))
318 return 0;
319
320 if (path_equal(m->where, "/"))
321 return 0;
322
5073f89f
TG
323 if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
324 device_wants_mount = true;
325
326 r = unit_add_node_link(UNIT(m), p->what, device_wants_mount);
dd144c63
LP
327 if (r < 0)
328 return r;
9fff8a1f 329
9fff8a1f 330 return 0;
173a8d04
LP
331}
332
6b1dc2bd
LP
333static int mount_add_quota_links(Mount *m) {
334 int r;
335 MountParameters *p;
336
337 assert(m);
338
67445f4e 339 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
6b1dc2bd
LP
340 return 0;
341
342 p = get_mount_parameters_fragment(m);
343 if (!p)
344 return 0;
345
346 if (!needs_quota(p))
347 return 0;
348
349 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
350 if (r < 0)
351 return r;
352
353 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
354 if (r < 0)
355 return r;
356
357 return 0;
358}
359
88ac30a1
TG
360static bool should_umount(Mount *m) {
361 MountParameters *p;
362
363 if (path_equal(m->where, "/") ||
364 path_equal(m->where, "/usr"))
365 return false;
366
367 p = get_mount_parameters(m);
d15d0333 368 if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
88ac30a1
TG
369 !in_initrd())
370 return false;
371
372 return true;
373}
374
2edd4434 375static int mount_add_default_dependencies(Mount *m) {
0c17fbce 376 const char *after, *after2, *online;
9ddc4a26 377 MountParameters *p;
0c17fbce 378 int r;
2edd4434
LP
379
380 assert(m);
381
67445f4e 382 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
9ddc4a26 383 return 0;
cb39ed3f 384
874d3404
LP
385 /* We do not add any default dependencies to / and /usr, since
386 * they are guaranteed to stay mounted the whole time, since
387 * our system is on it. Also, don't bother with anything
388 * mounted below virtual file systems, it's also going to be
389 * virtual, and hence not worth the effort. */
390 if (path_equal(m->where, "/") ||
391 path_equal(m->where, "/usr") ||
392 path_startswith(m->where, "/proc") ||
393 path_startswith(m->where, "/sys") ||
394 path_startswith(m->where, "/dev"))
6b1dc2bd 395 return 0;
2edd4434 396
874d3404
LP
397 p = get_mount_parameters(m);
398 if (!p)
6b1dc2bd
LP
399 return 0;
400
e8d2f6cd 401 if (mount_is_network(p)) {
6b1dc2bd 402 after = SPECIAL_REMOTE_FS_PRE_TARGET;
a63a5c46 403 after2 = SPECIAL_NETWORK_TARGET;
0c17fbce 404 online = SPECIAL_NETWORK_ONLINE_TARGET;
e8d2f6cd 405 } else {
6b1dc2bd 406 after = SPECIAL_LOCAL_FS_PRE_TARGET;
a63a5c46 407 after2 = NULL;
0c17fbce 408 online = NULL;
e8d2f6cd 409 }
6b1dc2bd 410
e8d2f6cd 411 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
6b1dc2bd
LP
412 if (r < 0)
413 return r;
414
a63a5c46
LP
415 if (after2) {
416 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
417 if (r < 0)
418 return r;
419 }
420
0c17fbce
LP
421 if (online) {
422 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
e8d2f6cd
LP
423 if (r < 0)
424 return r;
425 }
426
88ac30a1
TG
427 if (should_umount(m)) {
428 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
429 if (r < 0)
430 return r;
431 }
2edd4434
LP
432
433 return 0;
434}
435
8d567588 436static int mount_verify(Mount *m) {
a57f7e2c 437 _cleanup_free_ char *e = NULL;
8d567588 438 bool b;
a57f7e2c 439
8d567588
LP
440 assert(m);
441
1124fe6f 442 if (UNIT(m)->load_state != UNIT_LOADED)
8d567588
LP
443 return 0;
444
6b1dc2bd 445 if (!m->from_fragment && !m->from_proc_self_mountinfo)
8cbef760
LP
446 return -ENOENT;
447
a57f7e2c
LP
448 e = unit_name_from_path(m->where, ".mount");
449 if (!e)
8d567588
LP
450 return -ENOMEM;
451
452 b = unit_has_name(UNIT(m), e);
8d567588 453 if (!b) {
79008bdd 454 log_unit_error(UNIT(m)->id, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m)->id);
8d567588
LP
455 return -EINVAL;
456 }
457
33ff02c9 458 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
79008bdd 459 log_unit_error(UNIT(m)->id, "Cannot create mount unit for API file system %s. Refusing.", m->where);
33ff02c9
LP
460 return -EINVAL;
461 }
462
1124fe6f 463 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
79008bdd 464 log_unit_error(UNIT(m)->id, "%s's What setting is missing. Refusing.", UNIT(m)->id);
4e85aff4
LP
465 return -EBADMSG;
466 }
467
4819ff03 468 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
79008bdd 469 log_unit_error(UNIT(m)->id, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m)->id);
4d0e5dbd
LP
470 return -EINVAL;
471 }
472
8d567588
LP
473 return 0;
474}
475
1a4ac875
MS
476static int mount_add_extras(Mount *m) {
477 Unit *u = UNIT(m);
e537352b
LP
478 int r;
479
e821075a
LP
480 assert(m);
481
482 if (u->fragment_path)
1a4ac875 483 m->from_fragment = true;
e537352b 484
1a4ac875
MS
485 if (!m->where) {
486 m->where = unit_name_to_path(u->id);
a16e1123 487 if (!m->where)
1a4ac875
MS
488 return -ENOMEM;
489 }
a16e1123 490
1a4ac875 491 path_kill_slashes(m->where);
e537352b 492
e821075a 493 if (!u->description) {
1a4ac875
MS
494 r = unit_set_description(u, m->where);
495 if (r < 0)
173a8d04 496 return r;
1a4ac875 497 }
6e2ef85b 498
1a4ac875
MS
499 r = mount_add_device_links(m);
500 if (r < 0)
501 return r;
6e2ef85b 502
1a4ac875
MS
503 r = mount_add_mount_links(m);
504 if (r < 0)
505 return r;
6e2ef85b 506
1a4ac875
MS
507 r = mount_add_quota_links(m);
508 if (r < 0)
509 return r;
e537352b 510
598459ce
LP
511 r = unit_patch_contexts(u);
512 if (r < 0)
513 return r;
4e67ddd6 514
598459ce 515 r = unit_add_exec_dependencies(u, &m->exec_context);
a016b922
LP
516 if (r < 0)
517 return r;
518
598459ce 519 r = unit_add_default_slice(u, &m->cgroup_context);
1a4ac875
MS
520 if (r < 0)
521 return r;
522
598459ce
LP
523 if (u->default_dependencies) {
524 r = mount_add_default_dependencies(m);
525 if (r < 0)
526 return r;
527 }
528
1a4ac875
MS
529 return 0;
530}
531
532static int mount_load(Unit *u) {
533 Mount *m = MOUNT(u);
534 int r;
535
536 assert(u);
537 assert(u->load_state == UNIT_STUB);
538
8eba616f
MS
539 if (m->from_proc_self_mountinfo)
540 r = unit_load_fragment_and_dropin_optional(u);
541 else
542 r = unit_load_fragment_and_dropin(u);
543
1a4ac875
MS
544 if (r < 0)
545 return r;
155da457 546
1a4ac875
MS
547 /* This is a new unit? Then let's add in some extras */
548 if (u->load_state == UNIT_LOADED) {
549 r = mount_add_extras(m);
550 if (r < 0)
551 return r;
e537352b
LP
552 }
553
8d567588 554 return mount_verify(m);
e537352b
LP
555}
556
deb0a77c 557static int mount_notify_automount(Mount *m, MountState old_state, MountState state) {
a16e1123
LP
558 Unit *p;
559 int r;
57020a3a 560 Iterator i;
a16e1123
LP
561
562 assert(m);
563
1124fe6f 564 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
ac155bb8 565 if (p->type == UNIT_AUTOMOUNT) {
deb0a77c 566 r = automount_update_mount(AUTOMOUNT(p), old_state, state);
57020a3a
LP
567 if (r < 0)
568 return r;
569 }
a16e1123 570
57020a3a 571 return 0;
a16e1123
LP
572}
573
e537352b
LP
574static void mount_set_state(Mount *m, MountState state) {
575 MountState old_state;
576 assert(m);
577
578 old_state = m->state;
579 m->state = state;
580
581 if (state != MOUNT_MOUNTING &&
582 state != MOUNT_MOUNTING_DONE &&
583 state != MOUNT_REMOUNTING &&
584 state != MOUNT_UNMOUNTING &&
585 state != MOUNT_MOUNTING_SIGTERM &&
586 state != MOUNT_MOUNTING_SIGKILL &&
587 state != MOUNT_UNMOUNTING_SIGTERM &&
588 state != MOUNT_UNMOUNTING_SIGKILL &&
589 state != MOUNT_REMOUNTING_SIGTERM &&
590 state != MOUNT_REMOUNTING_SIGKILL) {
718db961 591 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
a16e1123 592 mount_unwatch_control_pid(m);
e537352b 593 m->control_command = NULL;
a16e1123 594 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
e537352b
LP
595 }
596
deb0a77c 597 mount_notify_automount(m, old_state, state);
8d567588 598
e537352b 599 if (state != old_state)
79008bdd 600 log_unit_debug(UNIT(m)->id,
66870f90
ZJS
601 "%s changed %s -> %s",
602 UNIT(m)->id,
603 mount_state_to_string(old_state),
604 mount_state_to_string(state));
e537352b 605
9d2f5178
LP
606 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
607 m->reload_result = MOUNT_SUCCESS;
e537352b
LP
608}
609
be847e82 610static int mount_coldplug(Unit *u) {
e537352b 611 Mount *m = MOUNT(u);
a16e1123
LP
612 MountState new_state = MOUNT_DEAD;
613 int r;
e537352b
LP
614
615 assert(m);
616 assert(m->state == MOUNT_DEAD);
617
a16e1123
LP
618 if (m->deserialized_state != m->state)
619 new_state = m->deserialized_state;
620 else if (m->from_proc_self_mountinfo)
621 new_state = MOUNT_MOUNTED;
e537352b 622
5bcb0f2b
LP
623 if (new_state == m->state)
624 return 0;
e537352b 625
5bcb0f2b
LP
626 if (new_state == MOUNT_MOUNTING ||
627 new_state == MOUNT_MOUNTING_DONE ||
628 new_state == MOUNT_REMOUNTING ||
629 new_state == MOUNT_UNMOUNTING ||
630 new_state == MOUNT_MOUNTING_SIGTERM ||
631 new_state == MOUNT_MOUNTING_SIGKILL ||
632 new_state == MOUNT_UNMOUNTING_SIGTERM ||
633 new_state == MOUNT_UNMOUNTING_SIGKILL ||
634 new_state == MOUNT_REMOUNTING_SIGTERM ||
635 new_state == MOUNT_REMOUNTING_SIGKILL) {
636
637 if (m->control_pid <= 0)
638 return -EBADMSG;
639
640 r = unit_watch_pid(UNIT(m), m->control_pid);
641 if (r < 0)
642 return r;
e537352b 643
5bcb0f2b
LP
644 r = mount_arm_timer(m);
645 if (r < 0)
646 return r;
a16e1123 647 }
e537352b 648
5bcb0f2b 649 mount_set_state(m, new_state);
e537352b 650 return 0;
e537352b
LP
651}
652
653static void mount_dump(Unit *u, FILE *f, const char *prefix) {
654 Mount *m = MOUNT(u);
655 MountParameters *p;
656
657 assert(m);
658 assert(f);
659
cb39ed3f 660 p = get_mount_parameters(m);
e537352b
LP
661
662 fprintf(f,
663 "%sMount State: %s\n"
81a5c6d0 664 "%sResult: %s\n"
e537352b
LP
665 "%sWhere: %s\n"
666 "%sWhat: %s\n"
667 "%sFile System Type: %s\n"
668 "%sOptions: %s\n"
e537352b
LP
669 "%sFrom /proc/self/mountinfo: %s\n"
670 "%sFrom fragment: %s\n"
3e5235b0 671 "%sDirectoryMode: %04o\n",
a16e1123 672 prefix, mount_state_to_string(m->state),
81a5c6d0 673 prefix, mount_result_to_string(m->result),
e537352b 674 prefix, m->where,
1e4fc9b1
HH
675 prefix, p ? strna(p->what) : "n/a",
676 prefix, p ? strna(p->fstype) : "n/a",
677 prefix, p ? strna(p->options) : "n/a",
e537352b
LP
678 prefix, yes_no(m->from_proc_self_mountinfo),
679 prefix, yes_no(m->from_fragment),
3e5235b0 680 prefix, m->directory_mode);
e537352b
LP
681
682 if (m->control_pid > 0)
683 fprintf(f,
ccd06097
ZJS
684 "%sControl PID: "PID_FMT"\n",
685 prefix, m->control_pid);
e537352b
LP
686
687 exec_context_dump(&m->exec_context, f, prefix);
4819ff03 688 kill_context_dump(&m->kill_context, f, prefix);
e537352b
LP
689}
690
a16e1123
LP
691static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
692 pid_t pid;
693 int r;
9fa95f85
DM
694 ExecParameters exec_params = {
695 .apply_permissions = true,
696 .apply_chroot = true,
697 .apply_tty_stdin = true,
698 };
a16e1123
LP
699
700 assert(m);
701 assert(c);
702 assert(_pid);
703
5ad096b3
LP
704 (void) unit_realize_cgroup(UNIT(m));
705 if (m->reset_cpu_usage) {
706 (void) unit_reset_cpu_usage(UNIT(m));
707 m->reset_cpu_usage = false;
708 }
4ad49000 709
613b411c
LP
710 r = unit_setup_exec_runtime(UNIT(m));
711 if (r < 0)
712 goto fail;
713
718db961 714 r = mount_arm_timer(m);
36697dc0 715 if (r < 0)
a16e1123
LP
716 goto fail;
717
9fa95f85
DM
718 exec_params.environment = UNIT(m)->manager->environment;
719 exec_params.confirm_spawn = UNIT(m)->manager->confirm_spawn;
720 exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
721 exec_params.cgroup_path = UNIT(m)->cgroup_path;
a931ad47 722 exec_params.cgroup_delegate = m->cgroup_context.delegate;
9fa95f85
DM
723 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(m)->manager);
724 exec_params.unit_id = UNIT(m)->id;
725
4ad49000 726 r = exec_spawn(c,
4ad49000 727 &m->exec_context,
9fa95f85 728 &exec_params,
613b411c 729 m->exec_runtime,
4ad49000
LP
730 &pid);
731 if (r < 0)
a16e1123
LP
732 goto fail;
733
4ad49000
LP
734 r = unit_watch_pid(UNIT(m), pid);
735 if (r < 0)
a16e1123
LP
736 /* FIXME: we need to do something here */
737 goto fail;
738
739 *_pid = pid;
740
741 return 0;
742
743fail:
718db961 744 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
a16e1123
LP
745
746 return r;
747}
748
9d2f5178 749static void mount_enter_dead(Mount *m, MountResult f) {
e537352b
LP
750 assert(m);
751
9d2f5178
LP
752 if (f != MOUNT_SUCCESS)
753 m->result = f;
e537352b 754
613b411c
LP
755 exec_runtime_destroy(m->exec_runtime);
756 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
757
e66cf1a3
LP
758 exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
759
9d2f5178 760 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
e537352b
LP
761}
762
9d2f5178 763static void mount_enter_mounted(Mount *m, MountResult f) {
80876c20
LP
764 assert(m);
765
9d2f5178
LP
766 if (f != MOUNT_SUCCESS)
767 m->result = f;
80876c20
LP
768
769 mount_set_state(m, MOUNT_MOUNTED);
770}
771
9d2f5178 772static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
e537352b
LP
773 int r;
774
775 assert(m);
776
9d2f5178
LP
777 if (f != MOUNT_SUCCESS)
778 m->result = f;
e537352b 779
cd2086fe
LP
780 r = unit_kill_context(
781 UNIT(m),
782 &m->kill_context,
db2cb23b
UTL
783 (state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM) ?
784 KILL_KILL : KILL_TERMINATE,
cd2086fe
LP
785 -1,
786 m->control_pid,
787 false);
788 if (r < 0)
789 goto fail;
e537352b 790
cd2086fe 791 if (r > 0) {
718db961 792 r = mount_arm_timer(m);
36697dc0 793 if (r < 0)
80876c20 794 goto fail;
e537352b 795
80876c20 796 mount_set_state(m, state);
ac84d1fb
LP
797 } else if (state == MOUNT_REMOUNTING_SIGTERM)
798 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
799 else if (state == MOUNT_REMOUNTING_SIGKILL)
9d2f5178 800 mount_enter_mounted(m, MOUNT_SUCCESS);
ac84d1fb
LP
801 else if (state == MOUNT_MOUNTING_SIGTERM)
802 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS);
803 else if (state == MOUNT_UNMOUNTING_SIGTERM)
804 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
80876c20 805 else
9d2f5178 806 mount_enter_dead(m, MOUNT_SUCCESS);
e537352b
LP
807
808 return;
809
810fail:
79008bdd 811 log_unit_warning(UNIT(m)->id,
66870f90 812 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
e537352b 813
80876c20 814 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
9d2f5178 815 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
80876c20 816 else
9d2f5178 817 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
818}
819
20ad4cfd 820void warn_if_dir_nonempty(const char *unit, const char* where) {
056edeb9
ZJS
821 int r;
822
cd2086fe
LP
823 assert(unit);
824 assert(where);
825
056edeb9
ZJS
826 r = dir_is_empty(where);
827 if (r > 0)
20ad4cfd 828 return;
056edeb9 829 else if (r == 0)
e2cc6eca
LP
830 log_unit_struct(unit,
831 LOG_NOTICE,
832 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
833 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
834 unit, where),
056edeb9 835 "WHERE=%s", where,
056edeb9
ZJS
836 NULL);
837 else
79008bdd 838 log_unit_warning(unit,
056edeb9
ZJS
839 "MESSAGE=Failed to check directory %s: %s",
840 where, strerror(-r));
20ad4cfd
ZJS
841}
842
5261ba90
TT
843static int fail_if_symlink(const char *unit, const char* where) {
844 assert(where);
845
846 if (is_symlink(where) > 0) {
e2cc6eca
LP
847 log_unit_struct(unit,
848 LOG_ERR,
849 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
850 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
851 unit, where),
5261ba90 852 "WHERE=%s", where,
5261ba90
TT
853 NULL);
854
855 return -ELOOP;
856 }
857 return 0;
858}
859
9d2f5178 860static void mount_enter_unmounting(Mount *m) {
e537352b
LP
861 int r;
862
863 assert(m);
864
7d54a03a
LP
865 /* Start counting our attempts */
866 if (!IN_SET(m->state,
867 MOUNT_UNMOUNTING,
868 MOUNT_UNMOUNTING_SIGTERM,
869 MOUNT_UNMOUNTING_SIGKILL))
870 m->n_retry_umount = 0;
871
a16e1123
LP
872 m->control_command_id = MOUNT_EXEC_UNMOUNT;
873 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
e537352b 874
e86b3761
ZJS
875 r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
876 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
877 r = exec_command_append(m->control_command, "-n", NULL);
7d54a03a 878 if (r < 0)
e537352b
LP
879 goto fail;
880
a16e1123 881 mount_unwatch_control_pid(m);
5e94833f 882
7d54a03a
LP
883 r = mount_spawn(m, m->control_command, &m->control_pid);
884 if (r < 0)
e537352b
LP
885 goto fail;
886
887 mount_set_state(m, MOUNT_UNMOUNTING);
888
889 return;
890
891fail:
79008bdd 892 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
893 "%s failed to run 'umount' task: %s",
894 UNIT(m)->id, strerror(-r));
9d2f5178 895 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
896}
897
8d567588 898static void mount_enter_mounting(Mount *m) {
e537352b 899 int r;
cb39ed3f 900 MountParameters *p;
e537352b
LP
901
902 assert(m);
903
a16e1123
LP
904 m->control_command_id = MOUNT_EXEC_MOUNT;
905 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
e537352b 906
d2e54fae 907 mkdir_p_label(m->where, m->directory_mode);
3e5235b0 908
20ad4cfd 909 warn_if_dir_nonempty(m->meta.id, m->where);
257f1d8e 910
cb39ed3f 911 /* Create the source directory for bind-mounts if needed */
6b1dc2bd 912 p = get_mount_parameters_fragment(m);
cb39ed3f 913 if (p && mount_is_bind(p))
d2e54fae 914 mkdir_p_label(p->what, m->directory_mode);
2b583ce6 915
5261ba90
TT
916 r = fail_if_symlink(m->meta.id, m->where);
917 if (r < 0)
918 goto fail;
919
e86b3761 920 if (m->from_fragment) {
17a1c597
ZJS
921 _cleanup_free_ char *opts = NULL;
922
923 r = fstab_filter_options(m->parameters_fragment.options,
76c37ab6 924 "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
17a1c597
ZJS
925 if (r < 0)
926 goto fail;
927
e86b3761
ZJS
928 r = exec_command_set(m->control_command, "/bin/mount",
929 m->parameters_fragment.what, m->where, NULL);
930 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
931 r = exec_command_append(m->control_command, "-n", NULL);
932 if (r >= 0 && m->sloppy_options)
933 r = exec_command_append(m->control_command, "-s", NULL);
934 if (r >= 0 && m->parameters_fragment.fstype)
935 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
0c47569a 936 if (r >= 0 && !isempty(opts))
17a1c597 937 r = exec_command_append(m->control_command, "-o", opts, NULL);
e86b3761 938 } else
e537352b
LP
939 r = -ENOENT;
940
941 if (r < 0)
942 goto fail;
943
a16e1123 944 mount_unwatch_control_pid(m);
5e94833f 945
257f1d8e
LP
946 r = mount_spawn(m, m->control_command, &m->control_pid);
947 if (r < 0)
e537352b
LP
948 goto fail;
949
950 mount_set_state(m, MOUNT_MOUNTING);
951
952 return;
953
954fail:
79008bdd 955 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
956 "%s failed to run 'mount' task: %s",
957 UNIT(m)->id, strerror(-r));
9d2f5178 958 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
959}
960
9d2f5178 961static void mount_enter_remounting(Mount *m) {
e537352b
LP
962 int r;
963
964 assert(m);
965
a16e1123
LP
966 m->control_command_id = MOUNT_EXEC_REMOUNT;
967 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
e537352b
LP
968
969 if (m->from_fragment) {
e537352b
LP
970 const char *o;
971
718db961 972 if (m->parameters_fragment.options)
63c372cb 973 o = strjoina("remount,", m->parameters_fragment.options);
718db961 974 else
e537352b
LP
975 o = "remount";
976
e86b3761
ZJS
977 r = exec_command_set(m->control_command, "/bin/mount",
978 m->parameters_fragment.what, m->where,
979 "-o", o, NULL);
980 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
981 r = exec_command_append(m->control_command, "-n", NULL);
982 if (r >= 0 && m->sloppy_options)
983 r = exec_command_append(m->control_command, "-s", NULL);
984 if (r >= 0 && m->parameters_fragment.fstype)
985 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
6b1dc2bd 986 } else
e537352b
LP
987 r = -ENOENT;
988
60b912f6 989 if (r < 0)
e537352b 990 goto fail;
e537352b 991
a16e1123 992 mount_unwatch_control_pid(m);
5e94833f 993
718db961
LP
994 r = mount_spawn(m, m->control_command, &m->control_pid);
995 if (r < 0)
e537352b
LP
996 goto fail;
997
998 mount_set_state(m, MOUNT_REMOUNTING);
999
1000 return;
1001
1002fail:
79008bdd 1003 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
1004 "%s failed to run 'remount' task: %s",
1005 UNIT(m)->id, strerror(-r));
9d2f5178
LP
1006 m->reload_result = MOUNT_FAILURE_RESOURCES;
1007 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
1008}
1009
1010static int mount_start(Unit *u) {
1011 Mount *m = MOUNT(u);
1012
1013 assert(m);
1014
1015 /* We cannot fulfill this request right now, try again later
1016 * please! */
1017 if (m->state == MOUNT_UNMOUNTING ||
1018 m->state == MOUNT_UNMOUNTING_SIGTERM ||
60b912f6
LP
1019 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1020 m->state == MOUNT_MOUNTING_SIGTERM ||
1021 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
1022 return -EAGAIN;
1023
1024 /* Already on it! */
60b912f6 1025 if (m->state == MOUNT_MOUNTING)
e537352b
LP
1026 return 0;
1027
fdf20a31 1028 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
e537352b 1029
9d2f5178
LP
1030 m->result = MOUNT_SUCCESS;
1031 m->reload_result = MOUNT_SUCCESS;
5ad096b3 1032 m->reset_cpu_usage = true;
9d2f5178 1033
8d567588 1034 mount_enter_mounting(m);
82a2b6bb 1035 return 1;
e537352b
LP
1036}
1037
1038static int mount_stop(Unit *u) {
1039 Mount *m = MOUNT(u);
1040
1041 assert(m);
1042
e537352b
LP
1043 /* Already on it */
1044 if (m->state == MOUNT_UNMOUNTING ||
1045 m->state == MOUNT_UNMOUNTING_SIGKILL ||
60b912f6
LP
1046 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1047 m->state == MOUNT_MOUNTING_SIGTERM ||
1048 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
1049 return 0;
1050
3f6c78dc
LP
1051 assert(m->state == MOUNT_MOUNTING ||
1052 m->state == MOUNT_MOUNTING_DONE ||
1053 m->state == MOUNT_MOUNTED ||
3f6c78dc
LP
1054 m->state == MOUNT_REMOUNTING ||
1055 m->state == MOUNT_REMOUNTING_SIGTERM ||
1056 m->state == MOUNT_REMOUNTING_SIGKILL);
e537352b 1057
9d2f5178 1058 mount_enter_unmounting(m);
82a2b6bb 1059 return 1;
e537352b
LP
1060}
1061
1062static int mount_reload(Unit *u) {
1063 Mount *m = MOUNT(u);
1064
1065 assert(m);
1066
1067 if (m->state == MOUNT_MOUNTING_DONE)
1068 return -EAGAIN;
1069
1070 assert(m->state == MOUNT_MOUNTED);
1071
9d2f5178 1072 mount_enter_remounting(m);
e537352b
LP
1073 return 0;
1074}
1075
a16e1123
LP
1076static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1077 Mount *m = MOUNT(u);
1078
1079 assert(m);
1080 assert(f);
1081 assert(fds);
1082
1083 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
9d2f5178
LP
1084 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1085 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
a16e1123
LP
1086
1087 if (m->control_pid > 0)
ccd06097 1088 unit_serialize_item_format(u, f, "control-pid", PID_FMT, m->control_pid);
a16e1123
LP
1089
1090 if (m->control_command_id >= 0)
1091 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1092
1093 return 0;
1094}
1095
1096static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1097 Mount *m = MOUNT(u);
a16e1123
LP
1098
1099 assert(u);
1100 assert(key);
1101 assert(value);
1102 assert(fds);
1103
1104 if (streq(key, "state")) {
1105 MountState state;
1106
1107 if ((state = mount_state_from_string(value)) < 0)
79008bdd 1108 log_unit_debug(u->id, "Failed to parse state value %s", value);
a16e1123
LP
1109 else
1110 m->deserialized_state = state;
9d2f5178
LP
1111 } else if (streq(key, "result")) {
1112 MountResult f;
a16e1123 1113
9d2f5178
LP
1114 f = mount_result_from_string(value);
1115 if (f < 0)
79008bdd 1116 log_unit_debug(UNIT(m)->id,
66870f90 1117 "Failed to parse result value %s", value);
9d2f5178
LP
1118 else if (f != MOUNT_SUCCESS)
1119 m->result = f;
1120
1121 } else if (streq(key, "reload-result")) {
1122 MountResult f;
1123
1124 f = mount_result_from_string(value);
1125 if (f < 0)
79008bdd 1126 log_unit_debug(UNIT(m)->id,
66870f90 1127 "Failed to parse reload result value %s", value);
9d2f5178
LP
1128 else if (f != MOUNT_SUCCESS)
1129 m->reload_result = f;
a16e1123
LP
1130
1131 } else if (streq(key, "control-pid")) {
5925dd3c 1132 pid_t pid;
a16e1123 1133
e364ad06 1134 if (parse_pid(value, &pid) < 0)
79008bdd 1135 log_unit_debug(UNIT(m)->id,
66870f90 1136 "Failed to parse control-pid value %s", value);
a16e1123 1137 else
5925dd3c 1138 m->control_pid = pid;
a16e1123
LP
1139 } else if (streq(key, "control-command")) {
1140 MountExecCommand id;
1141
1142 if ((id = mount_exec_command_from_string(value)) < 0)
79008bdd 1143 log_unit_debug(UNIT(m)->id,
66870f90 1144 "Failed to parse exec-command value %s", value);
a16e1123
LP
1145 else {
1146 m->control_command_id = id;
1147 m->control_command = m->exec_command + id;
1148 }
a16e1123 1149 } else
79008bdd 1150 log_unit_debug(UNIT(m)->id,
66870f90 1151 "Unknown serialization key '%s'", key);
a16e1123
LP
1152
1153 return 0;
1154}
1155
44a6b1b6 1156_pure_ static UnitActiveState mount_active_state(Unit *u) {
e537352b
LP
1157 assert(u);
1158
1159 return state_translation_table[MOUNT(u)->state];
1160}
1161
44a6b1b6 1162_pure_ static const char *mount_sub_state_to_string(Unit *u) {
10a94420
LP
1163 assert(u);
1164
a16e1123 1165 return mount_state_to_string(MOUNT(u)->state);
10a94420
LP
1166}
1167
44a6b1b6 1168_pure_ static bool mount_check_gc(Unit *u) {
701cc384
LP
1169 Mount *m = MOUNT(u);
1170
1171 assert(m);
1172
6b1dc2bd 1173 return m->from_proc_self_mountinfo;
701cc384
LP
1174}
1175
e537352b
LP
1176static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1177 Mount *m = MOUNT(u);
9d2f5178 1178 MountResult f;
e537352b
LP
1179
1180 assert(m);
1181 assert(pid >= 0);
1182
8c47c732
LP
1183 if (pid != m->control_pid)
1184 return;
e537352b 1185
e537352b
LP
1186 m->control_pid = 0;
1187
96342de6 1188 if (is_clean_exit(code, status, NULL))
9d2f5178
LP
1189 f = MOUNT_SUCCESS;
1190 else if (code == CLD_EXITED)
1191 f = MOUNT_FAILURE_EXIT_CODE;
1192 else if (code == CLD_KILLED)
1193 f = MOUNT_FAILURE_SIGNAL;
1194 else if (code == CLD_DUMPED)
1195 f = MOUNT_FAILURE_CORE_DUMP;
1196 else
1197 assert_not_reached("Unknown code");
1198
1199 if (f != MOUNT_SUCCESS)
1200 m->result = f;
8c47c732 1201
a16e1123 1202 if (m->control_command) {
6ea832a2 1203 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
9d2f5178 1204
a16e1123
LP
1205 m->control_command = NULL;
1206 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1207 }
1208
79008bdd
LP
1209 log_unit_full(u->id,
1210 f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
66870f90
ZJS
1211 "%s mount process exited, code=%s status=%i",
1212 u->id, sigchld_code_to_string(code), status);
e537352b
LP
1213
1214 /* Note that mount(8) returning and the kernel sending us a
1215 * mount table change event might happen out-of-order. If an
1216 * operation succeed we assume the kernel will follow soon too
1217 * and already change into the resulting state. If it fails
1218 * we check if the kernel still knows about the mount. and
1219 * change state accordingly. */
1220
1221 switch (m->state) {
1222
1223 case MOUNT_MOUNTING:
1224 case MOUNT_MOUNTING_DONE:
1225 case MOUNT_MOUNTING_SIGKILL:
1226 case MOUNT_MOUNTING_SIGTERM:
e537352b 1227
9d2f5178
LP
1228 if (f == MOUNT_SUCCESS)
1229 mount_enter_mounted(m, f);
e537352b 1230 else if (m->from_proc_self_mountinfo)
9d2f5178 1231 mount_enter_mounted(m, f);
e537352b 1232 else
9d2f5178 1233 mount_enter_dead(m, f);
e537352b
LP
1234 break;
1235
e2f3b44c
LP
1236 case MOUNT_REMOUNTING:
1237 case MOUNT_REMOUNTING_SIGKILL:
1238 case MOUNT_REMOUNTING_SIGTERM:
1239
9d2f5178 1240 m->reload_result = f;
e2f3b44c 1241 if (m->from_proc_self_mountinfo)
9d2f5178 1242 mount_enter_mounted(m, MOUNT_SUCCESS);
e2f3b44c 1243 else
9d2f5178 1244 mount_enter_dead(m, MOUNT_SUCCESS);
e2f3b44c
LP
1245
1246 break;
1247
e537352b
LP
1248 case MOUNT_UNMOUNTING:
1249 case MOUNT_UNMOUNTING_SIGKILL:
1250 case MOUNT_UNMOUNTING_SIGTERM:
1251
7d54a03a
LP
1252 if (f == MOUNT_SUCCESS) {
1253
1254 if (m->from_proc_self_mountinfo) {
1255
1256 /* Still a mount point? If so, let's
1257 * try again. Most likely there were
1258 * multiple mount points stacked on
1259 * top of each other. Note that due to
1260 * the io event priority logic we can
1261 * be sure the new mountinfo is loaded
1262 * before we process the SIGCHLD for
1263 * the mount command. */
1264
1265 if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
1266 log_unit_debug(u->id, "%s: mount still present, trying again.", u->id);
1267 m->n_retry_umount++;
1268 mount_enter_unmounting(m);
1269 } else {
1270 log_unit_debug(u->id, "%s: mount still present after %u attempts to unmount, giving up.", u->id, m->n_retry_umount);
1271 mount_enter_mounted(m, f);
1272 }
1273 } else
1274 mount_enter_dead(m, f);
1275
1276 } else if (m->from_proc_self_mountinfo)
9d2f5178 1277 mount_enter_mounted(m, f);
e537352b 1278 else
9d2f5178 1279 mount_enter_dead(m, f);
e537352b
LP
1280 break;
1281
1282 default:
1283 assert_not_reached("Uh, control process died at wrong time.");
1284 }
c4e2ceae
LP
1285
1286 /* Notify clients about changed exit status */
1287 unit_add_to_dbus_queue(u);
e537352b
LP
1288}
1289
718db961
LP
1290static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1291 Mount *m = MOUNT(userdata);
e537352b
LP
1292
1293 assert(m);
718db961 1294 assert(m->timer_event_source == source);
e537352b
LP
1295
1296 switch (m->state) {
1297
1298 case MOUNT_MOUNTING:
1299 case MOUNT_MOUNTING_DONE:
79008bdd 1300 log_unit_warning(UNIT(m)->id,
718db961 1301 "%s mounting timed out. Stopping.", UNIT(m)->id);
9d2f5178 1302 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1303 break;
1304
1305 case MOUNT_REMOUNTING:
79008bdd 1306 log_unit_warning(UNIT(m)->id,
718db961 1307 "%s remounting timed out. Stopping.", UNIT(m)->id);
9d2f5178
LP
1308 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1309 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
1310 break;
1311
1312 case MOUNT_UNMOUNTING:
79008bdd 1313 log_unit_warning(UNIT(m)->id,
718db961 1314 "%s unmounting timed out. Stopping.", UNIT(m)->id);
9d2f5178 1315 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1316 break;
1317
1318 case MOUNT_MOUNTING_SIGTERM:
4819ff03 1319 if (m->kill_context.send_sigkill) {
79008bdd 1320 log_unit_warning(UNIT(m)->id,
718db961 1321 "%s mounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1322 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1323 } else {
79008bdd 1324 log_unit_warning(UNIT(m)->id,
66870f90 1325 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1326 UNIT(m)->id);
ba035df2
LP
1327
1328 if (m->from_proc_self_mountinfo)
9d2f5178 1329 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1330 else
9d2f5178 1331 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1332 }
e537352b
LP
1333 break;
1334
1335 case MOUNT_REMOUNTING_SIGTERM:
4819ff03 1336 if (m->kill_context.send_sigkill) {
79008bdd 1337 log_unit_warning(UNIT(m)->id,
718db961 1338 "%s remounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1339 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1340 } else {
79008bdd 1341 log_unit_warning(UNIT(m)->id,
66870f90 1342 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1343 UNIT(m)->id);
ba035df2
LP
1344
1345 if (m->from_proc_self_mountinfo)
9d2f5178 1346 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1347 else
9d2f5178 1348 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1349 }
e537352b
LP
1350 break;
1351
1352 case MOUNT_UNMOUNTING_SIGTERM:
4819ff03 1353 if (m->kill_context.send_sigkill) {
79008bdd 1354 log_unit_warning(UNIT(m)->id,
718db961 1355 "%s unmounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1356 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1357 } else {
79008bdd 1358 log_unit_warning(UNIT(m)->id,
66870f90 1359 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1360 UNIT(m)->id);
ba035df2
LP
1361
1362 if (m->from_proc_self_mountinfo)
9d2f5178 1363 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1364 else
9d2f5178 1365 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1366 }
e537352b
LP
1367 break;
1368
1369 case MOUNT_MOUNTING_SIGKILL:
1370 case MOUNT_REMOUNTING_SIGKILL:
1371 case MOUNT_UNMOUNTING_SIGKILL:
79008bdd 1372 log_unit_warning(UNIT(m)->id,
66870f90 1373 "%s mount process still around after SIGKILL. Ignoring.",
718db961 1374 UNIT(m)->id);
e537352b
LP
1375
1376 if (m->from_proc_self_mountinfo)
9d2f5178 1377 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
e537352b 1378 else
9d2f5178 1379 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1380 break;
1381
1382 default:
1383 assert_not_reached("Timeout at wrong time.");
1384 }
718db961
LP
1385
1386 return 0;
e537352b
LP
1387}
1388
628c89cc 1389static int mount_setup_unit(
e537352b
LP
1390 Manager *m,
1391 const char *what,
1392 const char *where,
1393 const char *options,
1394 const char *fstype,
e537352b 1395 bool set_flags) {
057d9ab8
LP
1396
1397 _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
b87705cd 1398 bool load_extras = false;
057d9ab8 1399 MountParameters *p;
ff5f34d0 1400 bool delete, changed = false;
057d9ab8
LP
1401 Unit *u;
1402 int r;
b08d03ff 1403
f50e0a01 1404 assert(m);
b08d03ff
LP
1405 assert(what);
1406 assert(where);
e537352b
LP
1407 assert(options);
1408 assert(fstype);
1409
e537352b
LP
1410 /* Ignore API mount points. They should never be referenced in
1411 * dependencies ever. */
33ff02c9 1412 if (mount_point_is_api(where) || mount_point_ignore(where))
57f2a956 1413 return 0;
b08d03ff 1414
8d567588
LP
1415 if (streq(fstype, "autofs"))
1416 return 0;
1417
4e85aff4
LP
1418 /* probably some kind of swap, ignore */
1419 if (!is_path(where))
b08d03ff
LP
1420 return 0;
1421
7d17cfbc
MS
1422 e = unit_name_from_path(where, ".mount");
1423 if (!e)
b08d03ff
LP
1424 return -ENOMEM;
1425
7d17cfbc
MS
1426 u = manager_get_unit(m, e);
1427 if (!u) {
b08d03ff
LP
1428 delete = true;
1429
7d17cfbc 1430 u = unit_new(m, sizeof(Mount));
057d9ab8 1431 if (!u)
628c89cc 1432 return log_oom();
b08d03ff
LP
1433
1434 r = unit_add_name(u, e);
b08d03ff
LP
1435 if (r < 0)
1436 goto fail;
1437
7d17cfbc
MS
1438 MOUNT(u)->where = strdup(where);
1439 if (!MOUNT(u)->where) {
07b0b134
ML
1440 r = -ENOMEM;
1441 goto fail;
1442 }
f50e0a01 1443
47a81ba2
UTL
1444 u->source_path = strdup("/proc/self/mountinfo");
1445 if (!u->source_path) {
1446 r = -ENOMEM;
1447 goto fail;
1448 }
1449
057d9ab8
LP
1450 if (m->running_as == SYSTEMD_SYSTEM) {
1451 const char* target;
1452
affc3d83 1453 target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
057d9ab8 1454 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
602c0e74
LP
1455 if (r < 0)
1456 goto fail;
057d9ab8
LP
1457
1458 if (should_umount(MOUNT(u))) {
1459 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1460 if (r < 0)
1461 goto fail;
1462 }
602c0e74 1463 }
89b1d5e0 1464
f94ea366 1465 unit_add_to_load_queue(u);
ff5f34d0 1466 changed = true;
b08d03ff
LP
1467 } else {
1468 delete = false;
8eba616f 1469
bcbd5405
WW
1470 if (!MOUNT(u)->where) {
1471 MOUNT(u)->where = strdup(where);
1472 if (!MOUNT(u)->where) {
1473 r = -ENOMEM;
1474 goto fail;
1475 }
1476 }
1477
9d05dd2e
ZJS
1478 if (m->running_as == SYSTEMD_SYSTEM &&
1479 mount_needs_network(options, fstype)) {
a6d305f9
CL
1480 /* _netdev option may have shown up late, or on a
1481 * remount. Add remote-fs dependencies, even though
9d05dd2e
ZJS
1482 * local-fs ones may already be there. */
1483 unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
1484 load_extras = true;
a6d305f9
CL
1485 }
1486
c2756a68 1487 if (u->load_state == UNIT_NOT_FOUND) {
8eba616f
MS
1488 u->load_state = UNIT_LOADED;
1489 u->load_error = 0;
b87705cd
LP
1490
1491 /* Load in the extras later on, after we
1492 * finished initialization of the unit */
1493 load_extras = true;
ff5f34d0 1494 changed = true;
8eba616f 1495 }
b08d03ff
LP
1496 }
1497
dd7a22a9
LP
1498 w = strdup(what);
1499 o = strdup(options);
1500 f = strdup(fstype);
1501 if (!w || !o || !f) {
e537352b
LP
1502 r = -ENOMEM;
1503 goto fail;
1504 }
1505
6b1dc2bd 1506 p = &MOUNT(u)->parameters_proc_self_mountinfo;
ff5f34d0
LP
1507
1508 changed = changed ||
1509 !streq_ptr(p->options, options) ||
1510 !streq_ptr(p->what, what) ||
1511 !streq_ptr(p->fstype, fstype);
1512
6b1dc2bd
LP
1513 if (set_flags) {
1514 MOUNT(u)->is_mounted = true;
1515 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
ff5f34d0 1516 MOUNT(u)->just_changed = changed;
ef734fd6 1517 }
f50e0a01 1518
6b1dc2bd
LP
1519 MOUNT(u)->from_proc_self_mountinfo = true;
1520
4e85aff4
LP
1521 free(p->what);
1522 p->what = w;
057d9ab8 1523 w = NULL;
b08d03ff 1524
4e85aff4
LP
1525 free(p->options);
1526 p->options = o;
057d9ab8 1527 o = NULL;
e537352b 1528
4e85aff4
LP
1529 free(p->fstype);
1530 p->fstype = f;
057d9ab8 1531 f = NULL;
b08d03ff 1532
b87705cd
LP
1533 if (load_extras) {
1534 r = mount_add_extras(MOUNT(u));
1535 if (r < 0)
1536 goto fail;
1537 }
1538
ff5f34d0
LP
1539 if (changed)
1540 unit_add_to_dbus_queue(u);
c1e1601e 1541
b08d03ff
LP
1542 return 0;
1543
1544fail:
628c89cc
LP
1545 log_warning_errno(r, "Failed to set up mount unit: %m");
1546
b08d03ff
LP
1547 if (delete && u)
1548 unit_free(u);
1549
4e85aff4 1550 return r;
b08d03ff
LP
1551}
1552
ef734fd6 1553static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
628c89cc
LP
1554 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
1555 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
60b912f6 1556 int r = 0;
b08d03ff
LP
1557
1558 assert(m);
1559
628c89cc
LP
1560 t = mnt_new_table();
1561 if (!t)
8d3ae2bd 1562 return log_oom();
b08d03ff 1563
628c89cc
LP
1564 i = mnt_new_iter(MNT_ITER_FORWARD);
1565 if (!i)
1566 return log_oom();
1567
1568 r = mnt_table_parse_mtab(t, NULL);
5cca8def 1569 if (r < 0)
628c89cc 1570 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
e537352b 1571
5cca8def
ZJS
1572 r = 0;
1573 for (;;) {
8d3ae2bd 1574 const char *device, *path, *options, *fstype;
527b7a42 1575 _cleanup_free_ char *d = NULL, *p = NULL;
628c89cc 1576 struct libmnt_fs *fs;
8d3ae2bd 1577 int k;
b08d03ff 1578
628c89cc 1579 k = mnt_table_next_fs(t, i, &fs);
5cca8def
ZJS
1580 if (k == 1)
1581 break;
628c89cc
LP
1582 if (k < 0)
1583 return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
5cca8def 1584
8d3ae2bd
CL
1585 device = mnt_fs_get_source(fs);
1586 path = mnt_fs_get_target(fs);
1587 options = mnt_fs_get_options(fs);
1588 fstype = mnt_fs_get_fstype(fs);
a2e0f3d3 1589
527b7a42 1590 if (cunescape(device, UNESCAPE_RELAX, &d) < 0)
628c89cc
LP
1591 return log_oom();
1592
527b7a42 1593 if (cunescape(path, UNESCAPE_RELAX, &p) < 0)
a57f7e2c 1594 return log_oom();
b08d03ff 1595
628c89cc
LP
1596 (void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags);
1597
1598 k = mount_setup_unit(m, d, p, options, fstype, set_flags);
5cca8def 1599 if (r == 0 && k < 0)
60b912f6 1600 r = k;
b08d03ff
LP
1601 }
1602
e537352b
LP
1603 return r;
1604}
1605
1606static void mount_shutdown(Manager *m) {
1607 assert(m);
1608
718db961 1609 m->mount_event_source = sd_event_source_unref(m->mount_event_source);
befb6d54 1610 m->mount_utab_event_source = sd_event_source_unref(m->mount_utab_event_source);
718db961 1611
a16e1123 1612 if (m->proc_self_mountinfo) {
e537352b 1613 fclose(m->proc_self_mountinfo);
a16e1123
LP
1614 m->proc_self_mountinfo = NULL;
1615 }
befb6d54 1616 m->utab_inotify_fd = safe_close(m->utab_inotify_fd);
b08d03ff
LP
1617}
1618
68db7a3b
ZJS
1619static int mount_get_timeout(Unit *u, uint64_t *timeout) {
1620 Mount *m = MOUNT(u);
1621 int r;
1622
1623 if (!m->timer_event_source)
1624 return 0;
1625
1626 r = sd_event_source_get_time(m->timer_event_source, timeout);
1627 if (r < 0)
1628 return r;
1629
1630 return 1;
1631}
1632
b08d03ff
LP
1633static int mount_enumerate(Manager *m) {
1634 int r;
1635 assert(m);
1636
8d3ae2bd
CL
1637 mnt_init_debug(0);
1638
a16e1123 1639 if (!m->proc_self_mountinfo) {
e62d8c39
ZJS
1640 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1641 if (!m->proc_self_mountinfo)
a16e1123 1642 return -errno;
ef734fd6 1643
151b9b96 1644 r = sd_event_add_io(m->event, &m->mount_event_source, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m);
718db961
LP
1645 if (r < 0)
1646 goto fail;
29083707
LP
1647
1648 /* Dispatch this before we dispatch SIGCHLD, so that
1649 * we always get the events from /proc/self/mountinfo
1650 * before the SIGCHLD of /bin/mount. */
1651 r = sd_event_source_set_priority(m->mount_event_source, -10);
1652 if (r < 0)
1653 goto fail;
7dfbe2e3
TG
1654
1655 (void) sd_event_source_set_description(m->mount_event_source, "mount-mountinfo-dispatch");
a16e1123 1656 }
ef734fd6 1657
befb6d54
CL
1658 if (m->utab_inotify_fd < 0) {
1659 m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
f7c1ad4f
LP
1660 if (m->utab_inotify_fd < 0) {
1661 r = -errno;
1662 goto fail;
1663 }
befb6d54 1664
90598531
ZJS
1665 (void) mkdir_p_label("/run/mount", 0755);
1666
befb6d54 1667 r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
f7c1ad4f
LP
1668 if (r < 0) {
1669 r = -errno;
1670 goto fail;
1671 }
befb6d54
CL
1672
1673 r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
1674 if (r < 0)
1675 goto fail;
1676
1677 r = sd_event_source_set_priority(m->mount_utab_event_source, -10);
1678 if (r < 0)
1679 goto fail;
7dfbe2e3
TG
1680
1681 (void) sd_event_source_set_description(m->mount_utab_event_source, "mount-utab-dispatch");
befb6d54
CL
1682 }
1683
e62d8c39
ZJS
1684 r = mount_load_proc_self_mountinfo(m, false);
1685 if (r < 0)
b08d03ff
LP
1686 goto fail;
1687
1688 return 0;
1689
1690fail:
1691 mount_shutdown(m);
1692 return r;
5cb5a6ff
LP
1693}
1694
718db961
LP
1695static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1696 Manager *m = userdata;
595ed347 1697 Unit *u;
ef734fd6
LP
1698 int r;
1699
1700 assert(m);
befb6d54 1701 assert(revents & (EPOLLPRI | EPOLLIN));
ef734fd6
LP
1702
1703 /* The manager calls this for every fd event happening on the
1704 * /proc/self/mountinfo file, which informs us about mounting
fddf1a31
ZJS
1705 * table changes, and for /run/mount events which we watch
1706 * for mount options. */
befb6d54
CL
1707
1708 if (fd == m->utab_inotify_fd) {
df63dda6 1709 bool rescan = false;
befb6d54 1710
b7307642
LP
1711 /* FIXME: We *really* need to replace this with
1712 * libmount's own API for this, we should not hardcode
1713 * internal behaviour of libmount here. */
1714
f7c1ad4f 1715 for (;;) {
0254e944 1716 union inotify_event_buffer buffer;
f7c1ad4f
LP
1717 struct inotify_event *e;
1718 ssize_t l;
1719
0254e944 1720 l = read(fd, &buffer, sizeof(buffer));
f7c1ad4f
LP
1721 if (l < 0) {
1722 if (errno == EAGAIN || errno == EINTR)
1723 break;
1724
1725 log_error_errno(errno, "Failed to read utab inotify: %m");
1726 break;
1727 }
1728
1729 FOREACH_INOTIFY_EVENT(e, buffer, l) {
1730 /* Only care about changes to utab,
1731 * but we have to monitor the
1732 * directory to reliably get
1733 * notifications about when utab is
1734 * replaced using rename(2) */
1735 if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab"))
df63dda6 1736 rescan = true;
befb6d54 1737 }
f7c1ad4f 1738 }
fddf1a31 1739
befb6d54
CL
1740 if (!rescan)
1741 return 0;
1742 }
ef734fd6 1743
4f0eedb7
ZJS
1744 r = mount_load_proc_self_mountinfo(m, true);
1745 if (r < 0) {
e537352b 1746 /* Reset flags, just in case, for later calls */
595ed347
MS
1747 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1748 Mount *mount = MOUNT(u);
e537352b
LP
1749
1750 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1751 }
1752
718db961 1753 return 0;
ef734fd6
LP
1754 }
1755
1756 manager_dispatch_load_queue(m);
1757
595ed347
MS
1758 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1759 Mount *mount = MOUNT(u);
ef734fd6 1760
e537352b 1761 if (!mount->is_mounted) {
e537352b 1762
ef734fd6 1763 mount->from_proc_self_mountinfo = false;
e537352b
LP
1764
1765 switch (mount->state) {
1766
1767 case MOUNT_MOUNTED:
aef83136
LP
1768 /* This has just been unmounted by
1769 * somebody else, follow the state
1770 * change. */
9d2f5178 1771 mount_enter_dead(mount, MOUNT_SUCCESS);
e537352b
LP
1772 break;
1773
1774 default:
e537352b 1775 break;
e537352b
LP
1776 }
1777
628c89cc
LP
1778 if (mount->parameters_proc_self_mountinfo.what)
1779 (void) device_found_node(m, mount->parameters_proc_self_mountinfo.what, false, DEVICE_FOUND_MOUNT, true);
1780
1781
e537352b
LP
1782 } else if (mount->just_mounted || mount->just_changed) {
1783
60b912f6 1784 /* New or changed mount entry */
e537352b
LP
1785
1786 switch (mount->state) {
1787
1788 case MOUNT_DEAD:
fdf20a31 1789 case MOUNT_FAILED:
aef83136
LP
1790 /* This has just been mounted by
1791 * somebody else, follow the state
1792 * change. */
9d2f5178 1793 mount_enter_mounted(mount, MOUNT_SUCCESS);
e537352b
LP
1794 break;
1795
1796 case MOUNT_MOUNTING:
5bcb0f2b 1797 mount_set_state(mount, MOUNT_MOUNTING_DONE);
e537352b
LP
1798 break;
1799
1800 default:
1801 /* Nothing really changed, but let's
1802 * issue an notification call
1803 * nonetheless, in case somebody is
1804 * waiting for this. (e.g. file system
1805 * ro/rw remounts.) */
1806 mount_set_state(mount, mount->state);
1807 break;
1808 }
1809 }
1810
1811 /* Reset the flags for later calls */
1812 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1813 }
718db961
LP
1814
1815 return 0;
e537352b
LP
1816}
1817
fdf20a31 1818static void mount_reset_failed(Unit *u) {
5632e374
LP
1819 Mount *m = MOUNT(u);
1820
1821 assert(m);
1822
fdf20a31 1823 if (m->state == MOUNT_FAILED)
5632e374
LP
1824 mount_set_state(m, MOUNT_DEAD);
1825
9d2f5178
LP
1826 m->result = MOUNT_SUCCESS;
1827 m->reload_result = MOUNT_SUCCESS;
5632e374
LP
1828}
1829
718db961 1830static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
814cc562 1831 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
8a0867d6
LP
1832}
1833
a16e1123
LP
1834static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1835 [MOUNT_DEAD] = "dead",
1836 [MOUNT_MOUNTING] = "mounting",
1837 [MOUNT_MOUNTING_DONE] = "mounting-done",
1838 [MOUNT_MOUNTED] = "mounted",
1839 [MOUNT_REMOUNTING] = "remounting",
1840 [MOUNT_UNMOUNTING] = "unmounting",
1841 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1842 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1843 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1844 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1845 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1846 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
fdf20a31 1847 [MOUNT_FAILED] = "failed"
a16e1123
LP
1848};
1849
1850DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1851
1852static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1853 [MOUNT_EXEC_MOUNT] = "ExecMount",
1854 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1855 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1856};
1857
1858DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1859
9d2f5178
LP
1860static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1861 [MOUNT_SUCCESS] = "success",
1862 [MOUNT_FAILURE_RESOURCES] = "resources",
1863 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1864 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1865 [MOUNT_FAILURE_SIGNAL] = "signal",
1866 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1867};
1868
1869DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1870
87f0e418 1871const UnitVTable mount_vtable = {
7d17cfbc 1872 .object_size = sizeof(Mount),
718db961
LP
1873 .exec_context_offset = offsetof(Mount, exec_context),
1874 .cgroup_context_offset = offsetof(Mount, cgroup_context),
1875 .kill_context_offset = offsetof(Mount, kill_context),
613b411c 1876 .exec_runtime_offset = offsetof(Mount, exec_runtime),
3ef63c31 1877
f975e971
LP
1878 .sections =
1879 "Unit\0"
1880 "Mount\0"
1881 "Install\0",
4ad49000 1882 .private_section = "Mount",
71645aca 1883
e537352b 1884 .no_alias = true,
9e2f7c11 1885 .no_instances = true,
e537352b
LP
1886
1887 .init = mount_init,
1888 .load = mount_load,
034c6ed7 1889 .done = mount_done,
e537352b 1890
f50e0a01
LP
1891 .coldplug = mount_coldplug,
1892
034c6ed7 1893 .dump = mount_dump,
5cb5a6ff 1894
e537352b
LP
1895 .start = mount_start,
1896 .stop = mount_stop,
1897 .reload = mount_reload,
1898
8a0867d6
LP
1899 .kill = mount_kill,
1900
a16e1123
LP
1901 .serialize = mount_serialize,
1902 .deserialize_item = mount_deserialize_item,
1903
f50e0a01 1904 .active_state = mount_active_state,
10a94420 1905 .sub_state_to_string = mount_sub_state_to_string,
b08d03ff 1906
701cc384
LP
1907 .check_gc = mount_check_gc,
1908
e537352b 1909 .sigchld_event = mount_sigchld_event,
e537352b 1910
fdf20a31 1911 .reset_failed = mount_reset_failed,
5632e374 1912
c4e2ceae 1913 .bus_interface = "org.freedesktop.systemd1.Mount",
718db961 1914 .bus_vtable = bus_mount_vtable,
74c964d3
LP
1915 .bus_set_property = bus_mount_set_property,
1916 .bus_commit_properties = bus_mount_commit_properties,
4139c1b2 1917
68db7a3b
ZJS
1918 .get_timeout = mount_get_timeout,
1919
0e252f6b
TG
1920 .can_transient = true,
1921
f50e0a01 1922 .enumerate = mount_enumerate,
c6918296
MS
1923 .shutdown = mount_shutdown,
1924
1925 .status_message_formats = {
1926 .starting_stopping = {
1927 [0] = "Mounting %s...",
1928 [1] = "Unmounting %s...",
1929 },
1930 .finished_start_job = {
1931 [JOB_DONE] = "Mounted %s.",
1932 [JOB_FAILED] = "Failed to mount %s.",
1933 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1934 [JOB_TIMEOUT] = "Timed out mounting %s.",
1935 },
1936 .finished_stop_job = {
1937 [JOB_DONE] = "Unmounted %s.",
1938 [JOB_FAILED] = "Failed unmounting %s.",
1939 [JOB_TIMEOUT] = "Timed out unmounting %s.",
1940 },
1941 },
5cb5a6ff 1942};