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 */
}
Example #2
0
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:
  ;
}