chiark / gitweb /
service: if we cannot add an alias to a sysv service, ignore this and go on
[elogind.git] / src / mount.c
index 9a201f33eda61990af100a41d0f935d48668713f..5d5857f5af5680cdb1e97fa8f724beb900248857 100644 (file)
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
 
 /***
   This file is part of systemd.
@@ -244,7 +244,8 @@ static int mount_add_target_links(Mount *m) {
 
         noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
         user = mount_test_option(p->options, "user") || mount_test_option(p->options, "users");
-        handle = !!mount_test_option(p->options, "comment=systemd.mount");
+        handle = !!mount_test_option(p->options, "comment=systemd.mount") ||
+                m->meta.manager->mount_auto;
         automount = !!mount_test_option(p->options, "comment=systemd.automount");
 
         if (mount_test_option(p->options, "_netdev") ||
@@ -265,7 +266,11 @@ static int mount_add_target_links(Mount *m) {
                 return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_WANTS, UNIT(am), true);
         } else {
 
-                if (!noauto && handle)
+                /* Automatically add mount points that aren't natively
+                 * configured to local-fs.target */
+                if (!noauto &&
+                    handle &&
+                    !m->from_fragment)
                         if (user || m->meta.manager->running_as == MANAGER_SYSTEM)
                                 if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0)
                                         return r;
@@ -274,6 +279,30 @@ static int mount_add_target_links(Mount *m) {
         }
 }
 
+static int mount_add_device_links(Mount *m) {
+        MountParameters *p;
+        bool nofail, noauto;
+
+        assert(m);
+
+        if (m->from_fragment)
+                p = &m->parameters_fragment;
+        else if (m->from_etc_fstab)
+                p = &m->parameters_etc_fstab;
+        else
+                return 0;
+
+        if (!p->what || path_equal(m->where, "/"))
+                return 0;
+
+        noauto = !!mount_test_option(p->options, MNTOPT_NOAUTO);
+        nofail = !!mount_test_option(p->options, "nofail");
+
+        return unit_add_node_link(UNIT(m), p->what,
+                                  !noauto && nofail &&
+                                  UNIT(m)->meta.manager->running_as == MANAGER_SYSTEM);
+}
+
 static int mount_add_default_dependencies(Mount *m) {
         int r;
 
@@ -361,9 +390,8 @@ static int mount_load(Unit *u) {
                 else if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
                         what = m->parameters_proc_self_mountinfo.what;
 
-                if (what)
-                        if ((r = unit_add_node_link(u, what, u->meta.manager->running_as == MANAGER_SYSTEM)) < 0)
-                                return r;
+                if ((r = mount_add_device_links(m)) < 0)
+                        return r;
 
                 if ((r = mount_add_mount_links(m)) < 0)
                         return r;
@@ -1005,6 +1033,9 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         default:
                 assert_not_reached("Uh, control process died at wrong time.");
         }
+
+        /* Notify clients about changed exit status */
+        unit_add_to_dbus_queue(u);
 }
 
 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
@@ -1172,7 +1203,7 @@ fail:
 }
 
 static char *fstab_node_to_udev_node(char *p) {
-        char *dn, *t;
+        char *dn, *t, *u;
         int r;
 
         /* FIXME: to follow udev's logic 100% we need to leave valid
@@ -1180,7 +1211,13 @@ static char *fstab_node_to_udev_node(char *p) {
 
         if (startswith(p, "LABEL=")) {
 
-                if (!(t = xescape(p+6, "/ ")))
+                if (!(u = unquote(p+6, '"')))
+                        return NULL;
+
+                t = xescape(u, "/ ");
+                free(u);
+
+                if (!t)
                         return NULL;
 
                 r = asprintf(&dn, "/dev/disk/by-label/%s", t);
@@ -1194,7 +1231,13 @@ static char *fstab_node_to_udev_node(char *p) {
 
         if (startswith(p, "UUID=")) {
 
-                if (!(t = xescape(p+5, "/ ")))
+                if (!(u = unquote(p+5, '"')))
+                        return NULL;
+
+                t = xescape(u, "/ ");
+                free(u);
+
+                if (!t)
                         return NULL;
 
                 r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t));
@@ -1271,6 +1314,7 @@ static int mount_load_etc_fstab(Manager *m) {
                                                  what,
                                                  pri,
                                                  !!mount_test_option(me->mnt_opts, MNTOPT_NOAUTO),
+                                                 !!mount_test_option(me->mnt_opts, "nofail"),
                                                  !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"),
                                                  false);
                 } else
@@ -1487,57 +1531,6 @@ void mount_fd_event(Manager *m, int events) {
         }
 }
 
-int mount_path_is_mounted(Manager *m, const char* path) {
-        char *t;
-        int r;
-
-        assert(m);
-        assert(path);
-
-        if (path[0] != '/')
-                return 1;
-
-        if (!(t = strdup(path)))
-                return -ENOMEM;
-
-        path_kill_slashes(t);
-
-        for (;;) {
-                char *e, *slash;
-                Unit *u;
-
-                if (!(e = unit_name_from_path(t, ".mount"))) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
-
-                u = manager_get_unit(m, e);
-                free(e);
-
-                if (u &&
-                    (MOUNT(u)->from_etc_fstab || MOUNT(u)->from_fragment) &&
-                    MOUNT(u)->state != MOUNT_MOUNTED) {
-                        r = 0;
-                        goto finish;
-                }
-
-                assert_se(slash = strrchr(t, '/'));
-
-                if (slash == t) {
-                        r = 1;
-                        goto finish;
-                }
-
-                *slash = 0;
-        }
-
-        r = 1;
-
-finish:
-        free(t);
-        return r;
-}
-
 static void mount_reset_maintenance(Unit *u) {
         Mount *m = MOUNT(u);
 
@@ -1608,7 +1601,9 @@ const UnitVTable mount_vtable = {
 
         .reset_maintenance = mount_reset_maintenance,
 
+        .bus_interface = "org.freedesktop.systemd1.Mount",
         .bus_message_handler = bus_mount_message_handler,
+        .bus_invalidating_properties =  bus_mount_invalidating_properties,
 
         .enumerate = mount_enumerate,
         .shutdown = mount_shutdown