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