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