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