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