LCOV - code coverage report
Current view: top level - core - mount.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 327 962 34.0 %
Date: 2015-07-29 18:47:03 Functions: 32 57 56.1 %

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

Generated by: LCOV version 1.11