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