]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/mount.c
dbus: typo fix in log
[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
11041c84 105 /* Quotas are not enabled on network filesystems,
340a1d23 106 * but we want them, for example, on storage connected via iscsi */
11041c84 107 if (p->fstype && fstype_is_network(p->fstype))
fc676b00
ZJS
108 return false;
109
110 if (mount_is_bind(p))
111 return false;
112
d15d0333
ZJS
113 return fstab_test_option(p->options,
114 "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
fc676b00
ZJS
115}
116
a16e1123
LP
117static void mount_init(Unit *u) {
118 Mount *m = MOUNT(u);
5cb5a6ff 119
a16e1123 120 assert(u);
ac155bb8 121 assert(u->load_state == UNIT_STUB);
a16e1123 122
1f19a534 123 m->timeout_usec = u->manager->default_timeout_start_usec;
3e5235b0
LP
124 m->directory_mode = 0755;
125
6b1dc2bd
LP
126 if (unit_has_name(u, "-.mount")) {
127 /* Don't allow start/stop for root directory */
5bcb0f2b
LP
128 u->refuse_manual_start = true;
129 u->refuse_manual_stop = true;
6b1dc2bd
LP
130 } else {
131 /* The stdio/kmsg bridge socket is on /, in order to avoid a
132 * dep loop, don't use kmsg logging for -.mount */
ac155bb8
MS
133 m->exec_context.std_output = u->manager->default_std_output;
134 m->exec_context.std_error = u->manager->default_std_error;
f6cebb3b 135 }
c3686083 136
a16e1123
LP
137 /* We need to make sure that /bin/mount is always called in
138 * the same process group as us, so that the autofs kernel
139 * side doesn't send us another mount request while we are
140 * already trying to comply its last one. */
74922904 141 m->exec_context.same_pgrp = true;
8d567588 142
a16e1123 143 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
c8f4d764 144
5bcb0f2b 145 u->ignore_on_isolate = true;
8d567588
LP
146}
147
718db961
LP
148static int mount_arm_timer(Mount *m) {
149 int r;
150
151 assert(m);
152
153 if (m->timeout_usec <= 0) {
154 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
155 return 0;
156 }
157
158 if (m->timer_event_source) {
159 r = sd_event_source_set_time(m->timer_event_source, now(CLOCK_MONOTONIC) + m->timeout_usec);
160 if (r < 0)
161 return r;
162
163 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
164 }
165
6a0f1f6d
LP
166 return sd_event_add_time(
167 UNIT(m)->manager->event,
168 &m->timer_event_source,
169 CLOCK_MONOTONIC,
170 now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
171 mount_dispatch_timer, m);
718db961
LP
172}
173
a16e1123 174static void mount_unwatch_control_pid(Mount *m) {
5e94833f
LP
175 assert(m);
176
177 if (m->control_pid <= 0)
178 return;
179
180 unit_unwatch_pid(UNIT(m), m->control_pid);
181 m->control_pid = 0;
182}
183
e537352b
LP
184static void mount_parameters_done(MountParameters *p) {
185 assert(p);
186
187 free(p->what);
188 free(p->options);
189 free(p->fstype);
190
191 p->what = p->options = p->fstype = NULL;
192}
193
87f0e418 194static void mount_done(Unit *u) {
ef734fd6 195 Mount *m = MOUNT(u);
034c6ed7 196
ef734fd6 197 assert(m);
034c6ed7 198
e537352b
LP
199 free(m->where);
200 m->where = NULL;
f50e0a01 201
e537352b
LP
202 mount_parameters_done(&m->parameters_proc_self_mountinfo);
203 mount_parameters_done(&m->parameters_fragment);
ef734fd6 204
613b411c 205 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
e537352b
LP
206 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
207 m->control_command = NULL;
f50e0a01 208
a16e1123 209 mount_unwatch_control_pid(m);
f50e0a01 210
718db961 211 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
f50e0a01
LP
212}
213
44a6b1b6 214_pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
cb39ed3f
LP
215 assert(m);
216
217 if (m->from_fragment)
218 return &m->parameters_fragment;
cb39ed3f
LP
219
220 return NULL;
221}
222
44a6b1b6 223_pure_ static MountParameters* get_mount_parameters(Mount *m) {
cb39ed3f
LP
224 assert(m);
225
226 if (m->from_proc_self_mountinfo)
227 return &m->parameters_proc_self_mountinfo;
228
6b1dc2bd 229 return get_mount_parameters_fragment(m);
cb39ed3f
LP
230}
231
6e2ef85b 232static int mount_add_mount_links(Mount *m) {
a57f7e2c 233 _cleanup_free_ char *parent = NULL;
5c78d8e2 234 MountParameters *pm;
ac155bb8 235 Unit *other;
a57f7e2c
LP
236 Iterator i;
237 Set *s;
b08d03ff
LP
238 int r;
239
6e2ef85b 240 assert(m);
b08d03ff 241
a57f7e2c
LP
242 if (!path_equal(m->where, "/")) {
243 /* Adds in links to other mount points that might lie further
244 * up in the hierarchy */
245 r = path_get_parent(m->where, &parent);
4f0eedb7 246 if (r < 0)
6e2ef85b 247 return r;
01f78473 248
a57f7e2c 249 r = unit_require_mounts_for(UNIT(m), parent);
4f0eedb7 250 if (r < 0)
01f78473 251 return r;
4f0eedb7 252 }
01f78473 253
a57f7e2c
LP
254 /* Adds in links to other mount points that might be needed
255 * for the source path (if this is a bind mount) to be
256 * available. */
257 pm = get_mount_parameters_fragment(m);
fc676b00
ZJS
258 if (pm && pm->what &&
259 path_is_absolute(pm->what) &&
260 !mount_is_network(pm)) {
261
a57f7e2c 262 r = unit_require_mounts_for(UNIT(m), pm->what);
4f0eedb7 263 if (r < 0)
6e2ef85b 264 return r;
4f0eedb7 265 }
b08d03ff 266
a57f7e2c
LP
267 /* Adds in links to other units that use this path or paths
268 * further down in the hierarchy */
269 s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
270 SET_FOREACH(other, s, i) {
b08d03ff 271
a57f7e2c
LP
272 if (other->load_state != UNIT_LOADED)
273 continue;
b08d03ff 274
a57f7e2c
LP
275 if (other == UNIT(m))
276 continue;
b08d03ff 277
a57f7e2c 278 r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
4f0eedb7 279 if (r < 0)
6e2ef85b 280 return r;
b08d03ff 281
a57f7e2c
LP
282 if (UNIT(m)->fragment_path) {
283 /* If we have fragment configuration, then make this dependency required */
284 r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
285 if (r < 0)
286 return r;
287 }
7c8fa05c
LP
288 }
289
290 return 0;
291}
292
173a8d04
LP
293static int mount_add_device_links(Mount *m) {
294 MountParameters *p;
5073f89f 295 bool device_wants_mount = false;
9fff8a1f 296 int r;
173a8d04
LP
297
298 assert(m);
299
06e97888 300 p = get_mount_parameters(m);
6b1dc2bd 301 if (!p)
173a8d04
LP
302 return 0;
303
9fff8a1f 304 if (!p->what)
173a8d04 305 return 0;
5c78d8e2 306
dd144c63
LP
307 if (mount_is_bind(p))
308 return 0;
309
310 if (!is_device_path(p->what))
311 return 0;
312
313 if (path_equal(m->where, "/"))
314 return 0;
315
5073f89f
TG
316 if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
317 device_wants_mount = true;
318
319 r = unit_add_node_link(UNIT(m), p->what, device_wants_mount);
dd144c63
LP
320 if (r < 0)
321 return r;
9fff8a1f 322
9fff8a1f 323 return 0;
173a8d04
LP
324}
325
6b1dc2bd
LP
326static int mount_add_quota_links(Mount *m) {
327 int r;
328 MountParameters *p;
329
330 assert(m);
331
67445f4e 332 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
6b1dc2bd
LP
333 return 0;
334
335 p = get_mount_parameters_fragment(m);
336 if (!p)
337 return 0;
338
339 if (!needs_quota(p))
340 return 0;
341
342 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
343 if (r < 0)
344 return r;
345
346 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
347 if (r < 0)
348 return r;
349
350 return 0;
351}
352
88ac30a1
TG
353static bool should_umount(Mount *m) {
354 MountParameters *p;
355
356 if (path_equal(m->where, "/") ||
357 path_equal(m->where, "/usr"))
358 return false;
359
360 p = get_mount_parameters(m);
d15d0333 361 if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
88ac30a1
TG
362 !in_initrd())
363 return false;
364
365 return true;
366}
367
2edd4434 368static int mount_add_default_dependencies(Mount *m) {
0c17fbce 369 const char *after, *after2, *online;
9ddc4a26 370 MountParameters *p;
0c17fbce 371 int r;
2edd4434
LP
372
373 assert(m);
374
67445f4e 375 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
9ddc4a26 376 return 0;
cb39ed3f 377
874d3404
LP
378 /* We do not add any default dependencies to / and /usr, since
379 * they are guaranteed to stay mounted the whole time, since
380 * our system is on it. Also, don't bother with anything
381 * mounted below virtual file systems, it's also going to be
382 * virtual, and hence not worth the effort. */
383 if (path_equal(m->where, "/") ||
384 path_equal(m->where, "/usr") ||
385 path_startswith(m->where, "/proc") ||
386 path_startswith(m->where, "/sys") ||
387 path_startswith(m->where, "/dev"))
6b1dc2bd 388 return 0;
2edd4434 389
874d3404
LP
390 p = get_mount_parameters(m);
391 if (!p)
6b1dc2bd
LP
392 return 0;
393
e8d2f6cd 394 if (mount_is_network(p)) {
6b1dc2bd 395 after = SPECIAL_REMOTE_FS_PRE_TARGET;
a63a5c46 396 after2 = SPECIAL_NETWORK_TARGET;
0c17fbce 397 online = SPECIAL_NETWORK_ONLINE_TARGET;
e8d2f6cd 398 } else {
6b1dc2bd 399 after = SPECIAL_LOCAL_FS_PRE_TARGET;
a63a5c46 400 after2 = NULL;
0c17fbce 401 online = NULL;
e8d2f6cd 402 }
6b1dc2bd 403
e8d2f6cd 404 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
6b1dc2bd
LP
405 if (r < 0)
406 return r;
407
a63a5c46
LP
408 if (after2) {
409 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
410 if (r < 0)
411 return r;
412 }
413
0c17fbce
LP
414 if (online) {
415 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
e8d2f6cd
LP
416 if (r < 0)
417 return r;
418 }
419
88ac30a1
TG
420 if (should_umount(m)) {
421 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
422 if (r < 0)
423 return r;
424 }
2edd4434
LP
425
426 return 0;
427}
428
8d567588 429static int mount_verify(Mount *m) {
a57f7e2c 430 _cleanup_free_ char *e = NULL;
8d567588 431 bool b;
a57f7e2c 432
8d567588
LP
433 assert(m);
434
1124fe6f 435 if (UNIT(m)->load_state != UNIT_LOADED)
8d567588
LP
436 return 0;
437
6b1dc2bd 438 if (!m->from_fragment && !m->from_proc_self_mountinfo)
8cbef760
LP
439 return -ENOENT;
440
a57f7e2c
LP
441 e = unit_name_from_path(m->where, ".mount");
442 if (!e)
8d567588
LP
443 return -ENOMEM;
444
445 b = unit_has_name(UNIT(m), e);
8d567588 446 if (!b) {
79008bdd 447 log_unit_error(UNIT(m)->id, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m)->id);
8d567588
LP
448 return -EINVAL;
449 }
450
33ff02c9 451 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
79008bdd 452 log_unit_error(UNIT(m)->id, "Cannot create mount unit for API file system %s. Refusing.", m->where);
33ff02c9
LP
453 return -EINVAL;
454 }
455
1124fe6f 456 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
79008bdd 457 log_unit_error(UNIT(m)->id, "%s's What setting is missing. Refusing.", UNIT(m)->id);
4e85aff4
LP
458 return -EBADMSG;
459 }
460
4819ff03 461 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
79008bdd 462 log_unit_error(UNIT(m)->id, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m)->id);
4d0e5dbd
LP
463 return -EINVAL;
464 }
465
8d567588
LP
466 return 0;
467}
468
1a4ac875
MS
469static int mount_add_extras(Mount *m) {
470 Unit *u = UNIT(m);
e537352b
LP
471 int r;
472
e821075a
LP
473 assert(m);
474
475 if (u->fragment_path)
1a4ac875 476 m->from_fragment = true;
e537352b 477
1a4ac875
MS
478 if (!m->where) {
479 m->where = unit_name_to_path(u->id);
a16e1123 480 if (!m->where)
1a4ac875
MS
481 return -ENOMEM;
482 }
a16e1123 483
1a4ac875 484 path_kill_slashes(m->where);
e537352b 485
e821075a 486 if (!u->description) {
1a4ac875
MS
487 r = unit_set_description(u, m->where);
488 if (r < 0)
173a8d04 489 return r;
1a4ac875 490 }
6e2ef85b 491
1a4ac875
MS
492 r = mount_add_device_links(m);
493 if (r < 0)
494 return r;
6e2ef85b 495
1a4ac875
MS
496 r = mount_add_mount_links(m);
497 if (r < 0)
498 return r;
6e2ef85b 499
1a4ac875
MS
500 r = mount_add_quota_links(m);
501 if (r < 0)
502 return r;
e537352b 503
598459ce
LP
504 r = unit_patch_contexts(u);
505 if (r < 0)
506 return r;
4e67ddd6 507
598459ce 508 r = unit_add_exec_dependencies(u, &m->exec_context);
a016b922
LP
509 if (r < 0)
510 return r;
511
598459ce 512 r = unit_add_default_slice(u, &m->cgroup_context);
1a4ac875
MS
513 if (r < 0)
514 return r;
515
598459ce
LP
516 if (u->default_dependencies) {
517 r = mount_add_default_dependencies(m);
518 if (r < 0)
519 return r;
520 }
521
1a4ac875
MS
522 return 0;
523}
524
525static int mount_load(Unit *u) {
526 Mount *m = MOUNT(u);
527 int r;
528
529 assert(u);
530 assert(u->load_state == UNIT_STUB);
531
8eba616f
MS
532 if (m->from_proc_self_mountinfo)
533 r = unit_load_fragment_and_dropin_optional(u);
534 else
535 r = unit_load_fragment_and_dropin(u);
536
1a4ac875
MS
537 if (r < 0)
538 return r;
155da457 539
1a4ac875
MS
540 /* This is a new unit? Then let's add in some extras */
541 if (u->load_state == UNIT_LOADED) {
542 r = mount_add_extras(m);
543 if (r < 0)
544 return r;
e537352b
LP
545 }
546
8d567588 547 return mount_verify(m);
e537352b
LP
548}
549
a16e1123
LP
550static int mount_notify_automount(Mount *m, int status) {
551 Unit *p;
552 int r;
57020a3a 553 Iterator i;
a16e1123
LP
554
555 assert(m);
556
1124fe6f 557 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
ac155bb8 558 if (p->type == UNIT_AUTOMOUNT) {
57020a3a
LP
559 r = automount_send_ready(AUTOMOUNT(p), status);
560 if (r < 0)
561 return r;
562 }
a16e1123 563
57020a3a 564 return 0;
a16e1123
LP
565}
566
e537352b
LP
567static void mount_set_state(Mount *m, MountState state) {
568 MountState old_state;
569 assert(m);
570
571 old_state = m->state;
572 m->state = state;
573
574 if (state != MOUNT_MOUNTING &&
575 state != MOUNT_MOUNTING_DONE &&
576 state != MOUNT_REMOUNTING &&
577 state != MOUNT_UNMOUNTING &&
578 state != MOUNT_MOUNTING_SIGTERM &&
579 state != MOUNT_MOUNTING_SIGKILL &&
580 state != MOUNT_UNMOUNTING_SIGTERM &&
581 state != MOUNT_UNMOUNTING_SIGKILL &&
582 state != MOUNT_REMOUNTING_SIGTERM &&
583 state != MOUNT_REMOUNTING_SIGKILL) {
718db961 584 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
a16e1123 585 mount_unwatch_control_pid(m);
e537352b 586 m->control_command = NULL;
a16e1123 587 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
e537352b
LP
588 }
589
8d567588
LP
590 if (state == MOUNT_MOUNTED ||
591 state == MOUNT_REMOUNTING)
592 mount_notify_automount(m, 0);
593 else if (state == MOUNT_DEAD ||
594 state == MOUNT_UNMOUNTING ||
595 state == MOUNT_MOUNTING_SIGTERM ||
596 state == MOUNT_MOUNTING_SIGKILL ||
597 state == MOUNT_REMOUNTING_SIGTERM ||
598 state == MOUNT_REMOUNTING_SIGKILL ||
599 state == MOUNT_UNMOUNTING_SIGTERM ||
600 state == MOUNT_UNMOUNTING_SIGKILL ||
36fcd77e 601 state == MOUNT_FAILED) {
b929bf04
TA
602 if (state != old_state)
603 mount_notify_automount(m, -ENODEV);
604 }
8d567588 605
e537352b 606 if (state != old_state)
79008bdd 607 log_unit_debug(UNIT(m)->id,
66870f90
ZJS
608 "%s changed %s -> %s",
609 UNIT(m)->id,
610 mount_state_to_string(old_state),
611 mount_state_to_string(state));
e537352b 612
9d2f5178
LP
613 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
614 m->reload_result = MOUNT_SUCCESS;
e537352b
LP
615}
616
6e392c9c 617static int mount_coldplug(Unit *u, Hashmap *deferred_work) {
e537352b 618 Mount *m = MOUNT(u);
a16e1123
LP
619 MountState new_state = MOUNT_DEAD;
620 int r;
e537352b
LP
621
622 assert(m);
623 assert(m->state == MOUNT_DEAD);
624
a16e1123
LP
625 if (m->deserialized_state != m->state)
626 new_state = m->deserialized_state;
627 else if (m->from_proc_self_mountinfo)
628 new_state = MOUNT_MOUNTED;
e537352b 629
5bcb0f2b
LP
630 if (new_state == m->state)
631 return 0;
e537352b 632
5bcb0f2b
LP
633 if (new_state == MOUNT_MOUNTING ||
634 new_state == MOUNT_MOUNTING_DONE ||
635 new_state == MOUNT_REMOUNTING ||
636 new_state == MOUNT_UNMOUNTING ||
637 new_state == MOUNT_MOUNTING_SIGTERM ||
638 new_state == MOUNT_MOUNTING_SIGKILL ||
639 new_state == MOUNT_UNMOUNTING_SIGTERM ||
640 new_state == MOUNT_UNMOUNTING_SIGKILL ||
641 new_state == MOUNT_REMOUNTING_SIGTERM ||
642 new_state == MOUNT_REMOUNTING_SIGKILL) {
643
644 if (m->control_pid <= 0)
645 return -EBADMSG;
646
647 r = unit_watch_pid(UNIT(m), m->control_pid);
648 if (r < 0)
649 return r;
e537352b 650
5bcb0f2b
LP
651 r = mount_arm_timer(m);
652 if (r < 0)
653 return r;
a16e1123 654 }
e537352b 655
5bcb0f2b 656 mount_set_state(m, new_state);
e537352b 657 return 0;
e537352b
LP
658}
659
660static void mount_dump(Unit *u, FILE *f, const char *prefix) {
661 Mount *m = MOUNT(u);
662 MountParameters *p;
663
664 assert(m);
665 assert(f);
666
cb39ed3f 667 p = get_mount_parameters(m);
e537352b
LP
668
669 fprintf(f,
670 "%sMount State: %s\n"
81a5c6d0 671 "%sResult: %s\n"
e537352b
LP
672 "%sWhere: %s\n"
673 "%sWhat: %s\n"
674 "%sFile System Type: %s\n"
675 "%sOptions: %s\n"
e537352b
LP
676 "%sFrom /proc/self/mountinfo: %s\n"
677 "%sFrom fragment: %s\n"
3e5235b0 678 "%sDirectoryMode: %04o\n",
a16e1123 679 prefix, mount_state_to_string(m->state),
81a5c6d0 680 prefix, mount_result_to_string(m->result),
e537352b 681 prefix, m->where,
1e4fc9b1
HH
682 prefix, p ? strna(p->what) : "n/a",
683 prefix, p ? strna(p->fstype) : "n/a",
684 prefix, p ? strna(p->options) : "n/a",
e537352b
LP
685 prefix, yes_no(m->from_proc_self_mountinfo),
686 prefix, yes_no(m->from_fragment),
3e5235b0 687 prefix, m->directory_mode);
e537352b
LP
688
689 if (m->control_pid > 0)
690 fprintf(f,
ccd06097
ZJS
691 "%sControl PID: "PID_FMT"\n",
692 prefix, m->control_pid);
e537352b
LP
693
694 exec_context_dump(&m->exec_context, f, prefix);
4819ff03 695 kill_context_dump(&m->kill_context, f, prefix);
e537352b
LP
696}
697
a16e1123
LP
698static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
699 pid_t pid;
700 int r;
9fa95f85
DM
701 ExecParameters exec_params = {
702 .apply_permissions = true,
703 .apply_chroot = true,
704 .apply_tty_stdin = true,
705 };
a16e1123
LP
706
707 assert(m);
708 assert(c);
709 assert(_pid);
710
5ad096b3
LP
711 (void) unit_realize_cgroup(UNIT(m));
712 if (m->reset_cpu_usage) {
713 (void) unit_reset_cpu_usage(UNIT(m));
714 m->reset_cpu_usage = false;
715 }
4ad49000 716
613b411c
LP
717 r = unit_setup_exec_runtime(UNIT(m));
718 if (r < 0)
719 goto fail;
720
718db961 721 r = mount_arm_timer(m);
36697dc0 722 if (r < 0)
a16e1123
LP
723 goto fail;
724
9fa95f85
DM
725 exec_params.environment = UNIT(m)->manager->environment;
726 exec_params.confirm_spawn = UNIT(m)->manager->confirm_spawn;
727 exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
728 exec_params.cgroup_path = UNIT(m)->cgroup_path;
a931ad47 729 exec_params.cgroup_delegate = m->cgroup_context.delegate;
9fa95f85
DM
730 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(m)->manager);
731 exec_params.unit_id = UNIT(m)->id;
732
4ad49000 733 r = exec_spawn(c,
4ad49000 734 &m->exec_context,
9fa95f85 735 &exec_params,
613b411c 736 m->exec_runtime,
4ad49000
LP
737 &pid);
738 if (r < 0)
a16e1123
LP
739 goto fail;
740
4ad49000
LP
741 r = unit_watch_pid(UNIT(m), pid);
742 if (r < 0)
a16e1123
LP
743 /* FIXME: we need to do something here */
744 goto fail;
745
746 *_pid = pid;
747
748 return 0;
749
750fail:
718db961 751 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
a16e1123
LP
752
753 return r;
754}
755
9d2f5178 756static void mount_enter_dead(Mount *m, MountResult f) {
e537352b
LP
757 assert(m);
758
9d2f5178
LP
759 if (f != MOUNT_SUCCESS)
760 m->result = f;
e537352b 761
613b411c
LP
762 exec_runtime_destroy(m->exec_runtime);
763 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
764
e66cf1a3
LP
765 exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
766
9d2f5178 767 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
e537352b
LP
768}
769
9d2f5178 770static void mount_enter_mounted(Mount *m, MountResult f) {
80876c20
LP
771 assert(m);
772
9d2f5178
LP
773 if (f != MOUNT_SUCCESS)
774 m->result = f;
80876c20
LP
775
776 mount_set_state(m, MOUNT_MOUNTED);
777}
778
9d2f5178 779static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
e537352b
LP
780 int r;
781
782 assert(m);
783
9d2f5178
LP
784 if (f != MOUNT_SUCCESS)
785 m->result = f;
e537352b 786
cd2086fe
LP
787 r = unit_kill_context(
788 UNIT(m),
789 &m->kill_context,
db2cb23b
UTL
790 (state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM) ?
791 KILL_KILL : KILL_TERMINATE,
cd2086fe
LP
792 -1,
793 m->control_pid,
794 false);
795 if (r < 0)
796 goto fail;
e537352b 797
cd2086fe 798 if (r > 0) {
718db961 799 r = mount_arm_timer(m);
36697dc0 800 if (r < 0)
80876c20 801 goto fail;
e537352b 802
80876c20 803 mount_set_state(m, state);
ac84d1fb
LP
804 } else if (state == MOUNT_REMOUNTING_SIGTERM)
805 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
806 else if (state == MOUNT_REMOUNTING_SIGKILL)
9d2f5178 807 mount_enter_mounted(m, MOUNT_SUCCESS);
ac84d1fb
LP
808 else if (state == MOUNT_MOUNTING_SIGTERM)
809 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS);
810 else if (state == MOUNT_UNMOUNTING_SIGTERM)
811 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
80876c20 812 else
9d2f5178 813 mount_enter_dead(m, MOUNT_SUCCESS);
e537352b
LP
814
815 return;
816
817fail:
79008bdd 818 log_unit_warning(UNIT(m)->id,
66870f90 819 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
e537352b 820
80876c20 821 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
9d2f5178 822 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
80876c20 823 else
9d2f5178 824 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
825}
826
20ad4cfd 827void warn_if_dir_nonempty(const char *unit, const char* where) {
056edeb9
ZJS
828 int r;
829
cd2086fe
LP
830 assert(unit);
831 assert(where);
832
056edeb9
ZJS
833 r = dir_is_empty(where);
834 if (r > 0)
20ad4cfd 835 return;
056edeb9 836 else if (r == 0)
e2cc6eca
LP
837 log_unit_struct(unit,
838 LOG_NOTICE,
839 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
840 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
841 unit, where),
056edeb9 842 "WHERE=%s", where,
056edeb9
ZJS
843 NULL);
844 else
79008bdd 845 log_unit_warning(unit,
056edeb9
ZJS
846 "MESSAGE=Failed to check directory %s: %s",
847 where, strerror(-r));
20ad4cfd
ZJS
848}
849
5261ba90
TT
850static int fail_if_symlink(const char *unit, const char* where) {
851 assert(where);
852
853 if (is_symlink(where) > 0) {
e2cc6eca
LP
854 log_unit_struct(unit,
855 LOG_ERR,
856 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
857 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
858 unit, where),
5261ba90 859 "WHERE=%s", where,
5261ba90
TT
860 NULL);
861
862 return -ELOOP;
863 }
864 return 0;
865}
866
9d2f5178 867static void mount_enter_unmounting(Mount *m) {
e537352b
LP
868 int r;
869
870 assert(m);
871
7d54a03a
LP
872 /* Start counting our attempts */
873 if (!IN_SET(m->state,
874 MOUNT_UNMOUNTING,
875 MOUNT_UNMOUNTING_SIGTERM,
876 MOUNT_UNMOUNTING_SIGKILL))
877 m->n_retry_umount = 0;
878
a16e1123
LP
879 m->control_command_id = MOUNT_EXEC_UNMOUNT;
880 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
e537352b 881
e86b3761
ZJS
882 r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
883 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
884 r = exec_command_append(m->control_command, "-n", NULL);
7d54a03a 885 if (r < 0)
e537352b
LP
886 goto fail;
887
a16e1123 888 mount_unwatch_control_pid(m);
5e94833f 889
7d54a03a
LP
890 r = mount_spawn(m, m->control_command, &m->control_pid);
891 if (r < 0)
e537352b
LP
892 goto fail;
893
894 mount_set_state(m, MOUNT_UNMOUNTING);
895
896 return;
897
898fail:
79008bdd 899 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
900 "%s failed to run 'umount' task: %s",
901 UNIT(m)->id, strerror(-r));
9d2f5178 902 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
903}
904
8d567588 905static void mount_enter_mounting(Mount *m) {
e537352b 906 int r;
cb39ed3f 907 MountParameters *p;
e537352b
LP
908
909 assert(m);
910
a16e1123
LP
911 m->control_command_id = MOUNT_EXEC_MOUNT;
912 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
e537352b 913
d2e54fae 914 mkdir_p_label(m->where, m->directory_mode);
3e5235b0 915
20ad4cfd 916 warn_if_dir_nonempty(m->meta.id, m->where);
257f1d8e 917
cb39ed3f 918 /* Create the source directory for bind-mounts if needed */
6b1dc2bd 919 p = get_mount_parameters_fragment(m);
cb39ed3f 920 if (p && mount_is_bind(p))
d2e54fae 921 mkdir_p_label(p->what, m->directory_mode);
2b583ce6 922
5261ba90
TT
923 r = fail_if_symlink(m->meta.id, m->where);
924 if (r < 0)
925 goto fail;
926
e86b3761 927 if (m->from_fragment) {
17a1c597
ZJS
928 _cleanup_free_ char *opts = NULL;
929
930 r = fstab_filter_options(m->parameters_fragment.options,
76c37ab6 931 "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
17a1c597
ZJS
932 if (r < 0)
933 goto fail;
934
e86b3761
ZJS
935 r = exec_command_set(m->control_command, "/bin/mount",
936 m->parameters_fragment.what, m->where, NULL);
937 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
938 r = exec_command_append(m->control_command, "-n", NULL);
939 if (r >= 0 && m->sloppy_options)
940 r = exec_command_append(m->control_command, "-s", NULL);
941 if (r >= 0 && m->parameters_fragment.fstype)
942 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
0c47569a 943 if (r >= 0 && !isempty(opts))
17a1c597 944 r = exec_command_append(m->control_command, "-o", opts, NULL);
e86b3761 945 } else
e537352b
LP
946 r = -ENOENT;
947
948 if (r < 0)
949 goto fail;
950
a16e1123 951 mount_unwatch_control_pid(m);
5e94833f 952
257f1d8e
LP
953 r = mount_spawn(m, m->control_command, &m->control_pid);
954 if (r < 0)
e537352b
LP
955 goto fail;
956
957 mount_set_state(m, MOUNT_MOUNTING);
958
959 return;
960
961fail:
79008bdd 962 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
963 "%s failed to run 'mount' task: %s",
964 UNIT(m)->id, strerror(-r));
9d2f5178 965 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
e537352b
LP
966}
967
9d2f5178 968static void mount_enter_remounting(Mount *m) {
e537352b
LP
969 int r;
970
971 assert(m);
972
a16e1123
LP
973 m->control_command_id = MOUNT_EXEC_REMOUNT;
974 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
e537352b
LP
975
976 if (m->from_fragment) {
e537352b
LP
977 const char *o;
978
718db961 979 if (m->parameters_fragment.options)
63c372cb 980 o = strjoina("remount,", m->parameters_fragment.options);
718db961 981 else
e537352b
LP
982 o = "remount";
983
e86b3761
ZJS
984 r = exec_command_set(m->control_command, "/bin/mount",
985 m->parameters_fragment.what, m->where,
986 "-o", o, NULL);
987 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
988 r = exec_command_append(m->control_command, "-n", NULL);
989 if (r >= 0 && m->sloppy_options)
990 r = exec_command_append(m->control_command, "-s", NULL);
991 if (r >= 0 && m->parameters_fragment.fstype)
992 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
6b1dc2bd 993 } else
e537352b
LP
994 r = -ENOENT;
995
60b912f6 996 if (r < 0)
e537352b 997 goto fail;
e537352b 998
a16e1123 999 mount_unwatch_control_pid(m);
5e94833f 1000
718db961
LP
1001 r = mount_spawn(m, m->control_command, &m->control_pid);
1002 if (r < 0)
e537352b
LP
1003 goto fail;
1004
1005 mount_set_state(m, MOUNT_REMOUNTING);
1006
1007 return;
1008
1009fail:
79008bdd 1010 log_unit_warning(UNIT(m)->id,
66870f90
ZJS
1011 "%s failed to run 'remount' task: %s",
1012 UNIT(m)->id, strerror(-r));
9d2f5178
LP
1013 m->reload_result = MOUNT_FAILURE_RESOURCES;
1014 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
1015}
1016
1017static int mount_start(Unit *u) {
1018 Mount *m = MOUNT(u);
1019
1020 assert(m);
1021
1022 /* We cannot fulfill this request right now, try again later
1023 * please! */
1024 if (m->state == MOUNT_UNMOUNTING ||
1025 m->state == MOUNT_UNMOUNTING_SIGTERM ||
60b912f6
LP
1026 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1027 m->state == MOUNT_MOUNTING_SIGTERM ||
1028 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
1029 return -EAGAIN;
1030
1031 /* Already on it! */
60b912f6 1032 if (m->state == MOUNT_MOUNTING)
e537352b
LP
1033 return 0;
1034
fdf20a31 1035 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
e537352b 1036
9d2f5178
LP
1037 m->result = MOUNT_SUCCESS;
1038 m->reload_result = MOUNT_SUCCESS;
5ad096b3 1039 m->reset_cpu_usage = true;
9d2f5178 1040
8d567588 1041 mount_enter_mounting(m);
82a2b6bb 1042 return 1;
e537352b
LP
1043}
1044
1045static int mount_stop(Unit *u) {
1046 Mount *m = MOUNT(u);
1047
1048 assert(m);
1049
e537352b
LP
1050 /* Already on it */
1051 if (m->state == MOUNT_UNMOUNTING ||
1052 m->state == MOUNT_UNMOUNTING_SIGKILL ||
60b912f6
LP
1053 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1054 m->state == MOUNT_MOUNTING_SIGTERM ||
1055 m->state == MOUNT_MOUNTING_SIGKILL)
e537352b
LP
1056 return 0;
1057
3f6c78dc
LP
1058 assert(m->state == MOUNT_MOUNTING ||
1059 m->state == MOUNT_MOUNTING_DONE ||
1060 m->state == MOUNT_MOUNTED ||
3f6c78dc
LP
1061 m->state == MOUNT_REMOUNTING ||
1062 m->state == MOUNT_REMOUNTING_SIGTERM ||
1063 m->state == MOUNT_REMOUNTING_SIGKILL);
e537352b 1064
9d2f5178 1065 mount_enter_unmounting(m);
82a2b6bb 1066 return 1;
e537352b
LP
1067}
1068
1069static int mount_reload(Unit *u) {
1070 Mount *m = MOUNT(u);
1071
1072 assert(m);
1073
1074 if (m->state == MOUNT_MOUNTING_DONE)
1075 return -EAGAIN;
1076
1077 assert(m->state == MOUNT_MOUNTED);
1078
9d2f5178 1079 mount_enter_remounting(m);
e537352b
LP
1080 return 0;
1081}
1082
a16e1123
LP
1083static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1084 Mount *m = MOUNT(u);
1085
1086 assert(m);
1087 assert(f);
1088 assert(fds);
1089
1090 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
9d2f5178
LP
1091 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1092 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
a16e1123
LP
1093
1094 if (m->control_pid > 0)
ccd06097 1095 unit_serialize_item_format(u, f, "control-pid", PID_FMT, m->control_pid);
a16e1123
LP
1096
1097 if (m->control_command_id >= 0)
1098 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1099
1100 return 0;
1101}
1102
1103static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1104 Mount *m = MOUNT(u);
a16e1123
LP
1105
1106 assert(u);
1107 assert(key);
1108 assert(value);
1109 assert(fds);
1110
1111 if (streq(key, "state")) {
1112 MountState state;
1113
1114 if ((state = mount_state_from_string(value)) < 0)
79008bdd 1115 log_unit_debug(u->id, "Failed to parse state value %s", value);
a16e1123
LP
1116 else
1117 m->deserialized_state = state;
9d2f5178
LP
1118 } else if (streq(key, "result")) {
1119 MountResult f;
a16e1123 1120
9d2f5178
LP
1121 f = mount_result_from_string(value);
1122 if (f < 0)
79008bdd 1123 log_unit_debug(UNIT(m)->id,
66870f90 1124 "Failed to parse result value %s", value);
9d2f5178
LP
1125 else if (f != MOUNT_SUCCESS)
1126 m->result = f;
1127
1128 } else if (streq(key, "reload-result")) {
1129 MountResult f;
1130
1131 f = mount_result_from_string(value);
1132 if (f < 0)
79008bdd 1133 log_unit_debug(UNIT(m)->id,
66870f90 1134 "Failed to parse reload result value %s", value);
9d2f5178
LP
1135 else if (f != MOUNT_SUCCESS)
1136 m->reload_result = f;
a16e1123
LP
1137
1138 } else if (streq(key, "control-pid")) {
5925dd3c 1139 pid_t pid;
a16e1123 1140
e364ad06 1141 if (parse_pid(value, &pid) < 0)
79008bdd 1142 log_unit_debug(UNIT(m)->id,
66870f90 1143 "Failed to parse control-pid value %s", value);
a16e1123 1144 else
5925dd3c 1145 m->control_pid = pid;
a16e1123
LP
1146 } else if (streq(key, "control-command")) {
1147 MountExecCommand id;
1148
1149 if ((id = mount_exec_command_from_string(value)) < 0)
79008bdd 1150 log_unit_debug(UNIT(m)->id,
66870f90 1151 "Failed to parse exec-command value %s", value);
a16e1123
LP
1152 else {
1153 m->control_command_id = id;
1154 m->control_command = m->exec_command + id;
1155 }
a16e1123 1156 } else
79008bdd 1157 log_unit_debug(UNIT(m)->id,
66870f90 1158 "Unknown serialization key '%s'", key);
a16e1123
LP
1159
1160 return 0;
1161}
1162
44a6b1b6 1163_pure_ static UnitActiveState mount_active_state(Unit *u) {
e537352b
LP
1164 assert(u);
1165
1166 return state_translation_table[MOUNT(u)->state];
1167}
1168
44a6b1b6 1169_pure_ static const char *mount_sub_state_to_string(Unit *u) {
10a94420
LP
1170 assert(u);
1171
a16e1123 1172 return mount_state_to_string(MOUNT(u)->state);
10a94420
LP
1173}
1174
44a6b1b6 1175_pure_ static bool mount_check_gc(Unit *u) {
701cc384
LP
1176 Mount *m = MOUNT(u);
1177
1178 assert(m);
1179
6b1dc2bd 1180 return m->from_proc_self_mountinfo;
701cc384
LP
1181}
1182
e537352b
LP
1183static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1184 Mount *m = MOUNT(u);
9d2f5178 1185 MountResult f;
e537352b
LP
1186
1187 assert(m);
1188 assert(pid >= 0);
1189
8c47c732
LP
1190 if (pid != m->control_pid)
1191 return;
e537352b 1192
e537352b
LP
1193 m->control_pid = 0;
1194
96342de6 1195 if (is_clean_exit(code, status, NULL))
9d2f5178
LP
1196 f = MOUNT_SUCCESS;
1197 else if (code == CLD_EXITED)
1198 f = MOUNT_FAILURE_EXIT_CODE;
1199 else if (code == CLD_KILLED)
1200 f = MOUNT_FAILURE_SIGNAL;
1201 else if (code == CLD_DUMPED)
1202 f = MOUNT_FAILURE_CORE_DUMP;
1203 else
1204 assert_not_reached("Unknown code");
1205
1206 if (f != MOUNT_SUCCESS)
1207 m->result = f;
8c47c732 1208
a16e1123 1209 if (m->control_command) {
6ea832a2 1210 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
9d2f5178 1211
a16e1123
LP
1212 m->control_command = NULL;
1213 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1214 }
1215
79008bdd
LP
1216 log_unit_full(u->id,
1217 f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
66870f90
ZJS
1218 "%s mount process exited, code=%s status=%i",
1219 u->id, sigchld_code_to_string(code), status);
e537352b
LP
1220
1221 /* Note that mount(8) returning and the kernel sending us a
1222 * mount table change event might happen out-of-order. If an
1223 * operation succeed we assume the kernel will follow soon too
1224 * and already change into the resulting state. If it fails
1225 * we check if the kernel still knows about the mount. and
1226 * change state accordingly. */
1227
1228 switch (m->state) {
1229
1230 case MOUNT_MOUNTING:
1231 case MOUNT_MOUNTING_DONE:
1232 case MOUNT_MOUNTING_SIGKILL:
1233 case MOUNT_MOUNTING_SIGTERM:
e537352b 1234
9d2f5178
LP
1235 if (f == MOUNT_SUCCESS)
1236 mount_enter_mounted(m, f);
e537352b 1237 else if (m->from_proc_self_mountinfo)
9d2f5178 1238 mount_enter_mounted(m, f);
e537352b 1239 else
9d2f5178 1240 mount_enter_dead(m, f);
e537352b
LP
1241 break;
1242
e2f3b44c
LP
1243 case MOUNT_REMOUNTING:
1244 case MOUNT_REMOUNTING_SIGKILL:
1245 case MOUNT_REMOUNTING_SIGTERM:
1246
9d2f5178 1247 m->reload_result = f;
e2f3b44c 1248 if (m->from_proc_self_mountinfo)
9d2f5178 1249 mount_enter_mounted(m, MOUNT_SUCCESS);
e2f3b44c 1250 else
9d2f5178 1251 mount_enter_dead(m, MOUNT_SUCCESS);
e2f3b44c
LP
1252
1253 break;
1254
e537352b
LP
1255 case MOUNT_UNMOUNTING:
1256 case MOUNT_UNMOUNTING_SIGKILL:
1257 case MOUNT_UNMOUNTING_SIGTERM:
1258
7d54a03a
LP
1259 if (f == MOUNT_SUCCESS) {
1260
1261 if (m->from_proc_self_mountinfo) {
1262
1263 /* Still a mount point? If so, let's
1264 * try again. Most likely there were
1265 * multiple mount points stacked on
1266 * top of each other. Note that due to
1267 * the io event priority logic we can
1268 * be sure the new mountinfo is loaded
1269 * before we process the SIGCHLD for
1270 * the mount command. */
1271
1272 if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
1273 log_unit_debug(u->id, "%s: mount still present, trying again.", u->id);
1274 m->n_retry_umount++;
1275 mount_enter_unmounting(m);
1276 } else {
1277 log_unit_debug(u->id, "%s: mount still present after %u attempts to unmount, giving up.", u->id, m->n_retry_umount);
1278 mount_enter_mounted(m, f);
1279 }
1280 } else
1281 mount_enter_dead(m, f);
1282
1283 } else if (m->from_proc_self_mountinfo)
9d2f5178 1284 mount_enter_mounted(m, f);
e537352b 1285 else
9d2f5178 1286 mount_enter_dead(m, f);
e537352b
LP
1287 break;
1288
1289 default:
1290 assert_not_reached("Uh, control process died at wrong time.");
1291 }
c4e2ceae
LP
1292
1293 /* Notify clients about changed exit status */
1294 unit_add_to_dbus_queue(u);
e537352b
LP
1295}
1296
718db961
LP
1297static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1298 Mount *m = MOUNT(userdata);
e537352b
LP
1299
1300 assert(m);
718db961 1301 assert(m->timer_event_source == source);
e537352b
LP
1302
1303 switch (m->state) {
1304
1305 case MOUNT_MOUNTING:
1306 case MOUNT_MOUNTING_DONE:
79008bdd 1307 log_unit_warning(UNIT(m)->id,
718db961 1308 "%s mounting timed out. Stopping.", UNIT(m)->id);
9d2f5178 1309 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1310 break;
1311
1312 case MOUNT_REMOUNTING:
79008bdd 1313 log_unit_warning(UNIT(m)->id,
718db961 1314 "%s remounting timed out. Stopping.", UNIT(m)->id);
9d2f5178
LP
1315 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1316 mount_enter_mounted(m, MOUNT_SUCCESS);
e537352b
LP
1317 break;
1318
1319 case MOUNT_UNMOUNTING:
79008bdd 1320 log_unit_warning(UNIT(m)->id,
718db961 1321 "%s unmounting timed out. Stopping.", UNIT(m)->id);
9d2f5178 1322 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1323 break;
1324
1325 case MOUNT_MOUNTING_SIGTERM:
4819ff03 1326 if (m->kill_context.send_sigkill) {
79008bdd 1327 log_unit_warning(UNIT(m)->id,
718db961 1328 "%s mounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1329 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1330 } else {
79008bdd 1331 log_unit_warning(UNIT(m)->id,
66870f90 1332 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1333 UNIT(m)->id);
ba035df2
LP
1334
1335 if (m->from_proc_self_mountinfo)
9d2f5178 1336 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1337 else
9d2f5178 1338 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1339 }
e537352b
LP
1340 break;
1341
1342 case MOUNT_REMOUNTING_SIGTERM:
4819ff03 1343 if (m->kill_context.send_sigkill) {
79008bdd 1344 log_unit_warning(UNIT(m)->id,
718db961 1345 "%s remounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1346 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1347 } else {
79008bdd 1348 log_unit_warning(UNIT(m)->id,
66870f90 1349 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1350 UNIT(m)->id);
ba035df2
LP
1351
1352 if (m->from_proc_self_mountinfo)
9d2f5178 1353 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1354 else
9d2f5178 1355 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1356 }
e537352b
LP
1357 break;
1358
1359 case MOUNT_UNMOUNTING_SIGTERM:
4819ff03 1360 if (m->kill_context.send_sigkill) {
79008bdd 1361 log_unit_warning(UNIT(m)->id,
718db961 1362 "%s unmounting timed out. Killing.", UNIT(m)->id);
9d2f5178 1363 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
ba035df2 1364 } else {
79008bdd 1365 log_unit_warning(UNIT(m)->id,
66870f90 1366 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
718db961 1367 UNIT(m)->id);
ba035df2
LP
1368
1369 if (m->from_proc_self_mountinfo)
9d2f5178 1370 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1371 else
9d2f5178 1372 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
ba035df2 1373 }
e537352b
LP
1374 break;
1375
1376 case MOUNT_MOUNTING_SIGKILL:
1377 case MOUNT_REMOUNTING_SIGKILL:
1378 case MOUNT_UNMOUNTING_SIGKILL:
79008bdd 1379 log_unit_warning(UNIT(m)->id,
66870f90 1380 "%s mount process still around after SIGKILL. Ignoring.",
718db961 1381 UNIT(m)->id);
e537352b
LP
1382
1383 if (m->from_proc_self_mountinfo)
9d2f5178 1384 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
e537352b 1385 else
9d2f5178 1386 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
e537352b
LP
1387 break;
1388
1389 default:
1390 assert_not_reached("Timeout at wrong time.");
1391 }
718db961
LP
1392
1393 return 0;
e537352b
LP
1394}
1395
628c89cc 1396static int mount_setup_unit(
e537352b
LP
1397 Manager *m,
1398 const char *what,
1399 const char *where,
1400 const char *options,
1401 const char *fstype,
e537352b 1402 bool set_flags) {
057d9ab8
LP
1403
1404 _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
b87705cd 1405 bool load_extras = false;
057d9ab8 1406 MountParameters *p;
ff5f34d0 1407 bool delete, changed = false;
057d9ab8
LP
1408 Unit *u;
1409 int r;
b08d03ff 1410
f50e0a01 1411 assert(m);
b08d03ff
LP
1412 assert(what);
1413 assert(where);
e537352b
LP
1414 assert(options);
1415 assert(fstype);
1416
e537352b
LP
1417 /* Ignore API mount points. They should never be referenced in
1418 * dependencies ever. */
33ff02c9 1419 if (mount_point_is_api(where) || mount_point_ignore(where))
57f2a956 1420 return 0;
b08d03ff 1421
8d567588
LP
1422 if (streq(fstype, "autofs"))
1423 return 0;
1424
4e85aff4
LP
1425 /* probably some kind of swap, ignore */
1426 if (!is_path(where))
b08d03ff
LP
1427 return 0;
1428
7d17cfbc
MS
1429 e = unit_name_from_path(where, ".mount");
1430 if (!e)
b08d03ff
LP
1431 return -ENOMEM;
1432
7d17cfbc
MS
1433 u = manager_get_unit(m, e);
1434 if (!u) {
b08d03ff
LP
1435 delete = true;
1436
7d17cfbc 1437 u = unit_new(m, sizeof(Mount));
057d9ab8 1438 if (!u)
628c89cc 1439 return log_oom();
b08d03ff
LP
1440
1441 r = unit_add_name(u, e);
b08d03ff
LP
1442 if (r < 0)
1443 goto fail;
1444
7d17cfbc
MS
1445 MOUNT(u)->where = strdup(where);
1446 if (!MOUNT(u)->where) {
07b0b134
ML
1447 r = -ENOMEM;
1448 goto fail;
1449 }
f50e0a01 1450
47a81ba2
UTL
1451 u->source_path = strdup("/proc/self/mountinfo");
1452 if (!u->source_path) {
1453 r = -ENOMEM;
1454 goto fail;
1455 }
1456
057d9ab8
LP
1457 if (m->running_as == SYSTEMD_SYSTEM) {
1458 const char* target;
1459
affc3d83 1460 target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
057d9ab8 1461 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
602c0e74
LP
1462 if (r < 0)
1463 goto fail;
057d9ab8
LP
1464
1465 if (should_umount(MOUNT(u))) {
1466 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1467 if (r < 0)
1468 goto fail;
1469 }
602c0e74 1470 }
89b1d5e0 1471
f94ea366 1472 unit_add_to_load_queue(u);
ff5f34d0 1473 changed = true;
b08d03ff
LP
1474 } else {
1475 delete = false;
8eba616f 1476
bcbd5405
WW
1477 if (!MOUNT(u)->where) {
1478 MOUNT(u)->where = strdup(where);
1479 if (!MOUNT(u)->where) {
1480 r = -ENOMEM;
1481 goto fail;
1482 }
1483 }
1484
9d05dd2e
ZJS
1485 if (m->running_as == SYSTEMD_SYSTEM &&
1486 mount_needs_network(options, fstype)) {
a6d305f9
CL
1487 /* _netdev option may have shown up late, or on a
1488 * remount. Add remote-fs dependencies, even though
9d05dd2e
ZJS
1489 * local-fs ones may already be there. */
1490 unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
1491 load_extras = true;
a6d305f9
CL
1492 }
1493
c2756a68 1494 if (u->load_state == UNIT_NOT_FOUND) {
8eba616f
MS
1495 u->load_state = UNIT_LOADED;
1496 u->load_error = 0;
b87705cd
LP
1497
1498 /* Load in the extras later on, after we
1499 * finished initialization of the unit */
1500 load_extras = true;
ff5f34d0 1501 changed = true;
8eba616f 1502 }
b08d03ff
LP
1503 }
1504
dd7a22a9
LP
1505 w = strdup(what);
1506 o = strdup(options);
1507 f = strdup(fstype);
1508 if (!w || !o || !f) {
e537352b
LP
1509 r = -ENOMEM;
1510 goto fail;
1511 }
1512
6b1dc2bd 1513 p = &MOUNT(u)->parameters_proc_self_mountinfo;
ff5f34d0
LP
1514
1515 changed = changed ||
1516 !streq_ptr(p->options, options) ||
1517 !streq_ptr(p->what, what) ||
1518 !streq_ptr(p->fstype, fstype);
1519
6b1dc2bd
LP
1520 if (set_flags) {
1521 MOUNT(u)->is_mounted = true;
1522 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
ff5f34d0 1523 MOUNT(u)->just_changed = changed;
ef734fd6 1524 }
f50e0a01 1525
6b1dc2bd
LP
1526 MOUNT(u)->from_proc_self_mountinfo = true;
1527
4e85aff4
LP
1528 free(p->what);
1529 p->what = w;
057d9ab8 1530 w = NULL;
b08d03ff 1531
4e85aff4
LP
1532 free(p->options);
1533 p->options = o;
057d9ab8 1534 o = NULL;
e537352b 1535
4e85aff4
LP
1536 free(p->fstype);
1537 p->fstype = f;
057d9ab8 1538 f = NULL;
b08d03ff 1539
b87705cd
LP
1540 if (load_extras) {
1541 r = mount_add_extras(MOUNT(u));
1542 if (r < 0)
1543 goto fail;
1544 }
1545
ff5f34d0
LP
1546 if (changed)
1547 unit_add_to_dbus_queue(u);
c1e1601e 1548
b08d03ff
LP
1549 return 0;
1550
1551fail:
628c89cc
LP
1552 log_warning_errno(r, "Failed to set up mount unit: %m");
1553
b08d03ff
LP
1554 if (delete && u)
1555 unit_free(u);
1556
4e85aff4 1557 return r;
b08d03ff
LP
1558}
1559
ef734fd6 1560static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
628c89cc
LP
1561 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
1562 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
60b912f6 1563 int r = 0;
b08d03ff
LP
1564
1565 assert(m);
1566
628c89cc
LP
1567 t = mnt_new_table();
1568 if (!t)
8d3ae2bd 1569 return log_oom();
b08d03ff 1570
628c89cc
LP
1571 i = mnt_new_iter(MNT_ITER_FORWARD);
1572 if (!i)
1573 return log_oom();
1574
1575 r = mnt_table_parse_mtab(t, NULL);
5cca8def 1576 if (r < 0)
628c89cc 1577 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
e537352b 1578
5cca8def
ZJS
1579 r = 0;
1580 for (;;) {
8d3ae2bd 1581 const char *device, *path, *options, *fstype;
527b7a42 1582 _cleanup_free_ char *d = NULL, *p = NULL;
628c89cc 1583 struct libmnt_fs *fs;
8d3ae2bd 1584 int k;
b08d03ff 1585
628c89cc 1586 k = mnt_table_next_fs(t, i, &fs);
5cca8def
ZJS
1587 if (k == 1)
1588 break;
628c89cc
LP
1589 if (k < 0)
1590 return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
5cca8def 1591
8d3ae2bd
CL
1592 device = mnt_fs_get_source(fs);
1593 path = mnt_fs_get_target(fs);
1594 options = mnt_fs_get_options(fs);
1595 fstype = mnt_fs_get_fstype(fs);
a2e0f3d3 1596
527b7a42 1597 if (cunescape(device, UNESCAPE_RELAX, &d) < 0)
628c89cc
LP
1598 return log_oom();
1599
527b7a42 1600 if (cunescape(path, UNESCAPE_RELAX, &p) < 0)
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};