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