[systemd-devel] [PATCH 3/6] systemd: try to use fsinfo for sigchld handling
Ian Kent
ikent at redhat.com
Mon Jul 27 04:58:14 UTC 2020
From: Ian Kent <raven at themaw.net>
Try and use the new fsinfo() system call when handing SIGCHLD from
systemd mount unit mounting.
Signed-off-by: Ian Kent <raven at themaw.net>
---
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;
More information about the systemd-devel
mailing list