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