From 0ffe041523bd8eac3765dc4ef74c3a679870dcd6 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 10 Aug 2011 12:13:35 -0400 Subject: [PATCH] Also unmount filesystems when devices mounted via /etc/fstab disappears But only if mounted via udisks. Signed-off-by: David Zeuthen --- src/udiskscleanup.c | 60 ++++++++++++++++++++++++++++++++++++++------- src/udiskscleanup.h | 2 ++ src/udiskslinuxfilesystem.c | 24 ++++++++++++++++-- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/udiskscleanup.c b/src/udiskscleanup.c index 2ecce6d..dccb057 100644 --- a/src/udiskscleanup.c +++ b/src/udiskscleanup.c @@ -67,10 +67,13 @@ * Known details include * block-device * (of type 't') that is the #dev_t - * for the mounted device and + * for the mounted device, * mounted-by-uid * (of type 'u') that is the #uid_t - * of the user who mounted the device. + * of the user who mounted the device, and + * fstab-mount + * (of type 'b') that is %TRUE + * if the device was mounted via an entry in /etc/fstab. * * * @@ -484,6 +487,8 @@ udisks_cleanup_check_mounted_fs_entry (UDisksCleanup *cleanup, GVariant *details; GVariant *block_device_value; dev_t block_device; + GVariant *fstab_mount_value; + gboolean fstab_mount; gboolean keep; gchar *s; GList *mounts; @@ -503,6 +508,8 @@ udisks_cleanup_check_mounted_fs_entry (UDisksCleanup *cleanup, device_to_be_cleaned = FALSE; attempt_no_cleanup = FALSE; block_device_value = NULL; + fstab_mount_value = NULL; + fstab_mount = FALSE; details = NULL; monitor = udisks_daemon_get_mount_monitor (cleanup->daemon); @@ -531,6 +538,17 @@ udisks_cleanup_check_mounted_fs_entry (UDisksCleanup *cleanup, } block_device = g_variant_get_uint64 (block_device_value); + fstab_mount_value = lookup_asv (details, "fstab-mount"); + if (fstab_mount_value == NULL) + { + s = g_variant_print (value, TRUE); + udisks_error ("mounted-fs entry %s is invalid: no fstab-mount key/value pair", s); + g_free (s); + attempt_no_cleanup = FALSE; + goto out; + } + fstab_mount = g_variant_get_boolean (fstab_mount_value); + /* udisks_debug ("Validating mounted-fs entry for mount point %s", mount_point); */ /* Figure out if still mounted */ @@ -623,20 +641,25 @@ udisks_cleanup_check_mounted_fs_entry (UDisksCleanup *cleanup, } /* remove directory */ - if (g_file_test (mount_point, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) + if (!fstab_mount) { - if (g_rmdir (mount_point) != 0) + if (g_file_test (mount_point, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - udisks_error ("Error cleaning up mount point %s: Error removing directory: %m", - mount_point); - /* keep the entry so we can clean it up later */ - keep = TRUE; - goto out2; + if (g_rmdir (mount_point) != 0) + { + udisks_error ("Error cleaning up mount point %s: Error removing directory: %m", + mount_point); + /* keep the entry so we can clean it up later */ + keep = TRUE; + goto out2; + } } } } out2: + if (fstab_mount_value != NULL) + g_variant_unref (fstab_mount_value); if (block_device_value != NULL) g_variant_unref (block_device_value); if (details != NULL) @@ -728,6 +751,7 @@ udisks_cleanup_check_mounted_fs (UDisksCleanup *cleanup, * @block_device: The block device. * @mount_point: The mount point. * @uid: The user id of the process requesting the device to be mounted. + * @fstab_mount: %TRUE if the device was mounted via /etc/fstab. * @error: Return location for error or %NULL. * * Adds a new entry to the @@ -740,6 +764,7 @@ udisks_cleanup_add_mounted_fs (UDisksCleanup *cleanup, const gchar *mount_point, dev_t block_device, uid_t uid, + gboolean fstab_mount, GError **error) { gboolean ret; @@ -804,6 +829,10 @@ udisks_cleanup_add_mounted_fs (UDisksCleanup *cleanup, "{sv}", "mounted-by-uid", g_variant_new_uint32 (uid)); + g_variant_builder_add (&details_builder, + "{sv}", + "fstab-mount", + g_variant_new_boolean (fstab_mount)); details_value = g_variant_builder_end (&details_builder); /* finally add the new entry */ @@ -954,6 +983,7 @@ udisks_cleanup_remove_mounted_fs (UDisksCleanup *cleanup, * @cleanup: A #UDisksCleanup. * @block_device: The block device. * @out_uid: Return location for the user id who mounted the device or %NULL. + * @out_fstab_mount: Return location for whether the device was a fstab mount or %NULL. * @error: Return location for error or %NULL. * * Gets the mount point for @block_device, if it exists in the @@ -966,6 +996,7 @@ gchar * udisks_cleanup_find_mounted_fs (UDisksCleanup *cleanup, dev_t block_device, uid_t *out_uid, + gboolean *out_fstab_mount, GError **error) { gchar *ret; @@ -1036,6 +1067,17 @@ udisks_cleanup_find_mounted_fs (UDisksCleanup *cleanup, g_variant_unref (value); } } + if (out_fstab_mount != NULL) + { + GVariant *value; + value = lookup_asv (details, "fstab-mount"); + *out_fstab_mount = FALSE; + if (value != NULL) + { + *out_fstab_mount = g_variant_get_boolean (value); + g_variant_unref (value); + } + } g_variant_unref (block_device_value); g_variant_unref (details); g_variant_unref (child); diff --git a/src/udiskscleanup.h b/src/udiskscleanup.h index e29b432..6461981 100644 --- a/src/udiskscleanup.h +++ b/src/udiskscleanup.h @@ -43,6 +43,7 @@ gboolean udisks_cleanup_add_mounted_fs (UDisksCleanup *cleanup, const gchar *mount_point, dev_t block_device, uid_t uid, + gboolean fstab_mount, GError **error); gboolean udisks_cleanup_remove_mounted_fs (UDisksCleanup *cleanup, const gchar *mount_point, @@ -50,6 +51,7 @@ gboolean udisks_cleanup_remove_mounted_fs (UDisksCleanup *cleanup, gchar *udisks_cleanup_find_mounted_fs (UDisksCleanup *cleanup, dev_t block_device, uid_t *out_uid, + gboolean *out_fstab_mount, GError **error); gboolean udisks_cleanup_ignore_mounted_fs (UDisksCleanup *cleanup, const gchar *mount_point); diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c index 728feab..f152f1d 100644 --- a/src/udiskslinuxfilesystem.c +++ b/src/udiskslinuxfilesystem.c @@ -842,6 +842,7 @@ handle_mount (UDisksFilesystem *filesystem, goto out; } } + escaped_mount_point_to_use = g_strescape (mount_point_to_use, NULL); if (!udisks_daemon_launch_spawned_job_sync (daemon, NULL, /* GCancellable */ @@ -863,6 +864,19 @@ handle_mount (UDisksFilesystem *filesystem, udisks_block_device_get_device (block), mount_point_to_use, caller_uid); + + /* update the mounted-fs file */ + if (!udisks_cleanup_add_mounted_fs (cleanup, + mount_point_to_use, + makedev (udisks_block_device_get_major (block), udisks_block_device_get_minor (block)), + caller_uid, + TRUE, /* fstab_mounted */ + &error)) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + udisks_filesystem_complete_mount (filesystem, invocation, mount_point_to_use); goto out; } @@ -961,8 +975,12 @@ handle_mount (UDisksFilesystem *filesystem, mount_point_to_use, makedev (udisks_block_device_get_major (block), udisks_block_device_get_minor (block)), caller_uid, + FALSE, /* fstab_mounted */ &error)) - goto out; + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } escaped_fs_type_to_use = g_strescape (fs_type_to_use, NULL); escaped_mount_options_to_use = g_strescape (mount_options_to_use, NULL); @@ -1053,6 +1071,7 @@ handle_unmount (UDisksFilesystem *filesystem, gboolean opt_force; gboolean rc; gboolean system_managed; + gboolean fstab_mounted; mount_point = NULL; escaped_mount_point = NULL; @@ -1099,7 +1118,7 @@ handle_unmount (UDisksFilesystem *filesystem, } /* if system-managed (e.g. referenced in /etc/fstab or similar), just - * run mount(8) as the calling user + * run umount(8) as the calling user */ if (system_managed) { @@ -1134,6 +1153,7 @@ handle_unmount (UDisksFilesystem *filesystem, mount_point = udisks_cleanup_find_mounted_fs (cleanup, makedev (udisks_block_device_get_major (block), udisks_block_device_get_minor (block)), &mounted_by_uid, + &fstab_mounted, &error); if (error != NULL) { -- 2.7.4