neil / rpms / udisks2

Forked from rpms/udisks2 a year ago
Clone
980768
From 6121d5437d7800876567fd08b6020ca1d72eeaac Mon Sep 17 00:00:00 2001
980768
From: Vratislav Podzimek <vpodzime@redhat.com>
980768
Date: Fri, 20 Oct 2017 13:24:20 +0200
980768
Subject: [PATCH] Add and use a service for cleaning up mount point directories
980768
980768
When udisks2 is used for mounting devices, it may need to create
980768
the mount point directory. If unmount happens later, udisks2
980768
cleans after itself and removes the mount point
980768
directory. However, if the unmount happens during reboot, the
980768
udisks2 daemon may already be terminated not having a chance to
980768
do the cleanup. We need a different mechanism to do the job in
980768
such cases.
980768
980768
systemd provides us with such a mechanism so let's make use of
980768
it.
980768
980768
Resolves: rhbz#1384796
980768
Signed-off-by: Vratislav Podzimek <vpodzime@redhat.com>
980768
---
980768
 data/Makefile.am                |  6 ++--
980768
 data/clean-mount-point@.service | 10 +++++++
980768
 packaging/udisks2.spec          |  1 +
980768
 src/Makefile.am                 |  3 +-
980768
 src/udiskslinuxfilesystem.c     | 61 +++++++++++++++++++++++++++++++++++++++--
980768
 5 files changed, 74 insertions(+), 7 deletions(-)
980768
 create mode 100644 data/clean-mount-point@.service
980768
980768
diff --git a/data/Makefile.am b/data/Makefile.am
980768
index 83af330..9b8073a 100644
980768
--- a/data/Makefile.am
980768
+++ b/data/Makefile.am
980768
@@ -15,14 +15,14 @@ dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf)
980768
 $(dbusconf_DATA): $(dbusconf_in_files) Makefile
980768
 	cp $< $@
980768
 
980768
-systemdservice_in_files = udisks2.service.in
980768
+systemdservice_in_files = udisks2.service.in clean-mount-point@.service
980768
 
980768
 if HAVE_SYSTEMD
980768
 systemdservicedir       = $(systemdsystemunitdir)
980768
 systemdservice_DATA     = $(systemdservice_in_files:.service.in=.service)
980768
 
980768
-$(systemdservice_DATA): $(systemdservice_in_files) Makefile
980768
-	@sed -e "s|\@udisksdprivdir\@|$(libexecdir)/udisks2|" $< > $@
980768
+$(systemdservice_DATA): udisks2.service.in Makefile
980768
+	@sed -e "s|\@udisksdprivdir\@|$(libexecdir)/udisks2|" udisks2.service.in > udisks2.service
980768
 endif
980768
 
980768
 udevrulesdir = $(udevdir)/rules.d
980768
diff --git a/data/clean-mount-point@.service b/data/clean-mount-point@.service
980768
new file mode 100644
980768
index 0000000..83edceb
980768
--- /dev/null
980768
+++ b/data/clean-mount-point@.service
980768
@@ -0,0 +1,10 @@
980768
+[Unit]
980768
+Description=Clean the %f mount point
980768
+Before=%i.mount
980768
+BindsTo=%i.mount
980768
+DefaultDependencies=no
980768
+
980768
+[Service]
980768
+Type=oneshot
980768
+RemainAfterExit=true
980768
+ExecStop=/bin/rm -fd %f
980768
diff --git a/src/Makefile.am b/src/Makefile.am
980768
index 396ab4e..3b22cca 100644
980768
--- a/src/Makefile.am
980768
+++ b/src/Makefile.am
980768
@@ -113,7 +113,8 @@ libudisks_daemon_la_LIBADD =                                                   \
980768
 	$(GIO_LIBS)                                                            \
980768
 	$(GMODULE_LIBS)                                                        \
980768
 	$(GUDEV_LIBS)                                                          \
980768
-	$(BLOCKDEV_LIBS)                                                          \
980768
+	$(BLOCKDEV_LIBS)                                                       \
980768
+	-lbd_utils                                                             \
980768
 	$(LIBATASMART_LIBS)                                                    \
980768
 	$(POLKIT_GOBJECT_1_LIBS)                                               \
980768
 	$(ACL_LIBS)                                                            \
980768
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
980768
index 4cd2784..2910181 100644
980768
--- a/src/udiskslinuxfilesystem.c
980768
+++ b/src/udiskslinuxfilesystem.c
980768
@@ -86,9 +86,11 @@ G_DEFINE_TYPE_WITH_CODE (UDisksLinuxFilesystem, udisks_linux_filesystem, UDISKS_
980768
                          G_IMPLEMENT_INTERFACE (UDISKS_TYPE_FILESYSTEM, filesystem_iface_init));
980768
 
980768
 #ifdef HAVE_FHS_MEDIA
980768
-#  define MOUNT_BASE "/media"
980768
+#define MOUNT_BASE "/media"
980768
+#define MOUNT_BASE_PERSISTENT TRUE
980768
 #else
980768
-#  define MOUNT_BASE "/run/media"
980768
+#define MOUNT_BASE "/run/media"
980768
+#define MOUNT_BASE_PERSISTENT FALSE
980768
 #endif
980768
 
980768
 /* ---------------------------------------------------------------------------------------------------- */
980768
@@ -833,6 +835,7 @@ add_acl (const gchar  *path,
980768
  * @gid: group id of the calling user
980768
  * @user_name: user name of the calling user
980768
  * @fs_type: The file system type to mount with
980768
+ * @persistent: if the mount point is persistent (survives reboot) or not
980768
  * @error: Return location for error or %NULL.
980768
  *
980768
  * Calculates the mount point to use.
980768
@@ -846,6 +849,7 @@ calculate_mount_point (UDisksDaemon  *daemon,
980768
                        gid_t          gid,
980768
                        const gchar   *user_name,
980768
                        const gchar   *fs_type,
980768
+                       gboolean      *persistent,
980768
                        GError       **error)
980768
 {
980768
   UDisksLinuxBlockObject *object = NULL;
980768
@@ -889,6 +893,7 @@ calculate_mount_point (UDisksDaemon  *daemon,
980768
   if (!fs_shared && (user_name != NULL && strstr (user_name, "/") == NULL))
980768
     {
980768
       mount_dir = g_strdup_printf (MOUNT_BASE "/%s", user_name);
980768
+      *persistent = MOUNT_BASE_PERSISTENT;
980768
       if (!g_file_test (mount_dir, G_FILE_TEST_EXISTS))
980768
         {
980768
           /* First ensure that MOUNT_BASE exists */
980768
@@ -933,8 +938,10 @@ calculate_mount_point (UDisksDaemon  *daemon,
980768
         }
980768
     }
980768
   /* otherwise fall back to mounting in /media */
980768
-  if (mount_dir == NULL)
980768
+  if (mount_dir == NULL) {
980768
     mount_dir = g_strdup ("/media");
980768
+    *persistent = TRUE;
980768
+  }
980768
 
980768
   /* NOTE: UTF-8 has the nice property that valid UTF-8 strings only contains
980768
    *       the byte 0x2F if it's for the '/' character (U+002F SOLIDUS).
980768
@@ -1135,6 +1142,49 @@ is_system_managed (UDisksBlock  *block,
980768
   return ret;
980768
 }
980768
 
980768
+static void trigger_mpoint_cleanup (const gchar *mount_point)
980768
+{
980768
+  const gchar *argv[] = {"systemctl", "start", NULL, NULL};
980768
+  GError *error = NULL;
980768
+  gchar *escaped_mpoint = NULL;
980768
+  gsize len = 0;
980768
+
980768
+  if (g_str_has_prefix (mount_point, "/"))
980768
+    mount_point++;
980768
+  else
980768
+    udisks_warning ("Invalid mount point given to trigger_mpoint_cleanup(): %s",
980768
+                    mount_point);
980768
+
980768
+  /* start with the mount point without the leading '/' */
980768
+  escaped_mpoint = g_strdup (mount_point);
980768
+
980768
+  /* and replace all '/'s with '-'s */
980768
+  for (gchar *letter = escaped_mpoint; *letter != '\0'; letter++, len++)
980768
+    {
980768
+      if (*letter == '/')
980768
+        *letter = '-';
980768
+    }
980768
+
980768
+  /* remove the potential trailing '-' (would happen if the given mount_point
980768
+     has a trailing '/') */
980768
+  if (escaped_mpoint[len - 1] == '-')
980768
+    escaped_mpoint[len - 1] = '\0';
980768
+
980768
+  argv[2] = g_strdup_printf ("clean-mount-point@%s", escaped_mpoint);
980768
+
980768
+  if (!bd_utils_exec_and_report_error (argv, NULL, &error) && (error != NULL))
980768
+    {
980768
+      /* this is a best-effort mechanism, if it fails, just log warning and move
980768
+         on */
980768
+      udisks_warning ("Failed to setup systemd-based mount point cleanup: %s",
980768
+                      error->message);
980768
+      g_clear_error (&error);
980768
+    }
980768
+
980768
+  g_free (escaped_mpoint);
980768
+  g_free ((gchar *) argv[2]);
980768
+}
980768
+
980768
 /* ---------------------------------------------------------------------------------------------------- */
980768
 
980768
 /* runs in thread dedicated to handling @invocation */
980768
@@ -1154,6 +1204,7 @@ handle_mount (UDisksFilesystem      *filesystem,
980768
   gchar *fs_type_to_use = NULL;
980768
   gchar *mount_options_to_use = NULL;
980768
   gchar *mount_point_to_use = NULL;
980768
+  gboolean mpoint_persistent = TRUE;
980768
   gchar *fstab_mount_options = NULL;
980768
   gchar *caller_user_name = NULL;
980768
   GError *error = NULL;
980768
@@ -1443,6 +1494,7 @@ handle_mount (UDisksFilesystem      *filesystem,
980768
                                               caller_gid,
980768
                                               caller_user_name,
980768
                                               fs_type_to_use,
980768
+                                              &mpoint_persistent,
980768
                                               &error);
980768
   if (mount_point_to_use == NULL)
980768
     {
980768
@@ -1487,6 +1539,9 @@ handle_mount (UDisksFilesystem      *filesystem,
980768
   else
980768
     udisks_simple_job_complete (UDISKS_SIMPLE_JOB (job), TRUE, NULL);
980768
 
980768
+  if (mpoint_persistent)
980768
+    trigger_mpoint_cleanup (mount_point_to_use);
980768
+
980768
   /* update the mounted-fs file */
980768
   udisks_state_add_mounted_fs (state,
980768
                                mount_point_to_use,
980768
-- 
980768
2.9.5
980768