From: Ian Kent <raven@xxxxxxxxxx> Try and use the new fsinfo() system call when handing SIGCHLD from systemd mount unit mounting. Signed-off-by: Ian Kent <raven@xxxxxxxxxx> --- src/core/mount.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/core/mount.c b/src/core/mount.c index 9c9abd9b8d..632aa73e1f 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -4,6 +4,8 @@ #include <signal.h> #include <stdio.h> #include <sys/epoll.h> +#include <sys/mount.h> +#include <libmount.h> #include "sd-messages.h" @@ -52,6 +54,7 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata); static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata); static void mount_update_unit_state(Mount *m, Set *gone, Set *around); +static int mount_setup_unit(Manager *m, const char *what, const char *where, const char *options, const char *fstype, bool set_flags); static int mount_process_proc_self_mountinfo(Manager *m); static bool MOUNT_STATE_WITH_PROCESS(MountState state) { @@ -1351,7 +1354,54 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { * race, let's explicitly scan /proc/self/mountinfo before we start processing /usr/bin/(u)mount * dying. It's ugly, but it makes our ordering systematic again, and makes sure we always see * /proc/self/mountinfo changes before our mount/umount exits. */ - (void) mount_process_proc_self_mountinfo(u->manager); + if (!mnt_has_fsinfo()) + (void) mount_process_proc_self_mountinfo(u->manager); + else { + _cleanup_set_free_free_ Set *around = NULL, *gone = NULL; + const char *device, *options, *fstype; + struct libmnt_fs *fs; + const char *what; + Iterator i; + + fs = mnt_new_fs(); + if (!fs) { + log_error_errno(-ENOMEM, "failed to allocate libmount fs struct"); + return; + } + + mnt_fs_set_target(fs, m->where); + + mnt_fs_enable_fsinfo(fs, 1); + device = mnt_fs_get_source(fs); + options = mnt_fs_get_options(fs); + fstype = mnt_fs_get_fstype(fs); + + if (device && fstype) { + device_found_node(u->manager, device, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT); + (void) mount_setup_unit(u->manager, device, m->where, options, fstype, true); + } + + mnt_unref_fs(fs); + + manager_dispatch_load_queue(u->manager); + + gone = set_new(NULL); + around = set_new(NULL); + if (!gone || !around) { + log_error_errno(-ENOMEM, "failed to allocate set"); + return; + } + + mount_update_unit_state(m, gone, around); + + SET_FOREACH(what, gone, i) { + if (set_contains(around, what)) + continue; + + /* Let the device units know that the device is no longer mounted */ + device_found_node(u->manager, what, 0, DEVICE_FOUND_MOUNT); + } + } m->control_pid = 0; _______________________________________________ systemd-devel mailing list systemd-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/systemd-devel