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