1
/* GIO - GLib Input, Output and Streaming Library
3
* Copyright (C) 2006-2007 Red Hat, Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Author: Alexander Larsson <alexl@redhat.com>
26
#include <sys/types.h>
27
#include <sys/socket.h>
31
#include <dbus/dbus.h>
32
#include <glib/gi18n.h>
33
#include "gvfsjobunmount.h"
34
#include "gvfsdbusutils.h"
35
#include "gvfsdaemonprotocol.h"
37
G_DEFINE_TYPE (GVfsJobUnmount, g_vfs_job_unmount, G_VFS_TYPE_JOB_DBUS)
39
static void run (GVfsJob *job);
40
static gboolean try (GVfsJob *job);
41
static void send_reply (GVfsJob *job);
42
static DBusMessage *create_reply (GVfsJob *job,
43
DBusConnection *connection,
44
DBusMessage *message);
47
g_vfs_job_unmount_finalize (GObject *object)
51
job = G_VFS_JOB_UNMOUNT (object);
53
if (job->mount_source)
54
g_object_unref (job->mount_source);
56
if (G_OBJECT_CLASS (g_vfs_job_unmount_parent_class)->finalize)
57
(*G_OBJECT_CLASS (g_vfs_job_unmount_parent_class)->finalize) (object);
61
g_vfs_job_unmount_class_init (GVfsJobUnmountClass *klass)
63
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
64
GVfsJobClass *job_class = G_VFS_JOB_CLASS (klass);
65
GVfsJobDBusClass *job_dbus_class = G_VFS_JOB_DBUS_CLASS (klass);
67
gobject_class->finalize = g_vfs_job_unmount_finalize;
70
job_class->send_reply = send_reply;
72
job_dbus_class->create_reply = create_reply;
77
g_vfs_job_unmount_init (GVfsJobUnmount *job)
82
g_vfs_job_unmount_new (DBusConnection *connection,
90
const char *dbus_id, *obj_path;
94
dbus_error_init (&derror);
95
dbus_message_iter_init (message, &iter);
97
if (!_g_dbus_message_iter_get_args (&iter, &derror,
98
DBUS_TYPE_STRING, &dbus_id,
99
DBUS_TYPE_OBJECT_PATH, &obj_path,
100
DBUS_TYPE_UINT32, &flags,
103
reply = dbus_message_new_error (message,
106
dbus_error_free (&derror);
108
dbus_connection_send (connection, reply, NULL);
109
dbus_message_unref (reply);
113
g_debug ("g_vfs_job_unmount_new request: %p\n", message);
115
job = g_object_new (G_VFS_TYPE_JOB_UNMOUNT,
117
"connection", connection,
120
job->backend = backend;
122
job->mount_source = g_mount_source_new (dbus_id, obj_path);
124
return G_VFS_JOB (job);
130
GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
131
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
133
class->unmount (op_job->backend,
136
op_job->mount_source);
140
job_finish_immediately_if_possible (GVfsJobUnmount *op_job)
142
GVfsBackend *backend = op_job->backend;
143
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
145
gboolean force_unmount;
147
if (class->try_unmount != NULL || class->unmount != NULL)
150
is_busy = g_vfs_backend_has_blocking_processes (backend);
151
force_unmount = op_job->flags & G_MOUNT_UNMOUNT_FORCE;
153
if (is_busy && ! force_unmount)
154
g_vfs_job_failed_literal (G_VFS_JOB (op_job),
155
G_IO_ERROR, G_IO_ERROR_BUSY,
156
_("Filesystem is busy"));
158
g_vfs_job_succeeded (G_VFS_JOB (op_job));
164
unmount_cb (GVfsBackend *backend,
168
GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (user_data);
169
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
170
gboolean should_unmount;
173
should_unmount = g_vfs_backend_unmount_with_operation_finish (backend,
177
op_job->flags |= G_MOUNT_UNMOUNT_FORCE;
179
finished = job_finish_immediately_if_possible (op_job);
183
gboolean run_in_thread = TRUE;
185
if (class->try_unmount != NULL)
186
run_in_thread = ! class->try_unmount (op_job->backend,
189
op_job->mount_source);
192
g_vfs_daemon_run_job_in_thread (g_vfs_backend_get_daemon (backend),
200
GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
201
GVfsBackend *backend = op_job->backend;
202
GVfsBackendClass *class = G_VFS_BACKEND_GET_CLASS (op_job->backend);
204
gboolean force_unmount;
206
is_busy = g_vfs_backend_has_blocking_processes (backend);
207
force_unmount = op_job->flags & G_MOUNT_UNMOUNT_FORCE;
209
if (is_busy && ! force_unmount
210
&& ! g_mount_source_is_dummy (op_job->mount_source))
212
g_vfs_backend_unmount_with_operation (backend,
213
op_job->mount_source,
214
(GAsyncReadyCallback) unmount_cb,
219
if (job_finish_immediately_if_possible (op_job))
222
return class->try_unmount (op_job->backend,
225
op_job->mount_source);
229
unregister_mount_callback (DBusMessage *unmount_reply,
233
GVfsBackend *backend;
234
GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (user_data);
236
g_debug ("unregister_mount_callback, unmount_reply: %p, error: %p\n", unmount_reply, error);
238
backend = op_job->backend;
239
(*G_VFS_JOB_CLASS (g_vfs_job_unmount_parent_class)->send_reply) (G_VFS_JOB (op_job));
241
/* Unlink job source from daemon */
242
g_vfs_job_source_closed (G_VFS_JOB_SOURCE (backend));
244
g_vfs_daemon_close_active_channels (g_vfs_backend_get_daemon ((backend)));
247
/* Might be called on an i/o thread */
249
send_reply (GVfsJob *job)
251
GVfsJobUnmount *op_job = G_VFS_JOB_UNMOUNT (job);
253
g_debug ("send_reply, failed: %d\n", job->failed);
256
(*G_VFS_JOB_CLASS (g_vfs_job_unmount_parent_class)->send_reply) (G_VFS_JOB (op_job));
259
GVfsBackend *backend = op_job->backend;
261
/* Setting the backend to block requests will also
262
set active GVfsChannels to block requets */
263
g_vfs_backend_set_block_requests (backend);
264
g_vfs_backend_unregister_mount (backend,
265
unregister_mount_callback,
270
/* Might be called on an i/o thread */
272
create_reply (GVfsJob *job,
273
DBusConnection *connection,
274
DBusMessage *message)
278
reply = dbus_message_new_method_return (message);