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