diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/calendarspec.c | 5 | ||||
-rw-r--r-- | src/boot/bootctl.c | 2 | ||||
-rw-r--r-- | src/core/device.c | 46 | ||||
-rw-r--r-- | src/core/device.h | 3 | ||||
-rw-r--r-- | src/core/mount.c | 20 | ||||
-rw-r--r-- | src/core/socket.c | 3 | ||||
-rw-r--r-- | src/core/unit.c | 3 | ||||
-rw-r--r-- | src/coredump/coredumpctl.c | 5 |
8 files changed, 82 insertions, 5 deletions
diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index 514587d237..adf79eb533 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -688,8 +688,11 @@ static int parse_date(const char **p, CalendarSpec *c) { c->month = first; c->day = second; return 0; - } else if (c->end_of_month) + } else if (c->end_of_month) { + free_chain(first); + free_chain(second); return -EINVAL; + } if (*t == '~') c->end_of_month = true; diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index dc11b0d9db..b747a95133 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -255,7 +255,7 @@ static int find_esp(uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_ if (!arg_path) return log_oom(); - log_info("Using EFI System Parition at %s.", path); + log_info("Using EFI System Partition at %s.", path); return 0; } diff --git a/src/core/device.c b/src/core/device.c index e345552f24..bd481c8050 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -285,6 +285,37 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) { } } +static bool device_is_bound_by_mounts(Unit *d, struct udev_device *dev) { + const char *bound_by; + int r = false; + + assert(d); + assert(dev); + + bound_by = udev_device_get_property_value(dev, "SYSTEMD_MOUNT_DEVICE_BOUND"); + if (bound_by) + r = parse_boolean(bound_by) > 0; + + DEVICE(d)->bind_mounts = r; + return r; +} + +static int device_upgrade_mount_deps(Unit *u) { + Unit *other; + Iterator i; + int r; + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) { + if (other->type != UNIT_MOUNT) + continue; + + r = unit_add_dependency(other, UNIT_BINDS_TO, u, true); + if (r < 0) + return r; + } + return 0; +} + static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) { _cleanup_free_ char *e = NULL; const char *sysfs = NULL; @@ -349,6 +380,13 @@ static int device_setup_unit(Manager *m, struct udev_device *dev, const char *pa (void) device_add_udev_wants(u, dev); } + /* So the user wants the mount units to be bound to the device but a + * mount unit might has been seen by systemd before the device appears + * on its radar. In this case the device unit is partially initialized + * and includes the deps on the mount unit but at that time the "bind + * mounts" flag wasn't not present. Fix this up now. */ + if (device_is_bound_by_mounts(u, dev)) + device_upgrade_mount_deps(u); /* Note that this won't dispatch the load queue, the caller * has to do that if needed and appropriate */ @@ -824,6 +862,14 @@ int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, return device_update_found_by_name(m, node, add, found, now); } +bool device_shall_be_bound_by(Unit *device, Unit *u) { + + if (u->type != UNIT_MOUNT) + return false; + + return DEVICE(device)->bind_mounts; +} + const UnitVTable device_vtable = { .object_size = sizeof(Device), .sections = diff --git a/src/core/device.h b/src/core/device.h index 184a1a349b..dd372fb695 100644 --- a/src/core/device.h +++ b/src/core/device.h @@ -40,8 +40,11 @@ struct Device { LIST_FIELDS(struct Device, same_sysfs); DeviceState state, deserialized_state; + + bool bind_mounts; }; extern const UnitVTable device_vtable; int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now); +bool device_shall_be_bound_by(Unit *device, Unit *u); diff --git a/src/core/mount.c b/src/core/mount.c index 997dbe3837..daf7f5697b 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -135,6 +135,16 @@ static bool mount_state_active(MountState state) { MOUNT_REMOUNTING_SIGKILL); } +static bool mount_is_bound_to_device(const Mount *m) { + const MountParameters *p; + + if (m->from_fragment) + return true; + + p = &m->parameters_proc_self_mountinfo; + return fstab_test_option(p->options, "x-systemd.device-bound\0"); +} + static bool needs_quota(const MountParameters *p) { assert(p); @@ -324,6 +334,7 @@ static int mount_add_mount_links(Mount *m) { static int mount_add_device_links(Mount *m) { MountParameters *p; bool device_wants_mount = false; + UnitDependency dep; int r; assert(m); @@ -353,7 +364,14 @@ static int mount_add_device_links(Mount *m) { if (mount_is_auto(p) && !mount_is_automount(p) && MANAGER_IS_SYSTEM(UNIT(m)->manager)) device_wants_mount = true; - r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, m->from_fragment ? UNIT_BINDS_TO : UNIT_REQUIRES); + /* Mount units from /proc/self/mountinfo are not bound to devices + * by default since they're subject to races when devices are + * unplugged. But the user can still force this dep with an + * appropriate option (or udev property) so the mount units are + * automatically stopped when the device disappears suddenly. */ + dep = mount_is_bound_to_device(m) ? UNIT_BINDS_TO : UNIT_REQUIRES; + + r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, dep); if (r < 0) return r; diff --git a/src/core/socket.c b/src/core/socket.c index fee9b702e6..0960a30039 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -423,8 +423,7 @@ static const char *socket_find_symlink_target(Socket *s) { break; case SOCKET_SOCKET: - if (p->address.sockaddr.un.sun_path[0] != 0) - f = p->address.sockaddr.un.sun_path; + f = socket_address_get_path(&p->address); break; default: diff --git a/src/core/unit.c b/src/core/unit.c index ab40135736..5d0b17425b 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3048,6 +3048,9 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep if (r < 0) return r; + if (dep == UNIT_REQUIRES && device_shall_be_bound_by(device, u)) + dep = UNIT_BINDS_TO; + r = unit_add_two_dependencies(u, UNIT_AFTER, MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS, device, true); diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 877bbb34fc..646757f9d9 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -821,6 +821,9 @@ static int run_gdb(sd_journal *j) { if (r < 0) return r; + /* Don't interfere with gdb and its handling of SIGINT. */ + (void) ignore_signals(SIGINT, -1); + pid = fork(); if (pid < 0) { r = log_error_errno(errno, "Failed to fork(): %m"); @@ -845,6 +848,8 @@ static int run_gdb(sd_journal *j) { r = st.si_code == CLD_EXITED ? st.si_status : 255; finish: + (void) default_signals(SIGINT, -1); + if (unlink_path) { log_debug("Removed temporary file %s", path); unlink(path); |