static gboolean storage_threaded_job_threaded_job_completed_default (StorageThreadedJob *job, gboolean result, GError *error) { if (result) { udisks_job_emit_completed (UDISKS_JOB (job), TRUE, ""); } else { GString *message; g_assert (error != NULL); message = g_string_new (NULL); g_string_append_printf (message, "Threaded job failed with error: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); udisks_job_emit_completed (UDISKS_JOB (job), FALSE, message->str); g_string_free (message, TRUE); } return TRUE; }
static gboolean udisks_spawned_job_spawned_job_completed_default (UlSpawnedJob *self, GError *error, gint status, GString *standard_output, GString *standard_error) { g_debug ("spawned job completed: " " status=%d (WIFEXITED=%d WEXITSTATUS=%d) " " standard_output=`%s' (%d bytes)\n" " standard_error=`%s' (%d bytes)\n", status, WIFEXITED (status), WEXITSTATUS (status), standard_output->str, (gint) standard_output->len, standard_error->str, (gint) standard_error->len); if (error != NULL) { gchar *message; message = g_strdup_printf ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); udisks_job_emit_completed (UDISKS_JOB (self), FALSE, message); g_free (message); } else if (ul_util_check_status_and_output (self->argv[0], status, standard_error->str, standard_output->str, &error)) { udisks_job_emit_completed (UDISKS_JOB (self), TRUE, standard_error->str); } else { udisks_job_emit_completed (UDISKS_JOB (self), FALSE, error->message); g_error_free (error); } return TRUE; }
StorageJob * storage_daemon_launch_spawned_jobv (StorageDaemon *self, gpointer object_or_interface, const gchar *job_operation, uid_t job_started_by_uid, GCancellable *cancellable, uid_t run_as_uid, uid_t run_as_euid, const gchar *input_string, const gchar **argv) { StorageSpawnedJob *job; GDBusObjectSkeleton *job_object; gchar *job_object_path; g_return_val_if_fail (STORAGE_IS_DAEMON (self), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); job = storage_spawned_job_new (argv, input_string, run_as_uid, run_as_euid, cancellable); if (object_or_interface != NULL) storage_job_add_thing (STORAGE_JOB (job), object_or_interface); /* TODO: protect job_id by a mutex */ job_object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++); job_object = g_dbus_object_skeleton_new (job_object_path); g_dbus_object_skeleton_add_interface (job_object, G_DBUS_INTERFACE_SKELETON (job)); g_free (job_object_path); udisks_job_set_cancelable (UDISKS_JOB (job), TRUE); udisks_job_set_operation (UDISKS_JOB (job), job_operation); udisks_job_set_started_by_uid (UDISKS_JOB (job), job_started_by_uid); g_dbus_object_manager_server_export (self->object_manager, G_DBUS_OBJECT_SKELETON (job_object)); self->num_jobs++; g_signal_connect_after (job, "completed", G_CALLBACK (on_job_completed), g_object_ref (self)); g_object_unref (job_object); return STORAGE_JOB (job); }
/** * storage_daemon_launch_threaded_job: * @daemon: A #StorageDaemon. * @object: (allow-none): An object to add to the job or %NULL. * @job_operation: The operation for the job. * @job_started_by_uid: The user who started the job. * @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. * @cancellable: A #GCancellable or %NULL. * * Launches a new job by running @job_func in a new dedicated thread. * * The job is started immediately - connect to the * #StorageThreadedJob::threaded-job-completed or #StorageJob::completed * signals to get notified when the job is done. * * Long-running jobs should periodically check @cancellable to see if * they have been cancelled. * * The returned object will be exported on the bus until the * #StorageJob::completed signal is emitted on the object. It is not * valid to use the returned object after this signal fires. * * Returns: A #StorageThreadedJob object. Do not free, the object * belongs to @manager. */ StorageJob * storage_daemon_launch_threaded_job (StorageDaemon *daemon, gpointer object_or_interface, const gchar *job_operation, uid_t job_started_by_uid, StorageJobFunc job_func, gpointer user_data, GDestroyNotify user_data_free_func, GCancellable *cancellable) { StorageThreadedJob *job; GDBusObjectSkeleton *job_object; gchar *job_object_path; g_return_val_if_fail (STORAGE_IS_DAEMON (daemon), NULL); g_return_val_if_fail (job_func != NULL, NULL); job = storage_threaded_job_new (job_func, user_data, user_data_free_func, cancellable); if (object_or_interface != NULL) storage_job_add_thing (STORAGE_JOB (job), object_or_interface); /* TODO: protect job_id by a mutex */ job_object_path = g_strdup_printf ("/org/freedesktop/UDisks2/jobs/%d", job_id++); job_object = g_dbus_object_skeleton_new (job_object_path); g_dbus_object_skeleton_add_interface (job_object, G_DBUS_INTERFACE_SKELETON (job)); g_free (job_object_path); udisks_job_set_cancelable (UDISKS_JOB (job), TRUE); udisks_job_set_operation (UDISKS_JOB (job), job_operation); udisks_job_set_started_by_uid (UDISKS_JOB (job), job_started_by_uid); g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (job_object)); daemon->num_jobs++; g_signal_connect_after (job, "completed", G_CALLBACK (on_job_completed), g_object_ref (daemon)); g_object_unref (job_object); return STORAGE_JOB (job); }
static void provider_update_jobs (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_objects; GList *all_objects; GList *wanted; GList *added, *removed; GList *l; object_manager = G_DBUS_OBJECT_MANAGER_SERVER (daemon_get_object_manager (provider->daemon)); udisks_objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (provider->udisks_client)); lvm_objects = g_dbus_object_manager_get_objects (provider->lvm_objman); all_objects = g_list_concat (udisks_objects, lvm_objects); wanted = NULL; for (l = all_objects; l != NULL; l = l->next) { if (!UDISKS_IS_OBJECT (l->data)) continue; UDisksObject *object = UDISKS_OBJECT (l->data); UDisksJob *job; job = udisks_object_peek_job (object); if (job == NULL) continue; const gchar *operation = udisks_job_get_operation (job); if (strcmp (operation, "format-mkfs") != 0 && strcmp (operation, "format-erase") != 0 && strcmp (operation, "lvm-vg-empty-device") != 0) continue; wanted = g_list_prepend (wanted, g_object_ref (job)); } wanted = g_list_sort (wanted, (GCompareFunc)_udisks_job_compare_func); provider->jobs = g_list_sort (provider->jobs, (GCompareFunc)_udisks_job_compare_func); diff_sorted_lists (provider->jobs, wanted, (GCompareFunc)_udisks_job_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitJob *object; object = g_hash_table_lookup (provider->hash_job_to_storage_job, job); if (object == NULL) { g_warning ("No object for job %p", job); } else { g_warn_if_fail (g_dbus_object_manager_server_unexport (object_manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)))); g_hash_table_remove (provider->hash_job_to_storage_job, job); } provider->jobs = g_list_remove (provider->jobs, job); g_object_unref (job); } for (l = added; l != NULL; l = l->next) { UDisksJob *job = UDISKS_JOB (l->data); CockpitObjectSkeleton *object; CockpitJob *cockpit_job; gchar *object_path; object_path = utils_generate_object_path ("/com/redhat/Cockpit/Jobs", udisks_job_get_operation (job)); cockpit_job = storage_job_new (provider, job); object = cockpit_object_skeleton_new (object_path); cockpit_object_skeleton_set_job (object, cockpit_job); g_object_unref (cockpit_job); g_free (object_path); g_warn_if_fail (g_hash_table_lookup (provider->hash_job_to_storage_job, job) == NULL); g_hash_table_insert (provider->hash_job_to_storage_job, g_object_ref (job), object); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->jobs = g_list_prepend (provider->jobs, g_object_ref (job)); } g_list_free (added); g_list_free (removed); g_list_free_full (all_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }