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