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