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