chiark / gitweb /
utmp: write out runlevels 5 and 3 preferrably if multiples make sense, and S instead...
[elogind.git] / src / mount.c
index bee3c9a60ef001a669bb6cb063d4840137fbfd68..b49443ced11b962e8d930049647ca49cf3b009f0 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") ||
@@ -279,14 +280,14 @@ static int mount_add_default_dependencies(Mount *m) {
 
         assert(m);
 
-        if (m->meta.manager->running_as == MANAGER_SYSTEM) {
+        if (m->meta.manager->running_as == MANAGER_SYSTEM &&
+            !path_equal(m->where, "/")) {
 
-                if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0)
+                if ((r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, SPECIAL_FSCK_TARGET, NULL, true)) < 0)
                         return r;
 
-                if (!path_equal(m->where, "/"))
-                        if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
-                                return r;
+                if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTED_BY, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
+                        return r;
         }
 
         return 0;
@@ -361,8 +362,10 @@ 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)
+                if (what && !path_equal(m->where, "/"))
+                        if ((r = unit_add_node_link(u, what,
+                                                    u->meta.manager->running_as == MANAGER_SYSTEM &&
+                                                    u->meta.manager->mount_on_plug)) < 0)
                                 return r;
 
                 if ((r = mount_add_mount_links(m)) < 0)
@@ -789,6 +792,7 @@ static void mount_enter_remounting(Mount *m, bool success) {
         return;
 
 fail:
+        log_warning("%s failed to run 'remount' task: %s", m->meta.id, strerror(-r));
         mount_enter_mounted(m, false);
 }
 
@@ -876,7 +880,6 @@ static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
 
 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
         Mount *m = MOUNT(u);
-        int r;
 
         assert(u);
         assert(key);
@@ -901,7 +904,7 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
         } else if (streq(key, "control-pid")) {
                 pid_t pid;
 
-                if ((r = parse_pid(value, &pid)) < 0)
+                if (parse_pid(value, &pid) < 0)
                         log_debug("Failed to parse control-pid value %s", value);
                 else
                         m->control_pid = pid;
@@ -1005,6 +1008,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 +1178,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 +1186,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 +1206,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));
@@ -1422,7 +1440,7 @@ void mount_fd_event(Manager *m, int events) {
          * table changes */
 
         if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) {
-                log_error("Failed to reread /proc/self/mountinfo: %s", strerror(errno));
+                log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
 
                 /* Reset flags, just in case, for later calls */
                 LIST_FOREACH(units_per_type, meta, m->units_per_type[UNIT_MOUNT]) {
@@ -1487,55 +1505,15 @@ void mount_fd_event(Manager *m, int events) {
         }
 }
 
-int mount_path_is_mounted(Manager *m, const char* path) {
-        char *t;
-        int r;
+static void mount_reset_maintenance(Unit *u) {
+        Mount *m = MOUNT(u);
 
         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 (m->state == MOUNT_MAINTENANCE)
+                mount_set_state(m, MOUNT_DEAD);
 
-                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;
+        m->failure = false;
 }
 
 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
@@ -1595,7 +1573,11 @@ const UnitVTable mount_vtable = {
         .sigchld_event = mount_sigchld_event,
         .timer_event = mount_timer_event,
 
+        .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