]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/mount.c
unit: add new macros to test for unit contexts
[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);
7d54a03a 837 if (r < 0)
e537352b
LP
838 goto fail;
839
a16e1123 840 mount_unwatch_control_pid(m);
5e94833f 841
7d54a03a
LP
842 r = mount_spawn(m, m->control_command, &m->control_pid);
843 if (r < 0)
e537352b
LP
844 goto fail;
845
846 mount_set_state(m, MOUNT_UNMOUNTING);
847
848 return;
849
850fail:
f2341e0a 851 log_unit_warning_errno(UNIT(m), r, "Failed to run 'umount' task: %m");
9d2f5178 852 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
853}
854
8d567588 855static void mount_enter_mounting(Mount *m) {
e537352b 856 int r;
cb39ed3f 857 MountParameters *p;
e537352b
LP
858
859 assert(m);
860
a16e1123
LP
861 m->control_command_id = MOUNT_EXEC_MOUNT;
862 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
e537352b 863
f2341e0a
LP
864 r = unit_fail_if_symlink(UNIT(m), m->where);
865 if (r < 0)
866 goto fail;
867
868 (void) mkdir_p_label(m->where, m->directory_mode);
3e5235b0 869
f2341e0a 870 unit_warn_if_dir_nonempty(UNIT(m), m->where);
257f1d8e 871
cb39ed3f 872 /* Create the source directory for bind-mounts if needed */
6b1dc2bd 873 p = get_mount_parameters_fragment(m);
cb39ed3f 874 if (p && mount_is_bind(p))
f2341e0a 875 (void) mkdir_p_label(p->what, m->directory_mode);
5261ba90 876
e86b3761 877 if (m->from_fragment) {
17a1c597
ZJS
878 _cleanup_free_ char *opts = NULL;
879
880 r = fstab_filter_options(m->parameters_fragment.options,
76c37ab6 881 "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
17a1c597
ZJS
882 if (r < 0)
883 goto fail;
884
f00929ad 885 r = exec_command_set(m->control_command, MOUNT_PATH,
e86b3761 886 m->parameters_fragment.what, m->where, NULL);
e86b3761
ZJS
887 if (r >= 0 && m->sloppy_options)
888 r = exec_command_append(m->control_command, "-s", NULL);
889 if (r >= 0 && m->parameters_fragment.fstype)
890 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
0c47569a 891 if (r >= 0 && !isempty(opts))
17a1c597 892 r = exec_command_append(m->control_command, "-o", opts, NULL);
e86b3761 893 } else
e537352b
LP
894 r = -ENOENT;
895
896 if (r < 0)
897 goto fail;
898
a16e1123 899 mount_unwatch_control_pid(m);
5e94833f 900
257f1d8e
LP
901 r = mount_spawn(m, m->control_command, &m->control_pid);
902 if (r < 0)
e537352b
LP
903 goto fail;
904
905 mount_set_state(m, MOUNT_MOUNTING);
906
907 return;
908
909fail:
f2341e0a 910 log_unit_warning_errno(UNIT(m), r, "Failed to run 'mount' task: %m");
9d2f5178 911 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
912}
913
9d2f5178 914static void mount_enter_remounting(Mount *m) {
e537352b
LP
915 int r;
916
917 assert(m);
918
a16e1123
LP
919 m->control_command_id = MOUNT_EXEC_REMOUNT;
920 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
e537352b
LP
921
922 if (m->from_fragment) {
e537352b
LP
923 const char *o;
924
718db961 925 if (m->parameters_fragment.options)
63c372cb 926 o = strjoina("remount,", m->parameters_fragment.options);
718db961 927 else
e537352b
LP
928 o = "remount";
929
f00929ad 930 r = exec_command_set(m->control_command, MOUNT_PATH,
e86b3761
ZJS
931 m->parameters_fragment.what, m->where,
932 "-o", o, NULL);
e86b3761
ZJS
933 if (r >= 0 && m->sloppy_options)
934 r = exec_command_append(m->control_command, "-s", NULL);
935 if (r >= 0 && m->parameters_fragment.fstype)
936 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
6b1dc2bd 937 } else
e537352b
LP
938 r = -ENOENT;
939
60b912f6 940 if (r < 0)
e537352b 941 goto fail;
e537352b 942
a16e1123 943 mount_unwatch_control_pid(m);
5e94833f 944
718db961
LP
945 r = mount_spawn(m, m->control_command, &m->control_pid);
946 if (r < 0)
e537352b
LP
947 goto fail;
948
949 mount_set_state(m, MOUNT_REMOUNTING);
950
951 return;
952
953fail:
f2341e0a 954 log_unit_warning_errno(UNIT(m), r, "Failed to run 'remount' task: %m");
9d2f5178
LP
955 m->reload_result = MOUNT_FAILURE_RESOURCES;
956 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
957}
958
959static int mount_start(Unit *u) {
960 Mount *m = MOUNT(u);
961
962 assert(m);
963
964 /* We cannot fulfill this request right now, try again later
965 * please! */
966 if (m->state == MOUNT_UNMOUNTING ||
967 m->state == MOUNT_UNMOUNTING_SIGTERM ||
60b912f6
LP
968 m->state == MOUNT_UNMOUNTING_SIGKILL ||
969 m->state == MOUNT_MOUNTING_SIGTERM ||
970 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
971 return -EAGAIN;
972
973 /* Already on it! */
60b912f6 974 if (m->state == MOUNT_MOUNTING)
e537352b
LP
975 return 0;
976
fdf20a31 977 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
e537352b 978
9d2f5178
LP
979 m->result = MOUNT_SUCCESS;
980 m->reload_result = MOUNT_SUCCESS;
5ad096b3 981 m->reset_cpu_usage = true;
9d2f5178 982
8d567588 983 mount_enter_mounting(m);
82a2b6bb 984 return 1;
e537352b
LP
985}
986
987static int mount_stop(Unit *u) {
988 Mount *m = MOUNT(u);
989
990 assert(m);
991
e537352b
LP
992 /* Already on it */
993 if (m->state == MOUNT_UNMOUNTING ||
994 m->state == MOUNT_UNMOUNTING_SIGKILL ||
60b912f6
LP
995 m->state == MOUNT_UNMOUNTING_SIGTERM ||
996 m->state == MOUNT_MOUNTING_SIGTERM ||
997 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
998 return 0;
999
3f6c78dc
LP
1000 assert(m->state == MOUNT_MOUNTING ||
1001 m->state == MOUNT_MOUNTING_DONE ||
1002 m->state == MOUNT_MOUNTED ||
3f6c78dc
LP
1003 m->state == MOUNT_REMOUNTING ||
1004 m->state == MOUNT_REMOUNTING_SIGTERM ||
1005 m->state == MOUNT_REMOUNTING_SIGKILL);
e537352b 1006
9d2f5178 1007 mount_enter_unmounting(m);
82a2b6bb 1008 return 1;
e537352b
LP
1009}
1010
1011static int mount_reload(Unit *u) {
1012 Mount *m = MOUNT(u);
1013
1014 assert(m);
1015
1016 if (m->state == MOUNT_MOUNTING_DONE)
1017 return -EAGAIN;
1018
1019 assert(m->state == MOUNT_MOUNTED);
1020
9d2f5178 1021 mount_enter_remounting(m);
2d018ae2 1022 return 1;
e537352b
LP
1023}
1024
a16e1123
LP
1025static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1026 Mount *m = MOUNT(u);
1027
1028 assert(m);
1029 assert(f);
1030 assert(fds);
1031
1032 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
9d2f5178
LP
1033 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1034 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
a16e1123
LP
1035
1036 if (m->control_pid > 0)
ccd06097 1037 unit_serialize_item_format(u, f, "control-pid", PID_FMT, m->control_pid);
a16e1123
LP
1038
1039 if (m->control_command_id >= 0)
1040 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1041
1042 return 0;
1043}
1044
1045static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1046 Mount *m = MOUNT(u);
a16e1123
LP
1047
1048 assert(u);
1049 assert(key);
1050 assert(value);
1051 assert(fds);
1052
1053 if (streq(key, "state")) {
1054 MountState state;
1055
1056 if ((state = mount_state_from_string(value)) < 0)
f2341e0a 1057 log_unit_debug(u, "Failed to parse state value: %s", value);
a16e1123
LP
1058 else
1059 m->deserialized_state = state;
9d2f5178
LP
1060 } else if (streq(key, "result")) {
1061 MountResult f;
a16e1123 1062
9d2f5178
LP
1063 f = mount_result_from_string(value);
1064 if (f < 0)
f2341e0a 1065 log_unit_debug(u, "Failed to parse result value: %s", value);
9d2f5178
LP
1066 else if (f != MOUNT_SUCCESS)
1067 m->result = f;
1068
1069 } else if (streq(key, "reload-result")) {
1070 MountResult f;
1071
1072 f = mount_result_from_string(value);
1073 if (f < 0)
f2341e0a 1074 log_unit_debug(u, "Failed to parse reload result value: %s", value);
9d2f5178
LP
1075 else if (f != MOUNT_SUCCESS)
1076 m->reload_result = f;
a16e1123
LP
1077
1078 } else if (streq(key, "control-pid")) {
5925dd3c 1079 pid_t pid;
a16e1123 1080
e364ad06 1081 if (parse_pid(value, &pid) < 0)
f2341e0a 1082 log_unit_debug(u, "Failed to parse control-pid value: %s", value);
a16e1123 1083 else
5925dd3c 1084 m->control_pid = pid;
a16e1123
LP
1085 } else if (streq(key, "control-command")) {
1086 MountExecCommand id;
1087
f2341e0a
LP
1088 id = mount_exec_command_from_string(value);
1089 if (id < 0)
1090 log_unit_debug(u, "Failed to parse exec-command value: %s", value);
a16e1123
LP
1091 else {
1092 m->control_command_id = id;
1093 m->control_command = m->exec_command + id;
1094 }
a16e1123 1095 } else
f2341e0a 1096 log_unit_debug(u, "Unknown serialization key: %s", key);
a16e1123
LP
1097
1098 return 0;
1099}
1100
44a6b1b6 1101_pure_ static UnitActiveState mount_active_state(Unit *u) {
e537352b
LP
1102 assert(u);
1103
1104 return state_translation_table[MOUNT(u)->state];
1105}
1106
44a6b1b6 1107_pure_ static const char *mount_sub_state_to_string(Unit *u) {
10a94420
LP
1108 assert(u);
1109
a16e1123 1110 return mount_state_to_string(MOUNT(u)->state);
10a94420
LP
1111}
1112
44a6b1b6 1113_pure_ static bool mount_check_gc(Unit *u) {
701cc384
LP
1114 Mount *m = MOUNT(u);
1115
1116 assert(m);
1117
6b1dc2bd 1118 return m->from_proc_self_mountinfo;
701cc384
LP
1119}
1120
e537352b
LP
1121static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1122 Mount *m = MOUNT(u);
9d2f5178 1123 MountResult f;
e537352b
LP
1124
1125 assert(m);
1126 assert(pid >= 0);
1127
8c47c732
LP
1128 if (pid != m->control_pid)
1129 return;
e537352b 1130
e537352b
LP
1131 m->control_pid = 0;
1132
96342de6 1133 if (is_clean_exit(code, status, NULL))
9d2f5178
LP
1134 f = MOUNT_SUCCESS;
1135 else if (code == CLD_EXITED)
1136 f = MOUNT_FAILURE_EXIT_CODE;
1137 else if (code == CLD_KILLED)
1138 f = MOUNT_FAILURE_SIGNAL;
1139 else if (code == CLD_DUMPED)
1140 f = MOUNT_FAILURE_CORE_DUMP;
1141 else
1142 assert_not_reached("Unknown code");
1143
1144 if (f != MOUNT_SUCCESS)
1145 m->result = f;
8c47c732 1146
a16e1123 1147 if (m->control_command) {
6ea832a2 1148 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
9d2f5178 1149
a16e1123
LP
1150 m->control_command = NULL;
1151 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1152 }
1153
f2341e0a
LP
1154 log_unit_full(u, f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,
1155 "Mount process exited, code=%s status=%i", sigchld_code_to_string(code), status);
e537352b
LP
1156
1157 /* Note that mount(8) returning and the kernel sending us a
1158 * mount table change event might happen out-of-order. If an
1159 * operation succeed we assume the kernel will follow soon too
1160 * and already change into the resulting state. If it fails
1161 * we check if the kernel still knows about the mount. and
1162 * change state accordingly. */
1163
1164 switch (m->state) {
1165
1166 case MOUNT_MOUNTING:
1167 case MOUNT_MOUNTING_DONE:
1168 case MOUNT_MOUNTING_SIGKILL:
1169 case MOUNT_MOUNTING_SIGTERM:
e537352b 1170
9d2f5178
LP
1171 if (f == MOUNT_SUCCESS)
1172 mount_enter_mounted(m, f);
e537352b 1173 else if (m->from_proc_self_mountinfo)
9d2f5178 1174 mount_enter_mounted(m, f);
e537352b 1175 else
9d2f5178 1176 mount_enter_dead(m, f);
e537352b
LP
1177 break;
1178
e2f3b44c
LP
1179 case MOUNT_REMOUNTING:
1180 case MOUNT_REMOUNTING_SIGKILL:
1181 case MOUNT_REMOUNTING_SIGTERM:
1182
9d2f5178 1183 m->reload_result = f;
e2f3b44c 1184 if (m->from_proc_self_mountinfo)
9d2f5178 1185 mount_enter_mounted(m, MOUNT_SUCCESS);
e2f3b44c 1186 else
9d2f5178 1187 mount_enter_dead(m, MOUNT_SUCCESS);
e2f3b44c
LP
1188
1189 break;
1190
e537352b
LP
1191 case MOUNT_UNMOUNTING:
1192 case MOUNT_UNMOUNTING_SIGKILL:
1193 case MOUNT_UNMOUNTING_SIGTERM:
1194
7d54a03a
LP
1195 if (f == MOUNT_SUCCESS) {
1196
1197 if (m->from_proc_self_mountinfo) {
1198
1199 /* Still a mount point? If so, let's
1200 * try again. Most likely there were
1201 * multiple mount points stacked on
1202 * top of each other. Note that due to
1203 * the io event priority logic we can
1204 * be sure the new mountinfo is loaded
1205 * before we process the SIGCHLD for
1206 * the mount command. */
1207
1208 if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
f2341e0a 1209 log_unit_debug(u, "Mount still present, trying again.");
7d54a03a
LP
1210 m->n_retry_umount++;
1211 mount_enter_unmounting(m);
1212 } else {
f2341e0a 1213 log_unit_debug(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
7d54a03a
LP
1214 mount_enter_mounted(m, f);
1215 }
1216 } else
1217 mount_enter_dead(m, f);
1218
1219 } else if (m->from_proc_self_mountinfo)
9d2f5178 1220 mount_enter_mounted(m, f);
e537352b 1221 else
9d2f5178 1222 mount_enter_dead(m, f);
e537352b
LP
1223 break;
1224
1225 default:
1226 assert_not_reached("Uh, control process died at wrong time.");
1227 }
c4e2ceae
LP
1228
1229 /* Notify clients about changed exit status */
1230 unit_add_to_dbus_queue(u);
e537352b
LP
1231}
1232
718db961
LP
1233static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1234 Mount *m = MOUNT(userdata);
e537352b
LP
1235
1236 assert(m);
718db961 1237 assert(m->timer_event_source == source);
e537352b
LP
1238
1239 switch (m->state) {
1240
1241 case MOUNT_MOUNTING:
1242 case MOUNT_MOUNTING_DONE:
f2341e0a 1243 log_unit_warning(UNIT(m), "Mounting timed out. Stopping.");
9d2f5178 1244 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1245 break;
1246
1247 case MOUNT_REMOUNTING:
f2341e0a 1248 log_unit_warning(UNIT(m), "Remounting timed out. Stopping.");
9d2f5178
LP
1249 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1250 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
1251 break;
1252
1253 case MOUNT_UNMOUNTING:
f2341e0a 1254 log_unit_warning(UNIT(m), "Unmounting timed out. Stopping.");
9d2f5178 1255 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1256 break;
1257
1258 case MOUNT_MOUNTING_SIGTERM:
4819ff03 1259 if (m->kill_context.send_sigkill) {
f2341e0a 1260 log_unit_warning(UNIT(m), "Mounting timed out. Killing.");
9d2f5178 1261 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1262 } else {
f2341e0a 1263 log_unit_warning(UNIT(m), "Mounting timed out. Skipping SIGKILL. Ignoring.");
ba035df2
LP
1264
1265 if (m->from_proc_self_mountinfo)
9d2f5178 1266 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1267 else
9d2f5178 1268 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1269 }
e537352b
LP
1270 break;
1271
1272 case MOUNT_REMOUNTING_SIGTERM:
4819ff03 1273 if (m->kill_context.send_sigkill) {
f2341e0a 1274 log_unit_warning(UNIT(m), "Remounting timed out. Killing.");
9d2f5178 1275 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1276 } else {
f2341e0a 1277 log_unit_warning(UNIT(m), "Remounting timed out. Skipping SIGKILL. Ignoring.");
ba035df2
LP
1278
1279 if (m->from_proc_self_mountinfo)
9d2f5178 1280 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1281 else
9d2f5178 1282 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1283 }
e537352b
LP
1284 break;
1285
1286 case MOUNT_UNMOUNTING_SIGTERM:
4819ff03 1287 if (m->kill_context.send_sigkill) {
f2341e0a 1288 log_unit_warning(UNIT(m), "Unmounting timed out. Killing.");
9d2f5178 1289 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1290 } else {
f2341e0a 1291 log_unit_warning(UNIT(m), "Unmounting timed out. Skipping SIGKILL. Ignoring.");
ba035df2
LP
1292
1293 if (m->from_proc_self_mountinfo)
9d2f5178 1294 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1295 else
9d2f5178 1296 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1297 }
e537352b
LP
1298 break;
1299
1300 case MOUNT_MOUNTING_SIGKILL:
1301 case MOUNT_REMOUNTING_SIGKILL:
1302 case MOUNT_UNMOUNTING_SIGKILL:
f2341e0a 1303 log_unit_warning(UNIT(m),"Mount process still around after SIGKILL. Ignoring.");
e537352b
LP
1304
1305 if (m->from_proc_self_mountinfo)
9d2f5178 1306 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
e537352b 1307 else
9d2f5178 1308 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1309 break;
1310
1311 default:
1312 assert_not_reached("Timeout at wrong time.");
1313 }
718db961
LP
1314
1315 return 0;
e537352b
LP
1316}
1317
628c89cc 1318static int mount_setup_unit(
e537352b
LP
1319 Manager *m,
1320 const char *what,
1321 const char *where,
1322 const char *options,
1323 const char *fstype,
e537352b 1324 bool set_flags) {
057d9ab8
LP
1325
1326 _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
b87705cd 1327 bool load_extras = false;
057d9ab8 1328 MountParameters *p;
ff5f34d0 1329 bool delete, changed = false;
057d9ab8
LP
1330 Unit *u;
1331 int r;
b08d03ff 1332
f50e0a01 1333 assert(m);
b08d03ff
LP
1334 assert(what);
1335 assert(where);
e537352b
LP
1336 assert(options);
1337 assert(fstype);
1338
e537352b
LP
1339 /* Ignore API mount points. They should never be referenced in
1340 * dependencies ever. */
33ff02c9 1341 if (mount_point_is_api(where) || mount_point_ignore(where))
57f2a956 1342 return 0;
b08d03ff 1343
8d567588
LP
1344 if (streq(fstype, "autofs"))
1345 return 0;
1346
4e85aff4
LP
1347 /* probably some kind of swap, ignore */
1348 if (!is_path(where))
b08d03ff
LP
1349 return 0;
1350
7410616c
LP
1351 r = unit_name_from_path(where, ".mount", &e);
1352 if (r < 0)
1353 return r;
b08d03ff 1354
7d17cfbc
MS
1355 u = manager_get_unit(m, e);
1356 if (!u) {
b08d03ff
LP
1357 delete = true;
1358
7d17cfbc 1359 u = unit_new(m, sizeof(Mount));
057d9ab8 1360 if (!u)
628c89cc 1361 return log_oom();
b08d03ff
LP
1362
1363 r = unit_add_name(u, e);
b08d03ff
LP
1364 if (r < 0)
1365 goto fail;
1366
7d17cfbc
MS
1367 MOUNT(u)->where = strdup(where);
1368 if (!MOUNT(u)->where) {
07b0b134
ML
1369 r = -ENOMEM;
1370 goto fail;
1371 }
f50e0a01 1372
47a81ba2
UTL
1373 u->source_path = strdup("/proc/self/mountinfo");
1374 if (!u->source_path) {
1375 r = -ENOMEM;
1376 goto fail;
1377 }
1378
b2c23da8 1379 if (m->running_as == MANAGER_SYSTEM) {
057d9ab8
LP
1380 const char* target;
1381
affc3d83 1382 target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
057d9ab8 1383 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
602c0e74
LP
1384 if (r < 0)
1385 goto fail;
057d9ab8
LP
1386
1387 if (should_umount(MOUNT(u))) {
1388 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1389 if (r < 0)
1390 goto fail;
1391 }
602c0e74 1392 }
89b1d5e0 1393
f94ea366 1394 unit_add_to_load_queue(u);
ff5f34d0 1395 changed = true;
b08d03ff
LP
1396 } else {
1397 delete = false;
8eba616f 1398
bcbd5405
WW
1399 if (!MOUNT(u)->where) {
1400 MOUNT(u)->where = strdup(where);
1401 if (!MOUNT(u)->where) {
1402 r = -ENOMEM;
1403 goto fail;
1404 }
1405 }
1406
b2c23da8 1407 if (m->running_as == MANAGER_SYSTEM &&
9d05dd2e 1408 mount_needs_network(options, fstype)) {
a6d305f9
CL
1409 /* _netdev option may have shown up late, or on a
1410 * remount. Add remote-fs dependencies, even though
9d05dd2e
ZJS
1411 * local-fs ones may already be there. */
1412 unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
1413 load_extras = true;
a6d305f9
CL
1414 }
1415
c2756a68 1416 if (u->load_state == UNIT_NOT_FOUND) {
8eba616f
MS
1417 u->load_state = UNIT_LOADED;
1418 u->load_error = 0;
b87705cd
LP
1419
1420 /* Load in the extras later on, after we
1421 * finished initialization of the unit */
1422 load_extras = true;
ff5f34d0 1423 changed = true;
8eba616f 1424 }
b08d03ff
LP
1425 }
1426
dd7a22a9
LP
1427 w = strdup(what);
1428 o = strdup(options);
1429 f = strdup(fstype);
1430 if (!w || !o || !f) {
e537352b
LP
1431 r = -ENOMEM;
1432 goto fail;
1433 }
1434
6b1dc2bd 1435 p = &MOUNT(u)->parameters_proc_self_mountinfo;
ff5f34d0
LP
1436
1437 changed = changed ||
1438 !streq_ptr(p->options, options) ||
1439 !streq_ptr(p->what, what) ||
1440 !streq_ptr(p->fstype, fstype);
1441
6b1dc2bd
LP
1442 if (set_flags) {
1443 MOUNT(u)->is_mounted = true;
1444 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
ff5f34d0 1445 MOUNT(u)->just_changed = changed;
ef734fd6 1446 }
f50e0a01 1447
6b1dc2bd
LP
1448 MOUNT(u)->from_proc_self_mountinfo = true;
1449
4e85aff4
LP
1450 free(p->what);
1451 p->what = w;
057d9ab8 1452 w = NULL;
b08d03ff 1453
4e85aff4
LP
1454 free(p->options);
1455 p->options = o;
057d9ab8 1456 o = NULL;
e537352b 1457
4e85aff4
LP
1458 free(p->fstype);
1459 p->fstype = f;
057d9ab8 1460 f = NULL;
b08d03ff 1461
b87705cd
LP
1462 if (load_extras) {
1463 r = mount_add_extras(MOUNT(u));
1464 if (r < 0)
1465 goto fail;
1466 }
1467
ff5f34d0
LP
1468 if (changed)
1469 unit_add_to_dbus_queue(u);
c1e1601e 1470
b08d03ff
LP
1471 return 0;
1472
1473fail:
628c89cc
LP
1474 log_warning_errno(r, "Failed to set up mount unit: %m");
1475
b08d03ff
LP
1476 if (delete && u)
1477 unit_free(u);
1478
4e85aff4 1479 return r;
b08d03ff
LP
1480}
1481
ef734fd6 1482static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
628c89cc
LP
1483 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
1484 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
60b912f6 1485 int r = 0;
b08d03ff
LP
1486
1487 assert(m);
1488
628c89cc
LP
1489 t = mnt_new_table();
1490 if (!t)
8d3ae2bd 1491 return log_oom();
b08d03ff 1492
628c89cc
LP
1493 i = mnt_new_iter(MNT_ITER_FORWARD);
1494 if (!i)
1495 return log_oom();
1496
1497 r = mnt_table_parse_mtab(t, NULL);
5cca8def 1498 if (r < 0)
628c89cc 1499 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
e537352b 1500
5cca8def
ZJS
1501 r = 0;
1502 for (;;) {
8d3ae2bd 1503 const char *device, *path, *options, *fstype;
527b7a42 1504 _cleanup_free_ char *d = NULL, *p = NULL;
628c89cc 1505 struct libmnt_fs *fs;
8d3ae2bd 1506 int k;
b08d03ff 1507
628c89cc 1508 k = mnt_table_next_fs(t, i, &fs);
5cca8def
ZJS
1509 if (k == 1)
1510 break;
628c89cc
LP
1511 if (k < 0)
1512 return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
5cca8def 1513
8d3ae2bd
CL
1514 device = mnt_fs_get_source(fs);
1515 path = mnt_fs_get_target(fs);
1516 options = mnt_fs_get_options(fs);
1517 fstype = mnt_fs_get_fstype(fs);
a2e0f3d3 1518
c0a7f8d3
DM
1519 if (!device || !path)
1520 continue;
1521
527b7a42 1522 if (cunescape(device, UNESCAPE_RELAX, &d) < 0)
628c89cc
LP
1523 return log_oom();
1524
527b7a42 1525 if (cunescape(path, UNESCAPE_RELAX, &p) < 0)
a57f7e2c 1526 return log_oom();
b08d03ff 1527
628c89cc
LP
1528 (void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags);
1529
1530 k = mount_setup_unit(m, d, p, options, fstype, set_flags);
5cca8def 1531 if (r == 0 && k < 0)
60b912f6 1532 r = k;
b08d03ff
LP
1533 }
1534
e537352b
LP
1535 return r;
1536}
1537
1538static void mount_shutdown(Manager *m) {
1539 assert(m);
1540
718db961 1541 m->mount_event_source = sd_event_source_unref(m->mount_event_source);
befb6d54 1542 m->mount_utab_event_source = sd_event_source_unref(m->mount_utab_event_source);
718db961 1543
a16e1123 1544 if (m->proc_self_mountinfo) {
e537352b 1545 fclose(m->proc_self_mountinfo);
a16e1123
LP
1546 m->proc_self_mountinfo = NULL;
1547 }
befb6d54 1548 m->utab_inotify_fd = safe_close(m->utab_inotify_fd);
b08d03ff
LP
1549}
1550
68db7a3b
ZJS
1551static int mount_get_timeout(Unit *u, uint64_t *timeout) {
1552 Mount *m = MOUNT(u);
1553 int r;
1554
1555 if (!m->timer_event_source)
1556 return 0;
1557
1558 r = sd_event_source_get_time(m->timer_event_source, timeout);
1559 if (r < 0)
1560 return r;
1561
1562 return 1;
1563}
1564
b08d03ff
LP
1565static int mount_enumerate(Manager *m) {
1566 int r;
1567 assert(m);
1568
8d3ae2bd
CL
1569 mnt_init_debug(0);
1570
a16e1123 1571 if (!m->proc_self_mountinfo) {
e62d8c39
ZJS
1572 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1573 if (!m->proc_self_mountinfo)
a16e1123 1574 return -errno;
ef734fd6 1575
151b9b96 1576 r = sd_event_add_io(m->event, &m->mount_event_source, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m);
718db961
LP
1577 if (r < 0)
1578 goto fail;
29083707
LP
1579
1580 /* Dispatch this before we dispatch SIGCHLD, so that
1581 * we always get the events from /proc/self/mountinfo
f00929ad 1582 * before the SIGCHLD of /usr/bin/mount. */
29083707
LP
1583 r = sd_event_source_set_priority(m->mount_event_source, -10);
1584 if (r < 0)
1585 goto fail;
7dfbe2e3
TG
1586
1587 (void) sd_event_source_set_description(m->mount_event_source, "mount-mountinfo-dispatch");
a16e1123 1588 }
ef734fd6 1589
befb6d54
CL
1590 if (m->utab_inotify_fd < 0) {
1591 m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
f7c1ad4f
LP
1592 if (m->utab_inotify_fd < 0) {
1593 r = -errno;
1594 goto fail;
1595 }
befb6d54 1596
90598531
ZJS
1597 (void) mkdir_p_label("/run/mount", 0755);
1598
befb6d54 1599 r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
f7c1ad4f
LP
1600 if (r < 0) {
1601 r = -errno;
1602 goto fail;
1603 }
befb6d54
CL
1604
1605 r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
1606 if (r < 0)
1607 goto fail;
1608
1609 r = sd_event_source_set_priority(m->mount_utab_event_source, -10);
1610 if (r < 0)
1611 goto fail;
7dfbe2e3
TG
1612
1613 (void) sd_event_source_set_description(m->mount_utab_event_source, "mount-utab-dispatch");
befb6d54
CL
1614 }
1615
e62d8c39
ZJS
1616 r = mount_load_proc_self_mountinfo(m, false);
1617 if (r < 0)
b08d03ff
LP
1618 goto fail;
1619
1620 return 0;
1621
1622fail:
1623 mount_shutdown(m);
1624 return r;
5cb5a6ff
LP
1625}
1626
718db961 1627static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
fcd8b266 1628 _cleanup_set_free_ Set *around = NULL, *gone = NULL;
718db961 1629 Manager *m = userdata;
fcd8b266
LP
1630 const char *what;
1631 Iterator i;
595ed347 1632 Unit *u;
ef734fd6
LP
1633 int r;
1634
1635 assert(m);
befb6d54 1636 assert(revents & (EPOLLPRI | EPOLLIN));
ef734fd6
LP
1637
1638 /* The manager calls this for every fd event happening on the
1639 * /proc/self/mountinfo file, which informs us about mounting
fddf1a31
ZJS
1640 * table changes, and for /run/mount events which we watch
1641 * for mount options. */
befb6d54
CL
1642
1643 if (fd == m->utab_inotify_fd) {
df63dda6 1644 bool rescan = false;
befb6d54 1645
b7307642
LP
1646 /* FIXME: We *really* need to replace this with
1647 * libmount's own API for this, we should not hardcode
1648 * internal behaviour of libmount here. */
1649
f7c1ad4f 1650 for (;;) {
0254e944 1651 union inotify_event_buffer buffer;
f7c1ad4f
LP
1652 struct inotify_event *e;
1653 ssize_t l;
1654
0254e944 1655 l = read(fd, &buffer, sizeof(buffer));
f7c1ad4f
LP
1656 if (l < 0) {
1657 if (errno == EAGAIN || errno == EINTR)
1658 break;
1659
1660 log_error_errno(errno, "Failed to read utab inotify: %m");
1661 break;
1662 }
1663
1664 FOREACH_INOTIFY_EVENT(e, buffer, l) {
1665 /* Only care about changes to utab,
1666 * but we have to monitor the
1667 * directory to reliably get
1668 * notifications about when utab is
1669 * replaced using rename(2) */
1670 if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab"))
df63dda6 1671 rescan = true;
befb6d54 1672 }
f7c1ad4f 1673 }
fddf1a31 1674
befb6d54
CL
1675 if (!rescan)
1676 return 0;
1677 }
ef734fd6 1678
4f0eedb7
ZJS
1679 r = mount_load_proc_self_mountinfo(m, true);
1680 if (r < 0) {
e537352b 1681 /* Reset flags, just in case, for later calls */
595ed347
MS
1682 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1683 Mount *mount = MOUNT(u);
e537352b
LP
1684
1685 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1686 }
1687
718db961 1688 return 0;
ef734fd6
LP
1689 }
1690
1691 manager_dispatch_load_queue(m);
1692
595ed347
MS
1693 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1694 Mount *mount = MOUNT(u);
ef734fd6 1695
e537352b 1696 if (!mount->is_mounted) {
e537352b 1697
394763f6
LP
1698 /* A mount point is not around right now. It
1699 * might be gone, or might never have
1700 * existed. */
1701
1702 if (mount->from_proc_self_mountinfo &&
1703 mount->parameters_proc_self_mountinfo.what) {
1704
1705 /* Remember that this device might just have disappeared */
1706 if (set_ensure_allocated(&gone, &string_hash_ops) < 0 ||
1707 set_put(gone, mount->parameters_proc_self_mountinfo.what) < 0)
1708 log_oom(); /* we don't care too much about OOM here... */
1709 }
fcd8b266 1710
ef734fd6 1711 mount->from_proc_self_mountinfo = false;
e537352b
LP
1712
1713 switch (mount->state) {
1714
1715 case MOUNT_MOUNTED:
aef83136
LP
1716 /* This has just been unmounted by
1717 * somebody else, follow the state
1718 * change. */
9d2f5178 1719 mount_enter_dead(mount, MOUNT_SUCCESS);
e537352b
LP
1720 break;
1721
1722 default:
e537352b 1723 break;
e537352b
LP
1724 }
1725
1726 } else if (mount->just_mounted || mount->just_changed) {
1727
fcd8b266 1728 /* A mount point was added or changed */
e537352b
LP
1729
1730 switch (mount->state) {
1731
1732 case MOUNT_DEAD:
fdf20a31 1733 case MOUNT_FAILED:
aef83136
LP
1734 /* This has just been mounted by
1735 * somebody else, follow the state
1736 * change. */
9d2f5178 1737 mount_enter_mounted(mount, MOUNT_SUCCESS);
e537352b
LP
1738 break;
1739
1740 case MOUNT_MOUNTING:
5bcb0f2b 1741 mount_set_state(mount, MOUNT_MOUNTING_DONE);
e537352b
LP
1742 break;
1743
1744 default:
1745 /* Nothing really changed, but let's
1746 * issue an notification call
1747 * nonetheless, in case somebody is
1748 * waiting for this. (e.g. file system
1749 * ro/rw remounts.) */
1750 mount_set_state(mount, mount->state);
1751 break;
1752 }
394763f6 1753 }
fcd8b266 1754
394763f6
LP
1755 if (mount->is_mounted &&
1756 mount->from_proc_self_mountinfo &&
1757 mount->parameters_proc_self_mountinfo.what) {
fcd8b266 1758
394763f6
LP
1759 if (set_ensure_allocated(&around, &string_hash_ops) < 0 ||
1760 set_put(around, mount->parameters_proc_self_mountinfo.what) < 0)
1761 log_oom();
e537352b
LP
1762 }
1763
1764 /* Reset the flags for later calls */
1765 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1766 }
718db961 1767
fcd8b266
LP
1768 SET_FOREACH(what, gone, i) {
1769 if (set_contains(around, what))
1770 continue;
1771
1772 /* Let the device units know that the device is no longer mounted */
1773 (void) device_found_node(m, what, false, DEVICE_FOUND_MOUNT, true);
1774 }
1775
718db961 1776 return 0;
e537352b
LP
1777}
1778
fdf20a31 1779static void mount_reset_failed(Unit *u) {
5632e374
LP
1780 Mount *m = MOUNT(u);
1781
1782 assert(m);
1783
fdf20a31 1784 if (m->state == MOUNT_FAILED)
5632e374
LP
1785 mount_set_state(m, MOUNT_DEAD);
1786
9d2f5178
LP
1787 m->result = MOUNT_SUCCESS;
1788 m->reload_result = MOUNT_SUCCESS;
5632e374
LP
1789}
1790
718db961 1791static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
814cc562 1792 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
8a0867d6
LP
1793}
1794
a16e1123
LP
1795static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1796 [MOUNT_DEAD] = "dead",
1797 [MOUNT_MOUNTING] = "mounting",
1798 [MOUNT_MOUNTING_DONE] = "mounting-done",
1799 [MOUNT_MOUNTED] = "mounted",
1800 [MOUNT_REMOUNTING] = "remounting",
1801 [MOUNT_UNMOUNTING] = "unmounting",
1802 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1803 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1804 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1805 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1806 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1807 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
fdf20a31 1808 [MOUNT_FAILED] = "failed"
a16e1123
LP
1809};
1810
1811DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1812
1813static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1814 [MOUNT_EXEC_MOUNT] = "ExecMount",
1815 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1816 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1817};
1818
1819DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1820
9d2f5178
LP
1821static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1822 [MOUNT_SUCCESS] = "success",
1823 [MOUNT_FAILURE_RESOURCES] = "resources",
1824 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1825 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1826 [MOUNT_FAILURE_SIGNAL] = "signal",
1827 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1828};
1829
1830DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1831
87f0e418 1832const UnitVTable mount_vtable = {
7d17cfbc 1833 .object_size = sizeof(Mount),
718db961
LP
1834 .exec_context_offset = offsetof(Mount, exec_context),
1835 .cgroup_context_offset = offsetof(Mount, cgroup_context),
1836 .kill_context_offset = offsetof(Mount, kill_context),
613b411c 1837 .exec_runtime_offset = offsetof(Mount, exec_runtime),
3ef63c31 1838
f975e971
LP
1839 .sections =
1840 "Unit\0"
1841 "Mount\0"
1842 "Install\0",
4ad49000 1843 .private_section = "Mount",
71645aca 1844
e537352b 1845 .no_alias = true,
9e2f7c11 1846 .no_instances = true,
e537352b
LP
1847
1848 .init = mount_init,
1849 .load = mount_load,
034c6ed7 1850 .done = mount_done,
e537352b 1851
f50e0a01
LP
1852 .coldplug = mount_coldplug,
1853
034c6ed7 1854 .dump = mount_dump,
5cb5a6ff 1855
e537352b
LP
1856 .start = mount_start,
1857 .stop = mount_stop,
1858 .reload = mount_reload,
1859
8a0867d6
LP
1860 .kill = mount_kill,
1861
a16e1123
LP
1862 .serialize = mount_serialize,
1863 .deserialize_item = mount_deserialize_item,
1864
f50e0a01 1865 .active_state = mount_active_state,
10a94420 1866 .sub_state_to_string = mount_sub_state_to_string,
b08d03ff 1867
701cc384
LP
1868 .check_gc = mount_check_gc,
1869
e537352b 1870 .sigchld_event = mount_sigchld_event,
e537352b 1871
fdf20a31 1872 .reset_failed = mount_reset_failed,
5632e374 1873
718db961 1874 .bus_vtable = bus_mount_vtable,
74c964d3
LP
1875 .bus_set_property = bus_mount_set_property,
1876 .bus_commit_properties = bus_mount_commit_properties,
4139c1b2 1877
68db7a3b
ZJS
1878 .get_timeout = mount_get_timeout,
1879
0e252f6b
TG
1880 .can_transient = true,
1881
f50e0a01 1882 .enumerate = mount_enumerate,
c6918296
MS
1883 .shutdown = mount_shutdown,
1884
1885 .status_message_formats = {
1886 .starting_stopping = {
1887 [0] = "Mounting %s...",
1888 [1] = "Unmounting %s...",
1889 },
1890 .finished_start_job = {
1891 [JOB_DONE] = "Mounted %s.",
1892 [JOB_FAILED] = "Failed to mount %s.",
c6918296
MS
1893 [JOB_TIMEOUT] = "Timed out mounting %s.",
1894 },
1895 .finished_stop_job = {
1896 [JOB_DONE] = "Unmounted %s.",
1897 [JOB_FAILED] = "Failed unmounting %s.",
1898 [JOB_TIMEOUT] = "Timed out unmounting %s.",
1899 },
1900 },
5cb5a6ff 1901};