Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #5
0
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);
}