X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fautomount.c;h=4a98540d8282346ea9d194998a6d833f44329abc;hp=697dfa1548cb31e2b601fef57ba1a7dd79b7bfb7;hb=a4783bd17ad96f55b0fe83a50959da13555292bf;hpb=c9bc07646100855ff8193e1e62c52b77327e264d diff --git a/src/core/automount.c b/src/core/automount.c index 697dfa154..4a98540d8 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -31,6 +31,7 @@ #include "unit.h" #include "automount.h" +#include "mount.h" #include "load-fragment.h" #include "load-dropin.h" #include "unit-name.h" @@ -40,6 +41,7 @@ #include "label.h" #include "mkdir.h" #include "path-util.h" +#include "dbus-common.h" static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = { [AUTOMOUNT_DEAD] = UNIT_INACTIVE, @@ -132,7 +134,8 @@ int automount_add_one_mount_link(Automount *a, Mount *m) { if (path_equal(a->where, m->where)) return 0; - if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + if (r < 0) return r; return 0; @@ -144,9 +147,11 @@ static int automount_add_mount_links(Automount *a) { assert(a); - LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) - if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 0) + LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) { + r = automount_add_one_mount_link(a, MOUNT(other)); + if (r < 0) return r; + } return 0; } @@ -156,7 +161,7 @@ static int automount_add_default_dependencies(Automount *a) { assert(a); - if (UNIT(a)->manager->running_as != MANAGER_SYSTEM) + if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM) return 0; r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); @@ -175,18 +180,19 @@ static int automount_verify(Automount *a) { return 0; if (path_equal(a->where, "/")) { - log_error("Cannot have an automount unit for the root directory. Refusing."); + log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing."); return -EINVAL; } - if (!(e = unit_name_from_path(a->where, ".automount"))) + e = unit_name_from_path(a->where, ".automount"); + if (!e) return -ENOMEM; b = unit_has_name(UNIT(a), e); free(e); if (!b) { - log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id); + log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id); return -EINVAL; } @@ -201,19 +207,23 @@ static int automount_load(Unit *u) { assert(u->load_state == UNIT_STUB); /* Load a .automount file */ - if ((r = unit_load_fragment_and_dropin_optional(u)) < 0) + r = unit_load_fragment_and_dropin_optional(u); + if (r < 0) return r; if (u->load_state == UNIT_LOADED) { Unit *x; - if (!a->where) - if (!(a->where = unit_name_to_path(u->id))) + if (!a->where) { + a->where = unit_name_to_path(u->id); + if (!a->where) return -ENOMEM; + } path_kill_slashes(a->where); - if ((r = automount_add_mount_links(a)) < 0) + r = automount_add_mount_links(a); + if (r < 0) return r; r = unit_load_related_unit(u, ".mount", &x); @@ -226,9 +236,11 @@ static int automount_load(Unit *u) { if (r < 0) return r; - if (UNIT(a)->default_dependencies) - if ((r = automount_add_default_dependencies(a)) < 0) + if (UNIT(a)->default_dependencies) { + r = automount_add_default_dependencies(a); + if (r < 0) return r; + } } return automount_verify(a); @@ -246,10 +258,11 @@ static void automount_set_state(Automount *a, AutomountState state) { unmount_autofs(a); if (state != old_state) - log_debug("%s changed %s -> %s", - UNIT(a)->id, - automount_state_to_string(old_state), - automount_state_to_string(state)); + log_debug_unit(UNIT(a)->id, + "%s changed %s -> %s", + UNIT(a)->id, + automount_state_to_string(old_state), + automount_state_to_string(state)); unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true); } @@ -263,7 +276,8 @@ static int automount_coldplug(Unit *u) { if (a->deserialized_state != a->state) { - if ((r = open_dev_autofs(u->manager)) < 0) + r = open_dev_autofs(u->manager); + if (r < 0) return r; if (a->deserialized_state == AUTOMOUNT_WAITING || @@ -271,7 +285,8 @@ static int automount_coldplug(Unit *u) { assert(a->pipe_fd >= 0); - if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0) + r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch); + if (r < 0) return r; } @@ -316,7 +331,8 @@ static int open_dev_autofs(Manager *m) { label_fix("/dev/autofs", false, false); - if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) { + m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY); + if (m->dev_autofs_fd < 0) { log_error("Failed to open /dev/autofs: %s", strerror(errno)); return -errno; } @@ -336,15 +352,12 @@ static int open_dev_autofs(Manager *m) { static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) { struct autofs_dev_ioctl *param; size_t l; - int r; assert(dev_autofs_fd >= 0); assert(where); l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1; - - if (!(param = malloc(l))) - return -ENOMEM; + param = alloca(l); init_autofs_dev_ioctl(param); param->size = l; @@ -352,22 +365,14 @@ static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) { param->openmount.devid = devid; strcpy(param->path, where); - if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) { - r = -errno; - goto finish; - } + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) + return -errno; - if (param->ioctlfd < 0) { - r = -EIO; - goto finish; - } + if (param->ioctlfd < 0) + return -EIO; fd_cloexec(param->ioctlfd, true); - r = param->ioctlfd; - -finish: - free(param); - return r; + return param->ioctlfd; } static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) { @@ -444,15 +449,16 @@ int automount_send_ready(Automount *a, int status) { if (set_isempty(a->tokens)) return 0; - if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) { + ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id); + if (ioctl_fd < 0) { r = ioctl_fd; goto fail; } if (status) - log_debug("Sending failure: %s", strerror(-status)); + log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status)); else - log_debug("Sending success."); + log_debug_unit(UNIT(a)->id, "Sending success."); r = 0; @@ -465,10 +471,11 @@ int automount_send_ready(Automount *a, int status) { * if you pass a positive status code here, the kernel will * freeze! Yay! */ - if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd, - ioctl_fd, - token, - status)) < 0) + k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd, + ioctl_fd, + token, + status); + if (k < 0) r = k; } @@ -493,7 +500,8 @@ static void automount_enter_waiting(Automount *a) { if (a->tokens) set_clear(a->tokens); - if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) { + dev_autofs_fd = open_dev_autofs(UNIT(a)->manager); + if (dev_autofs_fd < 0) { r = dev_autofs_fd; goto fail; } @@ -501,6 +509,8 @@ static void automount_enter_waiting(Automount *a) { /* We knowingly ignore the results of this call */ mkdir_p_label(a->where, 0555); + warn_if_dir_nonempty(a->meta.id, a->where); + if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) { r = -errno; goto fail; @@ -527,15 +537,18 @@ static void automount_enter_waiting(Automount *a) { goto fail; } - if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) { + ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev); + if (ioctl_fd < 0) { r = ioctl_fd; goto fail; } - if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0) + r = autofs_protocol(dev_autofs_fd, ioctl_fd); + if (r < 0) goto fail; - if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0) + r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300); + if (r < 0) goto fail; /* Autofs fun fact: @@ -547,7 +560,8 @@ static void automount_enter_waiting(Automount *a) { close_nointr_nofail(ioctl_fd); ioctl_fd = -1; - if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0) + r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch); + if (r < 0) goto fail; a->pipe_fd = p[0]; @@ -566,14 +580,15 @@ fail: if (mounted) repeat_unmout(a->where); - log_error("Failed to initialize automounter: %s", strerror(-r)); + log_error_unit(UNIT(a)->id, + "Failed to initialize automounter: %s", strerror(-r)); automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); } static void automount_enter_runnning(Automount *a) { int r; struct stat st; - DBusError error; + _cleanup_dbus_error_free_ DBusError error; assert(a); assert(UNIT_DEREF(a->mount)); @@ -583,7 +598,8 @@ static void automount_enter_runnning(Automount *a) { /* We don't take mount requests anymore if we are supposed to * shut down anyway */ if (unit_pending_inactive(UNIT(a))) { - log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id); + log_debug_unit(UNIT(a)->id, + "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id); automount_send_ready(a, -EHOSTDOWN); return; } @@ -592,14 +608,18 @@ 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("%s failed to stat automount point: %m", UNIT(a)->id); + log_warning_unit(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("%s's automount point already active?", UNIT(a)->id); + log_info_unit(UNIT(a)->id, + "%s's automount point already active?", UNIT(a)->id); else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) { - log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r)); + log_warning_unit(UNIT(a)->id, + "%s failed to queue mount startup job: %s", + UNIT(a)->id, bus_error(&error, r)); goto fail; } @@ -608,18 +628,18 @@ static void automount_enter_runnning(Automount *a) { fail: automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); - dbus_error_free(&error); } static int automount_start(Unit *u) { Automount *a = AUTOMOUNT(u); assert(a); - assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED); if (path_is_mount_point(a->where, false)) { - log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id); + log_error_unit(u->id, + "Path %s is already a mount point, refusing start for %s", + a->where, u->id); return -EEXIST; } @@ -635,7 +655,6 @@ static int automount_stop(Unit *u) { Automount *a = AUTOMOUNT(u); assert(a); - assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING); automount_enter_dead(a, AUTOMOUNT_SUCCESS); @@ -661,7 +680,8 @@ static int automount_serialize(Unit *u, FILE *f, FDSet *fds) { if (a->pipe_fd >= 0) { int copy; - if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0) + copy = fdset_put_dup(fds, a->pipe_fd); + if (copy < 0) return copy; unit_serialize_item_format(u, f, "pipe-fd", "%i", copy); @@ -680,8 +700,9 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu if (streq(key, "state")) { AutomountState state; - if ((state = automount_state_from_string(value)) < 0) - log_debug("Failed to parse state value %s", value); + state = automount_state_from_string(value); + if (state < 0) + log_debug_unit(u->id, "Failed to parse state value %s", value); else a->deserialized_state = state; } else if (streq(key, "result")) { @@ -689,7 +710,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("Failed to parse result value %s", value); + log_debug_unit(u->id, "Failed to parse result value %s", value); else if (f != AUTOMOUNT_SUCCESS) a->result = f; @@ -697,27 +718,28 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu unsigned d; if (safe_atou(value, &d) < 0) - log_debug("Failed to parse dev-id value %s", value); + log_debug_unit(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("Failed to parse token value %s", value); + log_debug_unit(u->id, "Failed to parse token value %s", value); else { if (!a->tokens) if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) return -ENOMEM; - if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0) + r = set_put(a->tokens, UINT_TO_PTR(token)); + if (r < 0) return r; } } else if (streq(key, "pipe-fd")) { int fd; if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) - log_debug("Failed to parse pipe-fd value %s", value); + log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value); else { if (a->pipe_fd >= 0) close_nointr_nofail(a->pipe_fd); @@ -725,7 +747,7 @@ static int automount_deserialize_item(Unit *u, const char *key, const char *valu a->pipe_fd = fdset_remove(fds, fd); } } else - log_debug("Unknown serialization key '%s'", key); + log_debug_unit(u->id, "Unknown serialization key '%s'", key); return 0; } @@ -763,12 +785,13 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { assert(fd == a->pipe_fd); if (events != EPOLLIN) { - log_error("Got invalid poll event on pipe."); + log_error_unit(u->id, "Got invalid poll event on pipe."); goto fail; } - if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) { - log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read"); + l = loop_read(a->pipe_fd, &packet, sizeof(packet), true); + if (l != sizeof(packet)) { + log_error_unit(u->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read"); goto fail; } @@ -777,23 +800,24 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { case autofs_ptype_missing_direct: if (packet.v5_packet.pid > 0) { - char *p = NULL; + _cleanup_free_ char *p = NULL; get_process_comm(packet.v5_packet.pid, &p); - log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p)); - free(p); - + log_debug_unit(u->id, + "Got direct mount request on %s, triggered by %lu (%s)", + a->where, (unsigned long) packet.v5_packet.pid, strna(p)); } else - log_debug("Got direct mount request for %s", packet.v5_packet.name); + log_debug_unit(u->id, "Got direct mount request on %s", a->where); - if (!a->tokens) - if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) { - log_error("Failed to allocate token set."); - goto fail; - } + r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func); + if (r < 0) { + log_error_unit(u->id, "Failed to allocate token set."); + goto fail; + } - if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) { - log_error("Failed to remember token: %s", strerror(-r)); + r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token)); + if (r < 0) { + log_error_unit(u->id, "Failed to remember token: %s", strerror(-r)); goto fail; } @@ -801,7 +825,7 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { break; default: - log_error("Received unknown automount request %i", packet.hdr.type); + log_error_unit(u->id, "Received unknown automount request %i", packet.hdr.type); break; } @@ -846,7 +870,6 @@ static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); const UnitVTable automount_vtable = { - .suffix = ".automount", .object_size = sizeof(Automount), .sections = "Unit\0"