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