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