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