chiark / gitweb /
unit: handle nicely of certain unit types are not supported on specific systems
[elogind.git] / src / core / automount.c
index 77d80b2789e49bc6bbd8dcc1c5d9d7dbd73f5d3b..90beb4daaaba4ecae5541731432bae9f47405653 100644 (file)
@@ -75,7 +75,7 @@ static void repeat_unmount(const char *path) {
                         continue;
 
                 if (errno != EINVAL)
-                        log_error("Failed to unmount: %m");
+                        log_error_errno(errno, "Failed to unmount: %m");
 
                 break;
         }
@@ -144,14 +144,14 @@ static int automount_add_default_dependencies(Automount *a) {
 
 static int automount_verify(Automount *a) {
         bool b;
-        char *e;
+        _cleanup_free_ char *e = NULL;
         assert(a);
 
         if (UNIT(a)->load_state != UNIT_LOADED)
                 return 0;
 
         if (path_equal(a->where, "/")) {
-                log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
+                log_unit_error(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
                 return -EINVAL;
         }
 
@@ -160,10 +160,9 @@ static int automount_verify(Automount *a) {
                 return -ENOMEM;
 
         b = unit_has_name(UNIT(a), e);
-        free(e);
 
         if (!b) {
-                log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
+                log_unit_error(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
                 return -EINVAL;
         }
 
@@ -227,7 +226,7 @@ static void automount_set_state(Automount *a, AutomountState state) {
                 unmount_autofs(a);
 
         if (state != old_state)
-                log_debug_unit(UNIT(a)->id,
+                log_unit_debug(UNIT(a)->id,
                                "%s changed %s -> %s",
                                UNIT(a)->id,
                                automount_state_to_string(old_state),
@@ -301,10 +300,8 @@ static int open_dev_autofs(Manager *m) {
         label_fix("/dev/autofs", false, false);
 
         m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
-        if (m->dev_autofs_fd < 0) {
-                log_error("Failed to open /dev/autofs: %m");
-                return -errno;
-        }
+        if (m->dev_autofs_fd < 0)
+                return log_error_errno(errno, "Failed to open /dev/autofs: %m");
 
         init_autofs_dev_ioctl(&param);
         if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, &param) < 0) {
@@ -423,9 +420,9 @@ int automount_send_ready(Automount *a, int status) {
                 return ioctl_fd;
 
         if (status)
-                log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
+                log_unit_debug_errno(UNIT(a)->id, status, "Sending failure: %m");
         else
-                log_debug_unit(UNIT(a)->id, "Sending success.");
+                log_unit_debug(UNIT(a)->id, "Sending success.");
 
         r = 0;
 
@@ -532,12 +529,12 @@ static void automount_enter_waiting(Automount *a) {
         return;
 
 fail:
-        close_pipe(p);
+        safe_close_pair(p);
 
         if (mounted)
                 repeat_unmount(a->where);
 
-        log_error_unit(UNIT(a)->id,
+        log_unit_error(UNIT(a)->id,
                        "Failed to initialize automounter: %s", strerror(-r));
         automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
 }
@@ -552,7 +549,7 @@ static void automount_enter_runnning(Automount *a) {
         /* We don't take mount requests anymore if we are supposed to
          * shut down anyway */
         if (unit_stop_pending(UNIT(a))) {
-                log_debug_unit(UNIT(a)->id,
+                log_unit_debug(UNIT(a)->id,
                                "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
                 automount_send_ready(a, -EHOSTDOWN);
                 return;
@@ -562,19 +559,19 @@ static void automount_enter_runnning(Automount *a) {
 
         /* Before we do anything, let's see if somebody is playing games with us? */
         if (lstat(a->where, &st) < 0) {
-                log_warning_unit(UNIT(a)->id,
+                log_unit_warning(UNIT(a)->id,
                                  "%s failed to stat automount point: %m", UNIT(a)->id);
                 goto fail;
         }
 
         if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
-                log_info_unit(UNIT(a)->id,
+                log_unit_info(UNIT(a)->id,
                               "%s's automount point already active?", UNIT(a)->id);
         else {
                 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
                                     JOB_REPLACE, true, &error, NULL);
                 if (r < 0) {
-                        log_warning_unit(UNIT(a)->id,
+                        log_unit_warning(UNIT(a)->id,
                                          "%s failed to queue mount startup job: %s",
                                          UNIT(a)->id, bus_error_message(&error, r));
                         goto fail;
@@ -595,7 +592,7 @@ static int automount_start(Unit *u) {
         assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
 
         if (path_is_mount_point(a->where, false)) {
-                log_error_unit(u->id,
+                log_unit_error(u->id,
                                "Path %s is already a mount point, refusing start for %s",
                                a->where, u->id);
                 return -EEXIST;
@@ -660,7 +657,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
 
                 state = automount_state_from_string(value);
                 if (state < 0)
-                        log_debug_unit(u->id, "Failed to parse state value %s", value);
+                        log_unit_debug(u->id, "Failed to parse state value %s", value);
                 else
                         a->deserialized_state = state;
         } else if (streq(key, "result")) {
@@ -668,7 +665,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
 
                 f = automount_result_from_string(value);
                 if (f < 0)
-                        log_debug_unit(u->id, "Failed to parse result value %s", value);
+                        log_unit_debug(u->id, "Failed to parse result value %s", value);
                 else if (f != AUTOMOUNT_SUCCESS)
                         a->result = f;
 
@@ -676,17 +673,17 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
                 unsigned d;
 
                 if (safe_atou(value, &d) < 0)
-                        log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
+                        log_unit_debug(u->id, "Failed to parse dev-id value %s", value);
                 else
                         a->dev_id = (unsigned) d;
         } else if (streq(key, "token")) {
                 unsigned token;
 
                 if (safe_atou(value, &token) < 0)
-                        log_debug_unit(u->id, "Failed to parse token value %s", value);
+                        log_unit_debug(u->id, "Failed to parse token value %s", value);
                 else {
                         if (!a->tokens)
-                                if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
+                                if (!(a->tokens = set_new(NULL)))
                                         return -ENOMEM;
 
                         r = set_put(a->tokens, UINT_TO_PTR(token));
@@ -697,13 +694,13 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu
                 int fd;
 
                 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-                        log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
+                        log_unit_debug(u->id, "Failed to parse pipe-fd value %s", value);
                 else {
                         safe_close(a->pipe_fd);
                         a->pipe_fd = fdset_remove(fds, fd);
                 }
         } else
-                log_debug_unit(u->id, "Unknown serialization key '%s'", key);
+                log_unit_debug(u->id, "Unknown serialization key '%s'", key);
 
         return 0;
 }
@@ -739,13 +736,16 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
         assert(fd == a->pipe_fd);
 
         if (events != EPOLLIN) {
-                log_error_unit(UNIT(a)->id, "Got invalid poll event on pipe.");
+                log_unit_error(UNIT(a)->id, "Got invalid poll event on pipe.");
                 goto fail;
         }
 
         l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
         if (l != sizeof(packet)) {
-                log_error_unit(UNIT(a)->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
+                if (l < 0)
+                        log_unit_error_errno(UNIT(a)->id, l, "Invalid read from pipe: %m");
+                else
+                        log_unit_error(UNIT(a)->id, "Invalid read from pipe: short read");
                 goto fail;
         }
 
@@ -757,21 +757,21 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
                         _cleanup_free_ char *p = NULL;
 
                         get_process_comm(packet.v5_packet.pid, &p);
-                        log_info_unit(UNIT(a)->id,
+                        log_unit_info(UNIT(a)->id,
                                        "Got automount request for %s, triggered by "PID_FMT" (%s)",
                                        a->where, packet.v5_packet.pid, strna(p));
                 } else
-                        log_debug_unit(UNIT(a)->id, "Got direct mount request on %s", a->where);
+                        log_unit_debug(UNIT(a)->id, "Got direct mount request on %s", a->where);
 
-                r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
+                r = set_ensure_allocated(&a->tokens, NULL);
                 if (r < 0) {
-                        log_error_unit(UNIT(a)->id, "Failed to allocate token set.");
+                        log_unit_error(UNIT(a)->id, "Failed to allocate token set.");
                         goto fail;
                 }
 
                 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
                 if (r < 0) {
-                        log_error_unit(UNIT(a)->id, "Failed to remember token: %s", strerror(-r));
+                        log_unit_error_errno(UNIT(a)->id, r, "Failed to remember token: %m");
                         goto fail;
                 }
 
@@ -779,7 +779,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
                 break;
 
         default:
-                log_error_unit(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
+                log_unit_error(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
                 break;
         }
 
@@ -807,6 +807,17 @@ static void automount_reset_failed(Unit *u) {
         a->result = AUTOMOUNT_SUCCESS;
 }
 
+static bool automount_supported(Manager *m) {
+        static int supported = -1;
+
+        assert(m);
+
+        if (supported < 0)
+                supported = access("/dev/autofs", F_OK) >= 0;
+
+        return supported;
+}
+
 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
         [AUTOMOUNT_DEAD] = "dead",
         [AUTOMOUNT_WAITING] = "waiting",
@@ -859,6 +870,7 @@ const UnitVTable automount_vtable = {
         .bus_vtable = bus_automount_vtable,
 
         .shutdown = automount_shutdown,
+        .supported = automount_supported,
 
         .status_message_formats = {
                 .finished_start_job = {