/** * udisks_daemon_util_hexdump_debug: * @data: Pointer to data. * @len: Length of data. * * Utility function to dumps the hexadecimal representation of @len * bytes of @data generated with udisks_daemon_util_hexdump() using * udisks_debug(). */ void udisks_daemon_util_hexdump_debug (gconstpointer data, gsize len) { gchar *s = udisks_daemon_util_hexdump (data, len); udisks_debug ("Hexdump of %" G_GSIZE_FORMAT " bytes:\n%s", len, s); g_free (s); }
static gboolean attr_changed (GIOChannel *channel, GIOCondition cond, gpointer user_data) { UDisksLinuxMDRaidObject *object = UDISKS_LINUX_MDRAID_OBJECT (user_data); gboolean bail = FALSE; GError *error = NULL; gchar *str = NULL; gsize len = 0; if (cond & ~G_IO_ERR) goto out; if (g_io_channel_seek_position (channel, 0, G_SEEK_SET, &error) != G_IO_STATUS_NORMAL) { udisks_debug ("Error seeking in channel (uuid %s): %s (%s, %d)", object->uuid, error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); bail = TRUE; goto out; } if (g_io_channel_read_to_end (channel, &str, &len, &error) != G_IO_STATUS_NORMAL) { udisks_debug ("Error reading (uuid %s): %s (%s, %d)", object->uuid, error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); bail = TRUE; goto out; } g_free (str); /* synthesize uevent */ if (object->raid_device != NULL) udisks_linux_mdraid_object_uevent (object, "change", object->raid_device, FALSE); out: if (bail) remove_watches (object); return TRUE; /* keep event source around */ }
/* called without lock held */ static void udisks_linux_provider_handle_uevent (UDisksLinuxProvider *provider, const gchar *action, UDisksLinuxDevice *device) { const gchar *subsystem; G_LOCK (provider_lock); udisks_debug ("uevent %s %s", action, g_udev_device_get_sysfs_path (device->udev_device)); subsystem = g_udev_device_get_subsystem (device->udev_device); if (g_strcmp0 (subsystem, "block") == 0) { handle_block_uevent (provider, action, device); } G_UNLOCK (provider_lock); }
/* 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); }