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