static UDisksObject * lookup_object_for_block (UDisksClient *client, dev_t block_device) { UDisksObject *ret; GList *objects; GList *l; ret = NULL; objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (client)); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); UDisksBlock *block; block = udisks_object_peek_block (object); if (block != NULL) { if (block_device == udisks_block_get_device_number (block)) { ret = g_object_ref (object); goto out; } } } out: g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
static void start_format_and_configure_block (StorageProvider *provider, UDisksBlock *block, GDBusMethodInvocation *invocation, const gchar *type, const gchar *erase, const gchar *label, const gchar *passphrase, const gchar *mount_point, const gchar *mount_options, const gchar *crypto_passphrase, const gchar *crypto_options) { GError *error = NULL; if (!storage_cleanup_block (provider, block, &error)) { g_dbus_error_strip_remote_error (error); g_dbus_method_invocation_return_error (invocation, COCKPIT_ERROR, COCKPIT_ERROR_FAILED, "%s", error->message); g_error_free (error); return; } FormatData *data = g_new0(FormatData, 1); data->block = g_object_ref (block); data->invocation = g_object_ref (invocation); data->mount_point = g_strdup (mount_point); data->mount_options = g_strdup (mount_options); data->crypto_passphrase = g_strdup (crypto_passphrase); data->crypto_options = g_strdup (crypto_options); data->udisks_object_manager = udisks_client_get_object_manager (storage_provider_get_udisks_client (provider)); data->object_added_handler_id = g_signal_connect (data->udisks_object_manager, "object-added", G_CALLBACK (on_udisks_object_added), data); GVariantBuilder options; g_variant_builder_init (&options, G_VARIANT_TYPE("a{sv}")); if (erase && strcmp (erase, "no") != 0) g_variant_builder_add (&options, "{sv}", "erase", g_variant_new_string (erase)); if (label && *label) g_variant_builder_add (&options, "{sv}", "label", g_variant_new_string (label)); if (passphrase && *passphrase) g_variant_builder_add (&options, "{sv}", "encrypt.passphrase", g_variant_new_string (passphrase)); udisks_block_call_format (block, type, g_variant_builder_end (&options), NULL, on_format_done, data); }
static void storage_remove_config (StorageProvider *provider, UDisksBlock *block, GVariant *config) { GVariantIter iter; GVariant *item; GError *error = NULL; gs_unref_object UDisksBlock *block_to_use = NULL; if (block == NULL) { /* Any block can be used to add/remove any configuration item. Let's hope we have at least one... XXX - UDisks should offer a method for manipulating fstab and crypttab on the Manager. */ UDisksClient *client = storage_provider_get_udisks_client (provider); GDBusObjectManager *manager = udisks_client_get_object_manager (client); GList *objects = g_dbus_object_manager_get_objects (manager); for (GList *l = objects; l; l = l->next) { UDisksObject *object = l->data; block_to_use = udisks_object_get_block (object); if (block_to_use) break; } g_list_free_full (objects, g_object_unref); if (block_to_use == NULL) { g_warning ("Can't remove config: no block object found."); return; } } else block_to_use = g_object_ref (block); g_variant_iter_init (&iter, config); while ((item = g_variant_iter_next_value (&iter)) != NULL) { if (!udisks_block_call_remove_configuration_item_sync (block_to_use, item, g_variant_new ("a{sv}", NULL), NULL, &error)) { gs_free gchar *config_text = g_variant_print (config, FALSE); g_warning ("Can't remove storage configuration '%s': %s", config_text, error->message); g_clear_error (&error); } } }
static void update_problems (GduSdMonitor *monitor, GList **problem_list, CheckProblemFunc check_func) { GList *want = NULL; GList *added = NULL; GList *removed = NULL; GList *objects; GList *l; objects = g_dbus_object_manager_get_objects (udisks_client_get_object_manager (monitor->client)); for (l = objects; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); if (check_func (monitor, object)) want = g_list_prepend (want, object); } want = g_list_sort (want, ptr_compare); *problem_list = g_list_sort (*problem_list, ptr_compare); diff_sorted_lists (*problem_list, want, ptr_compare, &added, &removed); for (l = removed; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_remove (*problem_list, object); g_object_unref (object); } for (l = added; l != NULL; l = l->next) { UDisksObject *object = UDISKS_OBJECT (l->data); *problem_list = g_list_prepend (*problem_list, g_object_ref (object)); } g_list_free (removed); g_list_free (added); g_list_free (want); g_list_free_full (objects, g_object_unref); }
static void udisks_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { UDisksClient *client = UDISKS_CLIENT (object); switch (prop_id) { case PROP_OBJECT_MANAGER: g_value_set_object (value, udisks_client_get_object_manager (client)); break; case PROP_MANAGER: g_value_set_object (value, udisks_client_get_manager (client)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void storage_provider_constructed (GObject *_object) { StorageProvider *provider = STORAGE_PROVIDER (_object); GError *error = NULL; /* TODO: use GInitable/GAsyncInitable or start() pattern here */ provider->udisks_client = udisks_client_new_sync (NULL, &error); if (provider->udisks_client == NULL) { g_warning ("Error connecting to udisks: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); goto out; } provider->lvm_objman = g_dbus_object_manager_client_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, "com.redhat.storaged", "/org/freedesktop/UDisks2", lvm_get_proxy_type, NULL, NULL, NULL, &error); if (provider->lvm_objman == NULL) { g_warning ("Error connecting to storaged: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); goto out; } g_signal_connect (provider->lvm_objman, "object-added", G_CALLBACK (on_lvm_object_added), provider); g_signal_connect (provider->lvm_objman, "object-removed", G_CALLBACK (on_lvm_object_removed), provider); g_signal_connect (provider->lvm_objman, "interface-added", G_CALLBACK (on_lvm_interface_added), provider); g_signal_connect (provider->lvm_objman, "interface-removed", G_CALLBACK (on_lvm_interface_removed), provider); GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); if (connection) { g_dbus_connection_signal_subscribe (connection, "com.redhat.storaged", "org.freedesktop.DBus.Properties", "PropertiesChanged", NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE, on_lvm_properties_changed, provider, NULL); } /* init */ provider_update (provider); provider_update_jobs (provider); g_signal_connect (provider->udisks_client, "changed", G_CALLBACK (on_udisks_client_changed), provider); /* We don't use the "changed" signal to watch jobs since we might miss some that only exist for a very short period, but we still want to report their failures. */ GDBusObjectManager *object_manager; object_manager = udisks_client_get_object_manager (provider->udisks_client); g_signal_connect (object_manager, "object-added", G_CALLBACK (on_object_added), provider); g_signal_connect (object_manager, "object-removed", G_CALLBACK (on_object_removed), provider); out: if (G_OBJECT_CLASS (storage_provider_parent_class)->constructed != NULL) G_OBJECT_CLASS (storage_provider_parent_class)->constructed (_object); }
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); }
static void provider_update_objects (StorageProvider *provider) { GDBusObjectManagerServer *object_manager; GList *udisks_objects; GList *lvm_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); wanted = NULL; for (l = udisks_objects; l != NULL; l = l->next) { GDBusInterface *iface = get_udisk_iface (UDISKS_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } for (l = lvm_objects; l != NULL; l = l->next) { if (!LVM_IS_OBJECT (l->data)) continue; GDBusInterface *iface = get_lvm_iface (LVM_OBJECT (l->data)); if (iface == NULL) continue; wanted = g_list_prepend (wanted, g_object_ref (iface)); } wanted = g_list_sort (wanted, (GCompareFunc)udisks_iface_compare_func); provider->ifaces = g_list_sort (provider->ifaces, (GCompareFunc)udisks_iface_compare_func); diff_sorted_lists (provider->ifaces, wanted, (GCompareFunc)udisks_iface_compare_func, &added, &removed, NULL); for (l = removed; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object; object = g_hash_table_lookup (provider->hash_interface_to_storage_object, iface); g_warn_if_fail (object != NULL); if (object) { 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_interface_to_storage_object, iface); provider->ifaces = g_list_remove (provider->ifaces, iface); g_object_unref (iface); } for (l = added; l != NULL; l = l->next) { GDBusInterface *iface = G_DBUS_INTERFACE (l->data); StorageObject *object = make_storage_object (provider, iface); g_warn_if_fail (g_hash_table_lookup (provider->hash_interface_to_storage_object, iface) == NULL); g_hash_table_insert (provider->hash_interface_to_storage_object, g_object_ref (iface), object); gs_free gchar *object_path = storage_object_make_object_path (object); g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); provider->ifaces = g_list_prepend (provider->ifaces, g_object_ref (iface)); } g_list_free (added); g_list_free (removed); g_list_free_full (udisks_objects, g_object_unref); g_list_free_full (lvm_objects, g_object_unref); g_list_free_full (wanted, g_object_unref); }