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