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