void storage_daemon_publish (StorageDaemon *self, const gchar *path, gboolean uniquely, gpointer thing) { GDBusInterface *prev; GDBusInterfaceInfo *info; GDBusObjectSkeleton *object; GQuark detail; g_return_if_fail (STORAGE_IS_DAEMON (self)); g_return_if_fail (path != NULL); if (G_IS_DBUS_INTERFACE (thing)) { g_debug ("%spublishing iface: %s %s", uniquely ? "uniquely " : "", path, g_dbus_interface_get_info(thing)->name); object = G_DBUS_OBJECT_SKELETON (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (self->object_manager), path)); if (object != NULL) { if (uniquely) { info = g_dbus_interface_get_info (thing); prev = g_dbus_object_get_interface (G_DBUS_OBJECT (object), info->name); if (prev) { g_object_unref (prev); g_object_unref (object); object = NULL; } } } if (object == NULL) object = g_dbus_object_skeleton_new (path); g_dbus_object_skeleton_add_interface (object, thing); } else { g_critical ("Unsupported type to publish: %s", G_OBJECT_TYPE_NAME (thing)); return; } if (uniquely) g_dbus_object_manager_server_export_uniquely (self->object_manager, object); else g_dbus_object_manager_server_export (self->object_manager, object); detail = g_quark_from_static_string (G_OBJECT_TYPE_NAME (thing)); g_signal_emit (self, signals[PUBLISHED], detail, thing); g_object_unref (object); }
void setting_export (Setting *setting) { g_return_if_fail (IS_SETTING (setting)); GDBusObjectManagerServer *object_manager; object_manager = daemon_get_object_manager (setting->daemon); if (g_dbus_interface_get_object (G_DBUS_INTERFACE (setting)) == NULL) { LoomObjectSkeleton *object = NULL; object = loom_object_skeleton_new ("/org/blackox/Loom/Setting"); loom_object_skeleton_set_setting (object, LOOM_SETTING (setting)); g_dbus_object_manager_server_export_uniquely (object_manager, G_DBUS_OBJECT_SKELETON (object)); g_object_unref (object); } }
/* called with lock held */ static void handle_block_uevent_for_block (UDisksLinuxProvider *provider, const gchar *action, UDisksLinuxDevice *device) { const gchar *sysfs_path; UDisksLinuxBlockObject *object; UDisksDaemon *daemon; daemon = udisks_provider_get_daemon (UDISKS_PROVIDER (provider)); sysfs_path = g_udev_device_get_sysfs_path (device->udev_device); if (g_strcmp0 (action, "remove") == 0) { object = g_hash_table_lookup (provider->sysfs_to_block, sysfs_path); if (object != NULL) { g_dbus_object_manager_server_unexport (udisks_daemon_get_object_manager (daemon), g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); g_warn_if_fail (g_hash_table_remove (provider->sysfs_to_block, sysfs_path)); } } else { object = g_hash_table_lookup (provider->sysfs_to_block, sysfs_path); if (object != NULL) { udisks_linux_block_object_uevent (object, action, device); } else { object = udisks_linux_block_object_new (daemon, device); g_dbus_object_manager_server_export_uniquely (udisks_daemon_get_object_manager (daemon), G_DBUS_OBJECT_SKELETON (object)); g_hash_table_insert (provider->sysfs_to_block, g_strdup (sysfs_path), object); } } }
static void user_added (ActUserManager *um, ActUser *user, Accounts *accounts) { if (act_user_is_system_account (user)) return; GDBusObjectManagerServer *object_manager_server = daemon_get_object_manager (daemon_get ()); CockpitAccount *acc = account_new (); account_update (ACCOUNT (acc), user); gs_free gchar *path = utils_generate_object_path ("/com/redhat/Cockpit/Accounts", cockpit_account_get_user_name (acc)); gs_unref_object CockpitObjectSkeleton *obj = cockpit_object_skeleton_new (path); cockpit_object_skeleton_set_account (obj, acc); g_dbus_object_manager_server_export_uniquely (object_manager_server, G_DBUS_OBJECT_SKELETON (obj)); g_hash_table_insert (accounts->act_user_to_account, user, ACCOUNT(acc)); }
static void update_with_variant (GPid pid, GVariant *info, GError *error, gpointer user_data) { StoragedLinuxVolumeGroupObject *object = user_data; StoragedDaemon *daemon; GDBusObjectManagerServer *manager; GVariantIter *iter; GHashTableIter volume_iter; gpointer key, value; GHashTable *new_lvs; GHashTable *new_pvs; GList *objects, *l; gboolean needs_polling = FALSE; daemon = storaged_linux_volume_group_object_get_daemon (object); manager = storaged_daemon_get_object_manager (daemon); if (error) { storaged_warning ("Failed to update LVM volume group %s: %s", storaged_linux_volume_group_object_get_name (object), error->message); g_object_unref (object); return; } storaged_linux_volume_group_update (STORAGED_LINUX_VOLUME_GROUP (object->iface_volume_group), info, &needs_polling); if (!g_dbus_object_manager_server_is_exported (manager, G_DBUS_OBJECT_SKELETON (object))) g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (object)); new_lvs = g_hash_table_new (g_str_hash, g_str_equal); if (g_variant_lookup (info, "lvs", "aa{sv}", &iter)) { GVariant *lv_info = NULL; while (g_variant_iter_loop (iter, "@a{sv}", &lv_info)) { const gchar *name; StoragedLinuxLogicalVolumeObject *volume; g_variant_lookup (lv_info, "name", "&s", &name); update_operations (daemon, name, lv_info, &needs_polling); if (lv_is_pvmove_volume (name)) needs_polling = TRUE; if (storaged_daemon_util_lvm2_name_is_reserved (name)) continue; volume = g_hash_table_lookup (object->logical_volumes, name); if (volume == NULL) { volume = storaged_linux_logical_volume_object_new (daemon, object, name); storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling); storaged_linux_logical_volume_object_update_etctabs (volume); g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (volume)); g_hash_table_insert (object->logical_volumes, g_strdup (name), g_object_ref (volume)); } else storaged_linux_logical_volume_object_update (volume, lv_info, &needs_polling); g_hash_table_insert (new_lvs, (gchar *)name, volume); } g_variant_iter_free (iter); } g_hash_table_iter_init (&volume_iter, object->logical_volumes); while (g_hash_table_iter_next (&volume_iter, &key, &value)) { const gchar *name = key; StoragedLinuxLogicalVolumeObject *volume = value; if (!g_hash_table_contains (new_lvs, name)) { g_dbus_object_manager_server_unexport (manager, g_dbus_object_get_object_path (G_DBUS_OBJECT (volume))); g_hash_table_iter_remove (&volume_iter); g_object_unref (G_OBJECT (volume)); } } storaged_volume_group_set_needs_polling (STORAGED_VOLUME_GROUP (object->iface_volume_group), needs_polling); /* Update block objects. */ new_pvs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_variant_unref); if (g_variant_lookup (info, "pvs", "aa{sv}", &iter)) { const gchar *name; GVariant *pv_info; while (g_variant_iter_next (iter, "@a{sv}", &pv_info)) { if (g_variant_lookup (pv_info, "device", "&s", &name)) g_hash_table_insert (new_pvs, (gchar *)name, pv_info); else g_variant_unref (pv_info); } } objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager)); for (l = objects; l != NULL; l = l->next) { if (STORAGED_IS_LINUX_BLOCK_OBJECT (l->data)) update_block (STORAGED_LINUX_BLOCK_OBJECT (l->data), object, new_lvs, new_pvs); } g_list_free_full (objects, g_object_unref); g_hash_table_destroy (new_lvs); g_hash_table_destroy (new_pvs); g_object_unref (object); }
/* called with lock held */ static void handle_block_uevent_for_drive (UDisksLinuxProvider *provider, const gchar *action, UDisksLinuxDevice *device) { UDisksLinuxDriveObject *object; UDisksDaemon *daemon; const gchar *sysfs_path; gchar *vpd; vpd = NULL; daemon = udisks_provider_get_daemon (UDISKS_PROVIDER (provider)); sysfs_path = g_udev_device_get_sysfs_path (device->udev_device); if (g_strcmp0 (action, "remove") == 0) { object = g_hash_table_lookup (provider->sysfs_path_to_drive, sysfs_path); if (object != NULL) { GList *devices; udisks_linux_drive_object_uevent (object, action, device); g_warn_if_fail (g_hash_table_remove (provider->sysfs_path_to_drive, sysfs_path)); devices = udisks_linux_drive_object_get_devices (object); if (devices == NULL) { const gchar *existing_vpd; existing_vpd = g_object_get_data (G_OBJECT (object), "x-vpd"); g_dbus_object_manager_server_unexport (udisks_daemon_get_object_manager (daemon), g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); g_warn_if_fail (g_hash_table_remove (provider->vpd_to_drive, existing_vpd)); } g_list_foreach (devices, (GFunc) g_object_unref, NULL); g_list_free (devices); } } else { if (!udisks_linux_drive_object_should_include_device (provider->gudev_client, device, &vpd)) goto out; if (vpd == NULL) { udisks_debug ("Ignoring block device %s with no serial or WWN", g_udev_device_get_sysfs_path (device->udev_device)); goto out; } object = g_hash_table_lookup (provider->vpd_to_drive, vpd); if (object != NULL) { if (g_hash_table_lookup (provider->sysfs_path_to_drive, sysfs_path) == NULL) g_hash_table_insert (provider->sysfs_path_to_drive, g_strdup (sysfs_path), object); udisks_linux_drive_object_uevent (object, action, device); } else { object = udisks_linux_drive_object_new (daemon, device); if (object != NULL) { g_object_set_data_full (G_OBJECT (object), "x-vpd", g_strdup (vpd), g_free); g_dbus_object_manager_server_export_uniquely (udisks_daemon_get_object_manager (daemon), G_DBUS_OBJECT_SKELETON (object)); g_hash_table_insert (provider->vpd_to_drive, g_strdup (vpd), object); g_hash_table_insert (provider->sysfs_path_to_drive, g_strdup (sysfs_path), object); /* schedule initial housekeeping for the drive unless coldplugging */ if (!provider->coldplug) { g_io_scheduler_push_job (perform_initial_housekeeping_for_drive, g_object_ref (object), (GDestroyNotify) g_object_unref, G_PRIORITY_DEFAULT, NULL); } } } } out: g_free (vpd); }
static void handle_block_uevent_for_mdraid_with_uuid (UDisksLinuxProvider *provider, const gchar *action, UDisksLinuxDevice *device, const gchar *uuid, gboolean is_member) { UDisksLinuxMDRaidObject *object; UDisksDaemon *daemon; const gchar *sysfs_path; daemon = udisks_provider_get_daemon (UDISKS_PROVIDER (provider)); sysfs_path = g_udev_device_get_sysfs_path (device->udev_device); /* if uuid is NULL or bogus, consider it a remove event */ if (uuid == NULL || g_strcmp0 (uuid, "00000000:00000000:00000000:00000000") == 0) action = "remove"; if (g_strcmp0 (action, "remove") == 0) { /* first check if this device was a member */ object = g_hash_table_lookup (provider->sysfs_path_to_mdraid_members, sysfs_path); if (object != NULL) { udisks_linux_mdraid_object_uevent (object, action, device, TRUE /* is_member */); g_warn_if_fail (g_hash_table_remove (provider->sysfs_path_to_mdraid_members, sysfs_path)); maybe_remove_mdraid_object (provider, object); } /* then check if the device was the raid device */ object = g_hash_table_lookup (provider->sysfs_path_to_mdraid, sysfs_path); if (object != NULL) { udisks_linux_mdraid_object_uevent (object, action, device, FALSE /* is_member */); g_warn_if_fail (g_hash_table_remove (provider->sysfs_path_to_mdraid, sysfs_path)); maybe_remove_mdraid_object (provider, object); } } else { if (uuid == NULL) goto out; object = g_hash_table_lookup (provider->uuid_to_mdraid, uuid); if (object != NULL) { if (is_member) { if (g_hash_table_lookup (provider->sysfs_path_to_mdraid_members, sysfs_path) == NULL) g_hash_table_insert (provider->sysfs_path_to_mdraid_members, g_strdup (sysfs_path), object); } else { if (g_hash_table_lookup (provider->sysfs_path_to_mdraid, sysfs_path) == NULL) g_hash_table_insert (provider->sysfs_path_to_mdraid, g_strdup (sysfs_path), object); } udisks_linux_mdraid_object_uevent (object, action, device, is_member); } else { object = udisks_linux_mdraid_object_new (daemon, uuid); udisks_linux_mdraid_object_uevent (object, action, device, is_member); g_dbus_object_manager_server_export_uniquely (udisks_daemon_get_object_manager (daemon), G_DBUS_OBJECT_SKELETON (object)); g_hash_table_insert (provider->uuid_to_mdraid, g_strdup (uuid), object); if (is_member) g_hash_table_insert (provider->sysfs_path_to_mdraid_members, g_strdup (sysfs_path), object); else g_hash_table_insert (provider->sysfs_path_to_mdraid, g_strdup (sysfs_path), object); } } out: ; }
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); }