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