예제 #1
0
static void
on_lvm_logical_volume_notify (GObject *object,
                                 GParamSpec *pspec,
                                 gpointer user_data)
{
  StorageLogicalVolume *logical_volume = STORAGE_LOGICAL_VOLUME (user_data);
  storage_logical_volume_update (logical_volume);
}
예제 #2
0
static void
poll_with_variant (GPid pid,
                   GVariant *info,
                   GError *error,
                   gpointer user_data)
{
  StorageVolumeGroup *self = user_data;
  GVariantIter *iter;
  gboolean needs_polling;

  if (pid != self->poll_pid)
    {
      g_object_unref (self);
      return;
    }

  self->poll_pid = 0;

  if (error)
    {
      g_message ("Failed to poll LVM volume group %s: %s",
                 storage_volume_group_get_name (self), error->message);
      g_object_unref (self);
      return;
    }

  volume_group_update_props (self, info, &needs_polling);

  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;
          StorageLogicalVolume *volume;

          g_variant_lookup (lv_info, "name", "&s", &name);
          update_operations (name, lv_info, &needs_polling);
          volume = g_hash_table_lookup (self->logical_volumes, name);
          if (volume)
            storage_logical_volume_update (volume, self, lv_info, &needs_polling);
        }
      g_variant_iter_free (iter);
    }

  g_object_unref (self);
}
예제 #3
0
static void
storage_logical_volume_constructed (GObject *object)
{
  StorageLogicalVolume *logical_volume = STORAGE_LOGICAL_VOLUME(object);

  logical_volume->lvm_logical_volume = g_object_ref (storage_object_get_lvm_logical_volume (logical_volume->object));
  g_signal_connect (logical_volume->lvm_logical_volume,
                    "notify",
                    G_CALLBACK (on_lvm_logical_volume_notify),
                    logical_volume);

  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (logical_volume->lvm_logical_volume), G_MAXINT);

  storage_logical_volume_update (logical_volume);

  if (G_OBJECT_CLASS (storage_logical_volume_parent_class)->constructed != NULL)
    G_OBJECT_CLASS (storage_logical_volume_parent_class)->constructed (object);
}
예제 #4
0
static void
update_with_variant (GPid pid,
                     GVariant *info,
                     GError *error,
                     gpointer user_data)
{
  struct UpdateData *data = user_data;
  StorageVolumeGroup *self = data->self;
  GVariantIter *iter;
  GHashTableIter volume_iter;
  gpointer key, value;
  GHashTable *new_lvs;
  gboolean needs_polling = FALSE;
  StorageDaemon *daemon;
  gchar *path;

  daemon = storage_daemon_get ();

  if (!error)
      volume_group_update_props (self, info, &needs_polling);

  /* After basic props, publish group, if not already done */
  if (self->need_publish)
    {
      self->need_publish = FALSE;
      path = storage_util_build_object_path ("/org/freedesktop/UDisks2/lvm",
                                        storage_volume_group_get_name (self), NULL);
      storage_daemon_publish (daemon, path, FALSE, self);
      g_free (path);
    }

  if (error)
    {
      g_message ("Failed to update LVM volume group %s: %s",
                 storage_volume_group_get_name (self), error->message);
      g_object_unref (self);
      return;
    }

  if (self->info && g_variant_equal (self->info, info))
    {
      g_debug ("%s updated without changes", self->name);
      g_object_unref (self);
      return;
    }

  if (self->info)
    g_variant_unref (self->info);
  self->info = g_variant_ref (info);

  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;
          StorageLogicalVolume *volume;

          g_variant_lookup (lv_info, "name", "&s", &name);

          update_operations (name, lv_info, &needs_polling);

          if (lv_is_pvmove_volume (name))
            needs_polling = TRUE;

          if (!lv_is_visible (name))
            continue;

          volume = g_hash_table_lookup (self->logical_volumes, name);
          if (volume == NULL)
            {
              volume = storage_logical_volume_new (self, name);
              storage_logical_volume_update (volume, self, lv_info, &needs_polling);

              g_hash_table_insert (self->logical_volumes, g_strdup (name), g_object_ref (volume));
            }
          else
            storage_logical_volume_update (volume, self, 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, self->logical_volumes);
  while (g_hash_table_iter_next (&volume_iter, &key, &value))
    {
      const gchar *name = key;
      StorageLogicalVolume *volume = value;

      if (!g_hash_table_contains (new_lvs, name))
        {
          /* Volume unpublishes itself */
          g_object_run_dispose (G_OBJECT (volume));
          g_hash_table_iter_remove (&volume_iter);
        }
    }

  lvm_volume_group_set_needs_polling (LVM_VOLUME_GROUP (self), needs_polling);

  /* Update physical volumes. */

  g_hash_table_remove_all (self->physical_volumes);

  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 (self->physical_volumes, g_strdup (name), pv_info);
          else
            g_variant_unref (pv_info);
        }
    }

  /* Make sure above is published before updating blocks to point at volume group */
  update_all_blocks (self);

  if (data->done)
    data->done (self, data->done_user_data);

  g_hash_table_destroy (new_lvs);
  g_object_unref (self);
  g_free (data);
}