This can be used to render spinners, e.g.
http://people.freedesktop.org/~david/gdu2-spinners.png
Signed-off-by: David Zeuthen <davidz@redhat.com>
-->
<property name="ExpectedEndTime" type="t" access="read"/>
+ <!-- Objects: The objects that the job is related to, if any. -->
+ <property name="Objects" type="ao" access="read"/>
+
<!--
Cancel:
@options: Options (currently unused except for <link linkend="udisks-std-options">standard options</link>).
udisks_client_get_cleartext_block
udisks_client_get_partition_table
udisks_client_get_partitions
+udisks_client_get_jobs_for_object
<SUBSECTION>
udisks_client_get_drive_info
udisks_client_get_partition_info
<TITLE>UDisksBaseJob</TITLE>
UDisksBaseJob
UDisksBaseJobClass
+udisks_base_job_add_object
+udisks_base_job_remove_object
udisks_base_job_get_cancellable
<SUBSECTION Standard>
UDISKS_TYPE_BASE_JOB
udisks_job_get_expected_end_time
udisks_job_get_progress
udisks_job_get_start_time
+udisks_job_get_objects
+udisks_job_dup_objects
udisks_job_set_expected_end_time
udisks_job_set_progress
udisks_job_set_start_time
+udisks_job_set_objects
UDisksJobProxy
UDisksJobProxyClass
udisks_job_proxy_new
/* ---------------------------------------------------------------------------------------------------- */
+/**
+ * udisks_base_job_add_object:
+ * @job: A #UDisksBaseJob.
+ * @object: A #UDisksObject.
+ *
+ * Adds the object path for @object to the <link
+ * linkend="gdbus-property-org-freedesktop-UDisks2-Job.Objects">Objects</link>
+ * array. If the object path is already in the array, does nothing.
+ */
+void
+udisks_base_job_add_object (UDisksBaseJob *job,
+ UDisksObject *object)
+{
+ const gchar *object_path;
+ const gchar *const *paths;
+ const gchar **p;
+ guint n;
+
+ g_return_if_fail (UDISKS_IS_BASE_JOB (job));
+ g_return_if_fail (UDISKS_IS_OBJECT (object));
+
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+ paths = udisks_job_get_objects (UDISKS_JOB (job));
+ for (n = 0; paths != NULL && paths[n] != NULL; n++)
+ {
+ if (g_strcmp0 (paths[n], object_path) == 0)
+ goto out;
+ }
+
+ p = g_new0 (const gchar *, n + 2);
+ p[n] = object_path;
+ udisks_job_set_objects (UDISKS_JOB (job), p);
+ g_free (p);
+
+ out:
+ ;
+}
+
+/**
+ * udisks_base_job_remove_object:
+ * @job: A #UDisksBaseJob.
+ * @object: A #UDisksObject.
+ *
+ * Removes the object path for @object to the <link
+ * linkend="gdbus-property-org-freedesktop-UDisks2-Job.Objects">Objects</link>
+ * array. If the object path is not in the array, does nothing.
+ */
+void
+udisks_base_job_remove_object (UDisksBaseJob *job,
+ UDisksObject *object)
+{
+ const gchar *object_path;
+ const gchar *const *paths;
+ GPtrArray *p = NULL;
+ guint n;
+
+ g_return_if_fail (UDISKS_IS_BASE_JOB (job));
+ g_return_if_fail (UDISKS_IS_OBJECT (object));
+
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+ paths = udisks_job_get_objects (UDISKS_JOB (job));
+ for (n = 0; paths != NULL && paths[n] != NULL; n++)
+ {
+ if (g_strcmp0 (paths[n], object_path) != 0)
+ {
+ if (p == NULL)
+ p = g_ptr_array_new ();
+ g_ptr_array_add (p, (gpointer) paths[n]);
+ }
+ }
+
+ if (p != NULL)
+ {
+ g_ptr_array_add (p, NULL);
+ udisks_job_set_objects (UDISKS_JOB (job), (const gchar *const *) p->pdata);
+ g_ptr_array_free (p, TRUE);
+ }
+ else
+ {
+ udisks_job_set_objects (UDISKS_JOB (job), NULL);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static gboolean
handle_cancel (UDisksJob *object,
GDBusMethodInvocation *invocation,
GType udisks_base_job_get_type (void) G_GNUC_CONST;
GCancellable *udisks_base_job_get_cancellable (UDisksBaseJob *job);
+void udisks_base_job_add_object (UDisksBaseJob *job,
+ UDisksObject *object);
+void udisks_base_job_remove_object (UDisksBaseJob *job,
+ UDisksObject *object);
G_END_DECLS
escaped_mount_point = g_strescape (mount_point, NULL);
/* right now -l is the only way to "force unmount" file systems... */
if (!udisks_daemon_launch_spawned_job_sync (cleanup->daemon,
+ NULL, /* UDisksObject */
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
error_message = NULL;
escaped_device_file = g_strescape (device_file_cleartext, NULL);
if (!udisks_daemon_launch_spawned_job_sync (cleanup->daemon,
+ NULL, /* UDisksObject */
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
error_message = NULL;
escaped_loop_device_file = g_strescape (loop_device, NULL);
if (!udisks_daemon_launch_spawned_job_sync (cleanup->daemon,
+ NULL, /* UDisksObject */
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
/**
* udisks_daemon_launch_simple_job:
* @daemon: A #UDisksDaemon.
+ * @object: (allow-none): A #UDisksObject to add to the job or %NULL.
* @cancellable: A #GCancellable or %NULL.
*
* Launches a new simple job.
*/
UDisksBaseJob *
udisks_daemon_launch_simple_job (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable)
{
UDisksSimpleJob *job;
- UDisksObjectSkeleton *object;
- gchar *object_path;
+ UDisksObjectSkeleton *job_object;
+ gchar *job_object_path;
g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
job = udisks_simple_job_new (cancellable);
+ if (object != NULL)
+ udisks_base_job_add_object (UDISKS_BASE_JOB (job), object);
/* TODO: protect job_id by a mutex */
- object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
- object = udisks_object_skeleton_new (object_path);
- udisks_object_skeleton_set_job (object, UDISKS_JOB (job));
- g_free (object_path);
+ job_object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
+ job_object = udisks_object_skeleton_new (job_object_path);
+ udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
+ g_free (job_object_path);
- g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object));
+ g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
g_signal_connect_after (job,
"completed",
G_CALLBACK (on_job_completed),
/**
* udisks_daemon_launch_threaded_job:
* @daemon: A #UDisksDaemon.
+ * @object: (allow-none): A #UDisksObject to add to the job or %NULL.
* @job_func: The function to run in another thread.
* @user_data: User data to pass to @job_func.
* @user_data_free_func: Function to free @user_data with or %NULL.
*/
UDisksBaseJob *
udisks_daemon_launch_threaded_job (UDisksDaemon *daemon,
+ UDisksObject *object,
UDisksThreadedJobFunc job_func,
gpointer user_data,
GDestroyNotify user_data_free_func,
GCancellable *cancellable)
{
UDisksThreadedJob *job;
- UDisksObjectSkeleton *object;
- gchar *object_path;
+ UDisksObjectSkeleton *job_object;
+ gchar *job_object_path;
g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
g_return_val_if_fail (job_func != NULL, NULL);
user_data,
user_data_free_func,
cancellable);
+ if (object != NULL)
+ udisks_base_job_add_object (UDISKS_BASE_JOB (job), object);
/* TODO: protect job_id by a mutex */
- object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
- object = udisks_object_skeleton_new (object_path);
- udisks_object_skeleton_set_job (object, UDISKS_JOB (job));
- g_free (object_path);
+ job_object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
+ job_object = udisks_object_skeleton_new (job_object_path);
+ udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
+ g_free (job_object_path);
- g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object));
+ g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
g_signal_connect_after (job,
"completed",
G_CALLBACK (on_job_completed),
/**
* udisks_daemon_launch_spawned_job:
* @daemon: A #UDisksDaemon.
+ * @object: (allow-none): A #UDisksObject to add to the job or %NULL.
* @cancellable: A #GCancellable or %NULL.
* @run_as_uid: The #uid_t to run the command as.
* @run_as_euid: The effective #uid_t to run the command as.
*/
UDisksBaseJob *
udisks_daemon_launch_spawned_job (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable,
uid_t run_as_uid,
uid_t run_as_euid,
va_list var_args;
gchar *command_line;
UDisksSpawnedJob *job;
- UDisksObjectSkeleton *object;
- gchar *object_path;
+ UDisksObjectSkeleton *job_object;
+ gchar *job_object_path;
g_return_val_if_fail (UDISKS_IS_DAEMON (daemon), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
job = udisks_spawned_job_new (command_line, input_string, run_as_uid, run_as_euid, cancellable);
g_free (command_line);
+ if (object != NULL)
+ udisks_base_job_add_object (UDISKS_BASE_JOB (job), object);
+
/* TODO: protect job_id by a mutex */
- object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
- object = udisks_object_skeleton_new (object_path);
- udisks_object_skeleton_set_job (object, UDISKS_JOB (job));
- g_free (object_path);
+ job_object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++);
+ job_object = udisks_object_skeleton_new (job_object_path);
+ udisks_object_skeleton_set_job (job_object, UDISKS_JOB (job));
+ g_free (job_object_path);
- g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object));
+ g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object));
g_signal_connect_after (job,
"completed",
G_CALLBACK (on_job_completed),
/**
* udisks_daemon_launch_spawned_job_sync:
* @daemon: A #UDisksDaemon.
+ * @object: (allow-none): A #UDisksObject to add to the job or %NULL.
* @cancellable: A #GCancellable or %NULL.
* @run_as_uid: The #uid_t to run the command as.
* @run_as_euid: The effective #uid_t to run the command as.
*/
gboolean
udisks_daemon_launch_spawned_job_sync (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable,
uid_t run_as_uid,
uid_t run_as_euid,
command_line = g_strdup_vprintf (command_line_format, var_args);
va_end (var_args);
job = udisks_daemon_launch_spawned_job (daemon,
+ object,
cancellable,
run_as_uid,
run_as_euid,
const gchar *object_path);
UDisksBaseJob *udisks_daemon_launch_simple_job (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable);
UDisksBaseJob *udisks_daemon_launch_spawned_job (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable,
uid_t run_as_uid,
uid_t run_as_euid,
const gchar *input_string,
const gchar *command_line_format,
- ...) G_GNUC_PRINTF (6, 7);
+ ...) G_GNUC_PRINTF (7, 8);
gboolean udisks_daemon_launch_spawned_job_sync (UDisksDaemon *daemon,
+ UDisksObject *object,
GCancellable *cancellable,
uid_t run_as_uid,
uid_t run_as_euid,
gchar **out_message,
const gchar *input_string,
const gchar *command_line_format,
- ...) G_GNUC_PRINTF (8, 9);
+ ...) G_GNUC_PRINTF (9, 10);
UDisksBaseJob *udisks_daemon_launch_threaded_job (UDisksDaemon *daemon,
+ UDisksObject *object,
UDisksThreadedJobFunc job_func,
gpointer user_data,
GDestroyNotify user_data_free_func,
wait_data = g_new0 (FormatWaitData, 1);
wait_data->object = object;
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
{
/* Create it */
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
/* Open it */
mapped_name = g_strdup_printf ("luks-%s", udisks_block_get_id_uuid (block));
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
command = subst_str (tmp, "$LABEL", escaped_label);
g_free (tmp);
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object_to_mkfs,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
goto out;
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ UDISKS_OBJECT (object),
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
{
drive->selftest_cancellable = g_cancellable_new ();
drive->selftest_job = UDISKS_THREADED_JOB (udisks_daemon_launch_threaded_job (daemon,
+ UDISKS_OBJECT (object),
selftest_job_func,
g_object_ref (drive),
g_object_unref,
/* TODO: support a 'readonly' option */
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
}
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
mount_fstab_as_root = FALSE;
mount_fstab_again:
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
mount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_uid */
mount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_euid */
/* run mount(8) */
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
escaped_mount_point = g_strescape (mount_point, NULL);
/* right now -l is the only way to "force unmount" file systems... */
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
unmount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_uid */
unmount_fstab_as_root ? 0 : caller_uid, /* uid_t run_as_euid */
}
escaped_mount_point = g_strescape (mount_point, NULL);
rc = udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
{
/* mount_point == NULL */
rc = udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
}
job = udisks_daemon_launch_spawned_job (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
}
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ NULL, /* UDisksObject */
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
fd = open (udisks_block_get_device (block), O_RDONLY);
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
fd = open (udisks_block_get_device (block), O_RDONLY);
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
fd = open (udisks_block_get_device (block), O_RDONLY);
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
escaped_device = g_strescape (udisks_block_get_device (partition_table_block), NULL);
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ partition_table_object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
}
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
/* wipe the newly created partition */
if (!udisks_daemon_launch_spawned_job_sync (daemon,
+ partition_object,
NULL, /* GCancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
goto out;
job = udisks_daemon_launch_spawned_job (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
goto out;
job = udisks_daemon_launch_spawned_job (daemon,
+ object,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
/* ---------------------------------------------------------------------------------------------------- */
+/**
+ * udisks_client_get_jobs_for_object:
+ * @client: A #UDisksClient.
+ * @object: A #UDisksObject.
+ *
+ * Gets all the #UDisksJob instances that reference @object, if any.
+ *
+ * Returns: (transfer full) (element-type UDisksJob): A list of #UDisksJob instances. The
+ * returned list should be freed with g_list_free() after each
+ * element has been freed with g_object_unref().
+ */
+GList *
+udisks_client_get_jobs_for_object (UDisksClient *client,
+ UDisksObject *object)
+{
+ GList *ret = NULL;
+ const gchar *object_path;
+ GList *l, *object_proxies = NULL;
+
+ /* TODO: this is probably slow. Can optimize by maintaining a hash-table from object path to UDisksJob* */
+
+ g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (UDISKS_IS_OBJECT (object), NULL);
+
+ object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
+
+ object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
+ for (l = object_proxies; l != NULL; l = l->next)
+ {
+ UDisksObject *object = UDISKS_OBJECT (l->data);
+ UDisksJob *job;
+
+ job = udisks_object_get_job (object);
+ if (job != NULL)
+ {
+ const gchar *const *object_paths;
+ guint n;
+ object_paths = udisks_job_get_objects (job);
+ for (n = 0; object_paths != NULL && object_paths[n] != NULL; n++)
+ {
+ if (g_strcmp0 (object_paths[n], object_path) == 0)
+ ret = g_list_prepend (ret, g_object_ref (job));
+ }
+ g_object_unref (job);
+ }
+ }
+ ret = g_list_reverse (ret);
+
+ g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
+ g_list_free (object_proxies);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
maybe_emit_changed_now (UDisksClient *client)
{
GList *udisks_client_get_partitions (UDisksClient *client,
UDisksPartitionTable *table);
+GList *udisks_client_get_jobs_for_object (UDisksClient *client,
+ UDisksObject *object);
+
void udisks_client_get_drive_info (UDisksClient *client,
UDisksDrive *drive,
gchar **out_name,