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