[gvfs/wip/udisks2: 5/5] udisks2: implement mount and unmount methods
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/wip/udisks2: 5/5] udisks2: implement mount and unmount methods
- Date: Wed, 28 Sep 2011 19:36:49 +0000 (UTC)
commit c5df9130880549f29bd183860b6fe32640898ccc
Author: David Zeuthen <davidz redhat com>
Date: Wed Sep 28 15:35:49 2011 -0400
udisks2: implement mount and unmount methods
Signed-off-by: David Zeuthen <davidz redhat com>
monitor/udisks2/gvfsudisks2drive.c | 2 +-
monitor/udisks2/gvfsudisks2mount.c | 379 +++++++++++++++++++++++++++-
monitor/udisks2/gvfsudisks2mount.h | 4 +-
monitor/udisks2/gvfsudisks2volume.c | 159 +++++++++++-
monitor/udisks2/gvfsudisks2volumemonitor.c | 16 +-
monitor/udisks2/gvfsudisks2volumemonitor.h | 1 +
6 files changed, 544 insertions(+), 17 deletions(-)
---
diff --git a/monitor/udisks2/gvfsudisks2drive.c b/monitor/udisks2/gvfsudisks2drive.c
index d5e3a38..b83af8e 100644
--- a/monitor/udisks2/gvfsudisks2drive.c
+++ b/monitor/udisks2/gvfsudisks2drive.c
@@ -166,7 +166,7 @@ update_drive (GVfsUDisks2Drive *drive)
if (drive->is_media_removable)
{
drive->has_media = (udisks_drive_get_size (drive->udisks_drive) > 0);
- drive->can_eject = TRUE;
+ drive->can_eject = FALSE; // TODO: set to TRUE when eject() has been implemented
}
else
{
diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c
index 6f049bb..6d82b61 100644
--- a/monitor/udisks2/gvfsudisks2mount.c
+++ b/monitor/udisks2/gvfsudisks2mount.c
@@ -27,6 +27,7 @@
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdlib.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
@@ -421,12 +422,11 @@ gvfs_udisks2_mount_has_uuid (GVfsUDisks2Mount *_mount,
return g_strcmp0 (mount->uuid, uuid) == 0;
}
-gboolean
-gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount *_mount,
- const gchar *mount_path)
+const gchar *
+gvfs_udisks2_mount_get_mount_path (GVfsUDisks2Mount *_mount)
{
GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
- return g_strcmp0 (mount->mount_path, mount_path) == 0;
+ return mount->mount_path;
}
static GDrive *
@@ -478,6 +478,375 @@ gvfs_udisks2_mount_can_eject (GMount *_mount)
/* ---------------------------------------------------------------------------------------------------- */
+static GArray *
+get_busy_processes (const gchar* const *mount_points)
+{
+ GArray *processes;
+ guint n;
+
+ processes = g_array_new (FALSE, FALSE, sizeof (GPid));
+
+ for (n = 0; mount_points != NULL && mount_points[n] != NULL; n++)
+ {
+ const gchar *mount_point = mount_points[n];
+ const gchar *lsof_argv[] = {"lsof", "-t", NULL, NULL};
+ gchar *standard_output = NULL;
+ const gchar *p;
+ gint exit_status;
+ GError *error;
+
+ lsof_argv[2] = mount_point;
+
+ error = NULL;
+ if (!g_spawn_sync (NULL, /* working_directory */
+ (gchar **) lsof_argv,
+ NULL, /* envp */
+ G_SPAWN_SEARCH_PATH,
+ NULL, /* child_setup */
+ NULL, /* user_data */
+ &standard_output,
+ NULL, /* standard_error */
+ &exit_status,
+ &error))
+ {
+ g_warning ("Error launching lsof(1): %s (%s, %d)",
+ error->message, g_quark_to_string (error->domain), error->code);
+ goto cont_loop;
+ }
+ if (!(WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0))
+ {
+ g_warning ("lsof(1) didn't exit normally");
+ goto cont_loop;
+ }
+
+ p = standard_output;
+ while (TRUE)
+ {
+ GPid pid;
+ gchar *endp;
+
+ if (*p == '\0')
+ break;
+
+ pid = strtol (p, &endp, 10);
+
+ if (pid == 0 && p == endp)
+ break;
+
+ g_array_append_val (processes, pid);
+
+ p = endp;
+ }
+ cont_loop:
+ g_free (standard_output);
+ }
+ return processes;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ GSimpleAsyncResult *simple;
+
+ GVfsUDisks2Mount *mount;
+
+ GCancellable *cancellable;
+ gulong cancelled_handler_id;
+ gboolean is_cancelled;
+
+ GMountOperation *mount_operation;
+ GMountUnmountFlags flags;
+
+ gulong mount_op_reply_handler_id;
+ guint retry_unmount_timer_id;
+
+} UnmountData;
+
+static void
+unmount_data_free (UnmountData *data)
+{
+ g_object_unref (data->simple);
+
+ if (data->mount_op_reply_handler_id > 0)
+ {
+ /* make the operation dialog go away */
+ g_signal_emit_by_name (data->mount_operation, "aborted");
+ g_signal_handler_disconnect (data->mount_operation, data->mount_op_reply_handler_id);
+ }
+ if (data->retry_unmount_timer_id > 0)
+ {
+ g_source_remove (data->retry_unmount_timer_id);
+ data->retry_unmount_timer_id = 0;
+ }
+
+ g_clear_object (&data->mount);
+ if (data->cancelled_handler_id != 0)
+ g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
+ g_clear_object (&data->cancellable);
+ g_clear_object (&data->mount_operation);
+
+ g_free (data);
+}
+
+static void unmount_do (UnmountData *data, gboolean force);
+
+static gboolean
+on_retry_timer_cb (gpointer user_data)
+{
+ UnmountData *data = user_data;
+
+ if (data->retry_unmount_timer_id == 0)
+ goto out;
+
+ /* we're removing the timeout */
+ data->retry_unmount_timer_id = 0;
+
+ /* timeout expired => try again */
+ unmount_do (data, FALSE);
+
+ out:
+ return FALSE; /* remove timeout */
+}
+
+static void
+on_mount_op_reply (GMountOperation *mount_operation,
+ GMountOperationResult result,
+ gpointer user_data)
+{
+ UnmountData *data = user_data;
+ gint choice;
+
+ /* disconnect the signal handler */
+ g_warn_if_fail (data->mount_op_reply_handler_id != 0);
+ g_signal_handler_disconnect (data->mount_operation,
+ data->mount_op_reply_handler_id);
+ data->mount_op_reply_handler_id = 0;
+
+ choice = g_mount_operation_get_choice (mount_operation);
+
+ if (result == G_MOUNT_OPERATION_ABORTED ||
+ (result == G_MOUNT_OPERATION_HANDLED && choice == 1))
+ {
+ /* don't show an error dialog here */
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED_HANDLED,
+ "GMountOperation aborted (user should never see this "
+ "error since it is G_IO_ERROR_FAILED_HANDLED)");
+ g_simple_async_result_complete_in_idle (data->simple);
+ unmount_data_free (data);
+ }
+ else if (result == G_MOUNT_OPERATION_HANDLED)
+ {
+ /* user chose force unmount => try again with force_unmount==TRUE */
+ unmount_do (data, TRUE);
+ }
+ else
+ {
+ /* result == G_MOUNT_OPERATION_UNHANDLED => GMountOperation instance doesn't
+ * support :show-processes signal
+ */
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_BUSY,
+ _("One or more programs are preventing the unmount operation."));
+ g_simple_async_result_complete_in_idle (data->simple);
+ unmount_data_free (data);
+ }
+}
+
+static void
+unmount_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ UDisksFilesystem *filesystem = UDISKS_FILESYSTEM (source_object);
+ UnmountData *data = user_data;
+ GError *error;
+
+ error = NULL;
+ if (!udisks_filesystem_call_unmount_finish (filesystem,
+ res,
+ &error))
+ {
+ /* translate to UDisksError to GIOError and strip D-Bus error information */
+ if (error->domain == UDISKS_ERROR && error->code == UDISKS_ERROR_DEVICE_BUSY)
+ error->code = G_IO_ERROR_BUSY;
+ else
+ error->code = G_IO_ERROR_FAILED;
+ error->domain = G_IO_ERROR;
+ g_dbus_error_strip_remote_error (error);
+
+ /* if the user passed in a GMountOperation, then do the GMountOperation::show-processes dance ... */
+ if (error->code == G_IO_ERROR_BUSY && data->mount_operation != NULL)
+ {
+ GArray *processes;
+ const gchar *choices[3] = {NULL, NULL, NULL};
+ const gchar *message;
+
+ /* TODO: get processes */
+ processes = get_busy_processes (udisks_filesystem_get_mount_points (filesystem));
+
+ if (data->mount_op_reply_handler_id == 0)
+ {
+ data->mount_op_reply_handler_id = g_signal_connect (data->mount_operation,
+ "reply",
+ G_CALLBACK (on_mount_op_reply),
+ data);
+ }
+ choices[0] = _("Unmount Anyway");
+ choices[1] = _("Cancel");
+ message = _("Volume is busy\n"
+ "One or more applications are keeping the volume busy.");
+ g_signal_emit_by_name (data->mount_operation,
+ "show-processes",
+ message,
+ processes,
+ choices);
+ /* set up a timer to try unmounting every two seconds - this will also
+ * update the list of busy processes
+ */
+ if (data->retry_unmount_timer_id == 0)
+ {
+ data->retry_unmount_timer_id = g_timeout_add_seconds (2,
+ on_retry_timer_cb,
+ data);
+ }
+ goto out;
+ }
+ else
+ {
+ g_simple_async_result_take_error (data->simple, error);
+ g_simple_async_result_complete (data->simple);
+ }
+ }
+ else
+ {
+ gvfs_udisks2_volume_monitor_update (data->mount->monitor);
+ g_simple_async_result_complete (data->simple);
+ }
+
+ unmount_data_free (data);
+ out:
+ ;
+}
+
+static void
+unmount_do (UnmountData *data,
+ gboolean force)
+{
+ UDisksBlock *block;
+ UDisksFilesystem *filesystem;
+ GVariantBuilder builder;
+
+ if (data->mount->volume != NULL)
+ {
+ block = gvfs_udisks2_volume_get_block (data->mount->volume);
+ }
+ else
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Don't know how to unmount non-udisks object yet (TODO)");
+ g_simple_async_result_complete (data->simple);
+ unmount_data_free (data);
+ goto out;
+ }
+
+ filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))));
+ if (filesystem == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No filesystem interface on D-Bus object");
+ g_simple_async_result_complete (data->simple);
+ unmount_data_free (data);
+ goto out;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ if (data->mount_operation == NULL)
+ {
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+ }
+ if (force || data->flags & G_MOUNT_UNMOUNT_FORCE)
+ {
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "force", g_variant_new_boolean (TRUE));
+ }
+ udisks_filesystem_call_unmount (filesystem,
+ g_variant_builder_end (&builder),
+ data->cancellable,
+ unmount_cb,
+ data);
+
+ out:
+ ;
+}
+
+static void
+gvfs_udisks2_mount_unmount_with_operation (GMount *_mount,
+ GMountUnmountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+ UnmountData *data;
+
+ /* first emit the ::mount-pre-unmount signal */
+ g_signal_emit_by_name (mount->monitor, "mount-pre-unmount", mount);
+
+ data = g_new0 (UnmountData, 1);
+ data->simple = g_simple_async_result_new (G_OBJECT (mount),
+ callback,
+ user_data,
+ gvfs_udisks2_mount_unmount_with_operation);
+ data->mount = g_object_ref (mount);
+ data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+ data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
+ data->flags = flags;
+
+ unmount_do (data, FALSE);
+}
+
+static gboolean
+gvfs_udisks2_mount_unmount_with_operation_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gvfs_udisks2_mount_unmount (GMount *mount,
+ GMountUnmountFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ gvfs_udisks2_mount_unmount_with_operation (mount, flags, NULL, cancellable, callback, user_data);
+}
+
+static gboolean
+gvfs_udisks2_mount_unmount_finish (GMount *mount,
+ GAsyncResult *result,
+ GError **error)
+{
+ return gvfs_udisks2_mount_unmount_with_operation_finish (mount, result, error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
gvfs_udisks2_mount_mount_iface_init (GMountIface *iface)
{
@@ -489,11 +858,11 @@ gvfs_udisks2_mount_mount_iface_init (GMountIface *iface)
iface->get_volume = gvfs_udisks2_mount_get_volume;
iface->can_unmount = gvfs_udisks2_mount_can_unmount;
iface->can_eject = gvfs_udisks2_mount_can_eject;
-#if 0
iface->unmount = gvfs_udisks2_mount_unmount;
iface->unmount_finish = gvfs_udisks2_mount_unmount_finish;
iface->unmount_with_operation = gvfs_udisks2_mount_unmount_with_operation;
iface->unmount_with_operation_finish = gvfs_udisks2_mount_unmount_with_operation_finish;
+#if 0
iface->eject = gvfs_udisks2_mount_eject;
iface->eject_finish = gvfs_udisks2_mount_eject_finish;
iface->eject_with_operation = gvfs_udisks2_mount_eject_with_operation;
diff --git a/monitor/udisks2/gvfsudisks2mount.h b/monitor/udisks2/gvfsudisks2mount.h
index 03b7769..dd16564 100644
--- a/monitor/udisks2/gvfsudisks2mount.h
+++ b/monitor/udisks2/gvfsudisks2mount.h
@@ -42,8 +42,6 @@ GVfsUDisks2Mount *gvfs_udisks2_mount_new (GVfsUDisks2VolumeMonitor *m
GVfsUDisks2Volume *volume);
void gvfs_udisks2_mount_unmounted (GVfsUDisks2Mount *mount);
-gboolean gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount *mount,
- const gchar *mount_path);
gboolean gvfs_udisks2_mount_has_uuid (GVfsUDisks2Mount *mount,
const gchar *uuid);
@@ -52,6 +50,8 @@ void gvfs_udisks2_mount_unset_volume (GVfsUDisks2Mount *m
gboolean gvfs_udisks2_mount_has_volume (GVfsUDisks2Mount *mount,
GVfsUDisks2Volume *volume);
+const gchar *gvfs_udisks2_mount_get_mount_path (GVfsUDisks2Mount *mount);
+
G_END_DECLS
#endif /* __GVFS_UDISKS2_MOUNT_H__ */
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
index 8d2e0a8..440bd99 100644
--- a/monitor/udisks2/gvfsudisks2volume.c
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -42,6 +42,11 @@ struct _GVfsUDisks2VolumeClass
GObjectClass parent_class;
};
+struct MountData;
+typedef struct MountData MountData;
+
+static void mount_cancel_pending_op (MountData *data);
+
struct _GVfsUDisks2Volume
{
GObject parent;
@@ -61,6 +66,12 @@ struct _GVfsUDisks2Volume
gchar *uuid;
gboolean can_mount;
gboolean should_automount;
+
+ /* If a mount operation is in progress, then pending_mount_op is != NULL. This
+ * is used to cancel the operation to make possible authentication dialogs go
+ * away.
+ */
+ MountData *mount_pending_op;
};
static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);
@@ -120,7 +131,7 @@ static void
emit_changed (GVfsUDisks2Volume *volume)
{
g_signal_emit_by_name (volume, "changed");
- g_signal_emit_by_name (volume->monitor, "volume_changed", volume);
+ g_signal_emit_by_name (volume->monitor, "volume-changed", volume);
}
static UDisksDrive *
@@ -299,11 +310,8 @@ gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor *monitor,
void
gvfs_udisks2_volume_removed (GVfsUDisks2Volume *volume)
{
-#if 0
-TODO
- if (volume->pending_mount_op != NULL)
- cancel_pending_mount_op (volume->pending_mount_op);
-#endif
+ if (volume->mount_pending_op != NULL)
+ mount_cancel_pending_op (volume->mount_pending_op);
if (volume->mount != NULL)
{
@@ -491,6 +499,143 @@ gvfs_udisks2_volume_get_activation_root (GVolume *_volume)
/* ---------------------------------------------------------------------------------------------------- */
+struct MountData
+{
+ GSimpleAsyncResult *simple;
+
+ GVfsUDisks2Volume *volume;
+
+ GCancellable *cancellable;
+
+ GMountOperation *mount_operation;
+};
+
+static void
+mount_data_free (MountData *data)
+{
+ g_object_unref (data->simple);
+
+ g_clear_object (&data->volume);
+ g_clear_object (&data->cancellable);
+ g_clear_object (&data->mount_operation);
+ g_free (data);
+}
+
+static void
+mount_cancel_pending_op (MountData *data)
+{
+ g_debug ("woot, cancelling");
+ /* send an ::aborted signal to make the dialog go away */
+ if (data->mount_operation != NULL)
+ g_signal_emit_by_name (data->mount_operation, "aborted");
+ g_cancellable_cancel (data->cancellable);
+}
+
+static void
+mount_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MountData *data = user_data;
+ gchar *mount_path;
+ GError *error;
+
+ /* we are no longer pending */
+ data->volume->mount_pending_op = NULL;
+
+ error = NULL;
+ if (!udisks_filesystem_call_mount_finish (UDISKS_FILESYSTEM (source_object),
+ &mount_path,
+ res,
+ &error))
+ {
+ g_simple_async_result_take_error (data->simple, error);
+ g_simple_async_result_complete (data->simple);
+ }
+ else
+ {
+ gvfs_udisks2_volume_monitor_update (data->volume->monitor);
+ g_simple_async_result_complete (data->simple);
+ g_free (mount_path);
+ }
+ mount_data_free (data);
+}
+
+static void
+gvfs_udisks2_volume_mount (GVolume *_volume,
+ GMountMountFlags flags,
+ GMountOperation *mount_operation,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+ UDisksFilesystem *filesystem;
+ GVariantBuilder builder;
+ MountData *data;
+
+ data = g_new0 (MountData, 1);
+ data->simple = g_simple_async_result_new (G_OBJECT (volume),
+ callback,
+ user_data,
+ gvfs_udisks2_volume_mount);
+ data->volume = g_object_ref (volume);
+
+ if (volume->mount_pending_op != NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "A mount operation is already pending");
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+
+ filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (volume->block))));
+ if (filesystem == NULL)
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "No filesystem interface on D-Bus object");
+ g_simple_async_result_complete (data->simple);
+ mount_data_free (data);
+ goto out;
+ }
+
+ data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+ data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
+ volume->mount_pending_op = data;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+ if (data->mount_operation == NULL)
+ {
+ g_variant_builder_add (&builder,
+ "{sv}",
+ "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+ }
+ udisks_filesystem_call_mount (filesystem,
+ g_variant_builder_end (&builder),
+ data->cancellable,
+ mount_cb,
+ data);
+
+ out:
+ ;
+}
+
+static gboolean
+gvfs_udisks2_volume_mount_finish (GVolume *volume,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ return !g_simple_async_result_propagate_error (simple, error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface)
{
@@ -506,9 +651,9 @@ gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface)
iface->enumerate_identifiers = gvfs_udisks2_volume_enumerate_identifiers;
iface->get_identifier = gvfs_udisks2_volume_get_identifier;
-#if 0
iface->mount_fn = gvfs_udisks2_volume_mount;
iface->mount_finish = gvfs_udisks2_volume_mount_finish;
+#if 0
iface->eject = gvfs_udisks2_volume_eject;
iface->eject_finish = gvfs_udisks2_volume_eject_finish;
iface->eject_with_operation = gvfs_udisks2_volume_eject_with_operation;
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c
index 0b14f2e..4c2df40 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.c
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.c
@@ -275,7 +275,7 @@ get_mount_for_mount_path (const gchar *mount_path,
for (l = monitor->mounts; l != NULL; l = l->next)
{
GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
- if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+ if (g_strcmp0 (gvfs_udisks2_mount_get_mount_path (mount), mount_path) == 0)
{
ret = g_object_ref (mount);
goto out;
@@ -397,6 +397,16 @@ gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor
/* ---------------------------------------------------------------------------------------------------- */
+void
+gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor)
+{
+ g_return_if_fail (GVFS_IS_UDISKS2_VOLUME_MONITOR (monitor));
+ udisks_client_settle (monitor->client);
+ update_all (monitor, TRUE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static UDisksClient *
get_udisks_client_sync (GError **error)
{
@@ -809,7 +819,7 @@ find_mount_by_mount_path (GVfsUDisks2VolumeMonitor *monitor,
for (l = monitor->mounts; l != NULL; l = l->next)
{
GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
- if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+ if (g_strcmp0 (gvfs_udisks2_mount_get_mount_path (mount), mount_path) == 0)
{
ret = mount;
goto out;
@@ -1034,6 +1044,7 @@ update_mounts (GVfsUDisks2VolumeMonitor *monitor,
gvfs_udisks2_mount_unmounted (mount);
monitor->mounts = g_list_remove (monitor->mounts, mount);
*removed_mounts = g_list_prepend (*removed_mounts, g_object_ref (mount));
+ g_debug ("removed mount at %s", gvfs_udisks2_mount_get_mount_path (mount));
g_object_unref (mount);
}
}
@@ -1050,6 +1061,7 @@ update_mounts (GVfsUDisks2VolumeMonitor *monitor,
{
monitor->mounts = g_list_prepend (monitor->mounts, mount);
*added_mounts = g_list_prepend (*added_mounts, g_object_ref (mount));
+ g_debug ("added mount at %s for %p", gvfs_udisks2_mount_get_mount_path (mount), volume);
}
}
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.h b/monitor/udisks2/gvfsudisks2volumemonitor.h
index a152743..c08d58e 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.h
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.h
@@ -46,6 +46,7 @@ typedef struct _GVfsUDisks2Mount GVfsUDisks2Mount;
GType gvfs_udisks2_volume_monitor_get_type (void) G_GNUC_CONST;
GVolumeMonitor *gvfs_udisks2_volume_monitor_new (void);
UDisksClient *gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor);
+void gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]