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