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