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