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