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