Exemplo n.º 1
0
static gboolean
logical_volume_is_unused_walker (GDBusObjectManager *objman,
                                 LvmLogicalVolume *logical_volume,
                                 gpointer user_data,
                                 GError **error)
{
  StorageProvider *provider = user_data;
  UDisksBlock *block = lvm_util_peek_block_for_logical_volume (storage_provider_get_lvm_object_manager (provider),
                                                               storage_provider_get_udisks_client (provider),
                                                               logical_volume);
  if (block)
    return block_is_unused (storage_provider_get_udisks_client (provider), block, error);
  else
    return TRUE;
}
Exemplo n.º 2
0
static gboolean
cleanup_logical_volume_walker (GDBusObjectManager *objman,
                               LvmLogicalVolume *logical_volume,
                               gpointer user_data,
                               GError **error)
{
  StorageProvider *provider = user_data;
  UDisksBlock *block = lvm_util_peek_block_for_logical_volume (storage_provider_get_lvm_object_manager (provider),
                                                               storage_provider_get_udisks_client (provider),
                                                               logical_volume);
  if (block)
    {
      /* The logical volume is active, let's clean it up by walking
         the tree of block devices hanging off of it.
       */
      return cleanup_block (provider, block, error);
    }
  else
    {
      /* The logical volume is inactive, let's clean it up by removing
         the remembered configs from its children.
      */
      LvmObject *object = LVM_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (logical_volume)));
      GList *remembered_configs = storage_provider_get_and_forget_remembered_configs
        (provider, g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
      for (GList *l = remembered_configs; l; l = l->next)
        {
          GVariant *config = l->data;
          storage_remove_config (provider, NULL, config);
        }
      g_list_free_full (remembered_configs, (GDestroyNotify)g_variant_unref);
      return TRUE;
    }
}
Exemplo n.º 3
0
static gboolean
handle_delete (CockpitStorageMDRaid *object,
               GDBusMethodInvocation *invocation)
{
  StorageMDRaid *mdraid = STORAGE_MDRAID(object);
  StorageProvider *provider = storage_object_get_provider (mdraid->object);
  UDisksClient *udisks_client = storage_provider_get_udisks_client (provider);
  gs_unref_object UDisksBlock *block = NULL;
  GList *members = NULL;
  GError *error = NULL;

  /* Delete is Stop followed by wiping of all member devices.
   */

  block = udisks_client_get_block_for_mdraid (udisks_client, mdraid->udisks_mdraid);
  if (block)
    {
      if (!storage_cleanup_block (provider, block, &error))
        goto out;
    }

  GVariantBuilder options;
  g_variant_builder_init (&options, G_VARIANT_TYPE("a{sv}"));

  if (!udisks_mdraid_call_stop_sync (mdraid->udisks_mdraid,
                                     g_variant_builder_end (&options),
                                     NULL,
                                     &error))
    goto out;

  members = udisks_client_get_members_for_mdraid (udisks_client,
                                                  mdraid->udisks_mdraid);
  for (GList *m = members; m; m = m->next)
    {
      UDisksBlock *block = m->data;
      GVariantBuilder options;
      g_variant_builder_init (&options, G_VARIANT_TYPE("a{sv}"));
      udisks_block_call_format_sync (block,
                                     "empty",
                                     g_variant_builder_end (&options),
                                     NULL,
                                     error ? NULL : &error);
    }

out:
  if (error)
    {
      g_dbus_error_strip_remote_error (error);
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR,
                                             COCKPIT_ERROR_FAILED,
                                             "%s", error->message);
    }
  else
    cockpit_storage_mdraid_complete_stop (object, invocation);

  g_list_free_full (members, g_object_unref);
  g_clear_error (&error);
  return TRUE;
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
void
storage_mdraid_update (StorageMDRaid *mdraid)
{
    UDisksMDRaid *udisks_mdraid = mdraid->udisks_mdraid;
    CockpitStorageMDRaid *iface = COCKPIT_STORAGE_MDRAID (mdraid);
    StorageProvider *provider = storage_object_get_provider (mdraid->object);
    UDisksClient *udisks_client = storage_provider_get_udisks_client (provider);

    cockpit_storage_mdraid_set_uuid (iface, udisks_mdraid_get_uuid (udisks_mdraid));
    cockpit_storage_mdraid_set_name (iface, udisks_mdraid_get_name (udisks_mdraid));
    cockpit_storage_mdraid_set_level (iface, udisks_mdraid_get_level (udisks_mdraid));
    cockpit_storage_mdraid_set_num_devices (iface, udisks_mdraid_get_num_devices (udisks_mdraid));
    cockpit_storage_mdraid_set_size (iface, udisks_mdraid_get_size (udisks_mdraid));
    cockpit_storage_mdraid_set_sync_action (iface, udisks_mdraid_get_sync_action (udisks_mdraid));
    cockpit_storage_mdraid_set_sync_completed (iface, udisks_mdraid_get_sync_completed (udisks_mdraid));
    cockpit_storage_mdraid_set_sync_rate (iface, udisks_mdraid_get_sync_rate (udisks_mdraid));
    cockpit_storage_mdraid_set_sync_remaining_time (iface, udisks_mdraid_get_sync_remaining_time (udisks_mdraid));
    cockpit_storage_mdraid_set_degraded (iface, udisks_mdraid_get_degraded (udisks_mdraid));
    {
        gs_free gchar *loc = g_locale_to_utf8 (udisks_mdraid_get_bitmap_location (udisks_mdraid),
                                               -1, NULL, NULL, NULL);
        cockpit_storage_mdraid_set_bitmap_location (iface, loc);
    }
    cockpit_storage_mdraid_set_chunk_size (iface, udisks_mdraid_get_chunk_size (udisks_mdraid));

    GVariantBuilder devices;
    g_variant_builder_init (&devices, G_VARIANT_TYPE("a(oiast)"));

    GVariantIter iter;
    gint disk_slot;
    const gchar *disk_block_objpath;
    gs_unref_variant GVariant *disk_states = NULL;
    guint64 disk_num_errors;
    g_variant_iter_init (&iter, udisks_mdraid_get_active_devices (udisks_mdraid));
    while (g_variant_iter_next (&iter, "(&oi@asta{sv})",
                                &disk_block_objpath,
                                &disk_slot,
                                &disk_states,
                                &disk_num_errors,
                                NULL))
    {
        UDisksObject *udisks_object;
        UDisksBlock *udisks_block;
        StorageObject *object;

        if ((udisks_object = udisks_client_peek_object (udisks_client, disk_block_objpath))
                && (udisks_block = udisks_object_peek_block (udisks_object))
                && (object = storage_provider_lookup_for_udisks_block (provider, udisks_block)))
        {
            g_variant_builder_add (&devices, "(oi@ast)",
                                   g_dbus_object_get_object_path (G_DBUS_OBJECT(object)),
                                   disk_slot,
                                   disk_states,
                                   disk_num_errors);
        }
    }
    cockpit_storage_mdraid_set_active_devices (iface, g_variant_builder_end (&devices));
}
Exemplo n.º 6
0
gboolean
storage_cleanup_block (StorageProvider *provider,
                       UDisksBlock *block,
                       GError **error)
{
  return (block_is_unused (storage_provider_get_udisks_client (provider), block, error)
          && cleanup_block (provider, block, error)
          && reload_systemd (error));
}
Exemplo n.º 7
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);
        }
    }
}
Exemplo n.º 8
0
static gboolean
cleanup_block (StorageProvider *provider,
               UDisksBlock *block,
               GError **error)
{
  gboolean ret = walk_block (storage_provider_get_udisks_client (provider),
                             block, cleanup_block_walker, provider, error);
  storage_provider_save_remembered_configs (provider);
  return ret;
}
Exemplo n.º 9
0
static UDisksBlock *
create_partition (StorageBlock *block,
                  guint64 offset,
                  guint64 size,
                  const gchar *type,
                  GError **error)
{
  UDisksObject *udisks_object =
    (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (block->udisks_block));
  if (udisks_object == NULL)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                   "No object!?");
      return NULL;
    }

  UDisksPartitionTable *table = udisks_object_peek_partition_table (udisks_object);
  if (table == NULL)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                   "Block device has no partition table");
      return NULL;
    }

  gs_free gchar *part_object_path = NULL;

  if (!udisks_partition_table_call_create_partition_sync (table,
                                                          offset,
                                                          size,
                                                          type,
                                                          "",
                                                          g_variant_new ("a{sv}", NULL),
                                                          &part_object_path,
                                                          NULL,
                                                          error))
    return NULL;

  StorageProvider *provider = storage_object_get_provider (block->object);
  UDisksClient *client = storage_provider_get_udisks_client (provider);
  udisks_client_settle (client);

  gs_unref_object UDisksObject *partition_object =
      udisks_client_get_object (client, part_object_path);
  UDisksBlock *partition_block = udisks_object_peek_block (partition_object);
  if (partition_block == NULL)
    {
      g_set_error (error, COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                   "Partition has no associated block device");
      return NULL;
    }

  return partition_block;
}
Exemplo n.º 10
0
void
storage_remember_block_configs (StorageProvider *provider,
                                UDisksBlock *block)
{
  GVariant *config = udisks_block_get_configuration (block);
  if (g_variant_n_children (config) > 0)
    {
      UDisksClient *client = storage_provider_get_udisks_client (provider);
      GDBusObjectManager *objman = storage_provider_get_lvm_object_manager (provider);
      GDBusObject *object = g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
      struct RememberData data;
      data.provider = provider;
      data.child_path = g_dbus_object_get_object_path (object);
      data.config = config;
      walk_block_parents (client, objman, block, remember_configs, &data, NULL);
    }
}
Exemplo n.º 11
0
void
storage_block_update (StorageBlock *block)
{
  CockpitStorageBlock *iface = COCKPIT_STORAGE_BLOCK (block);
  StorageProvider *provider;
  UDisksClient *udisks_client;
  UDisksObject *udisks_object;
  UDisksBlock *udisks_block;
  UDisksPartition *udisks_partition = NULL;
  UDisksPartitionTable *udisks_partition_table = NULL;
  UDisksFilesystem *udisks_filesystem = NULL;
  UDisksPhysicalVolume *udisks_physical_volume = NULL;

  provider = storage_object_get_provider (block->object);
  udisks_client = storage_provider_get_udisks_client (provider);
  udisks_block = block->udisks_block;
  udisks_object = (UDisksObject *)g_dbus_interface_get_object (G_DBUS_INTERFACE (udisks_block));
  if (udisks_object != NULL)
    {
      udisks_partition = udisks_object_peek_partition (udisks_object);
      udisks_partition_table = udisks_object_peek_partition_table (udisks_object);
      udisks_filesystem = udisks_object_peek_filesystem (udisks_object);
      udisks_physical_volume = udisks_object_peek_physical_volume (udisks_object);
    }

  {
    gs_free gchar *d =
      g_filename_display_name (udisks_block_get_preferred_device (udisks_block));
    cockpit_storage_block_set_device (iface, d);
  }

  cockpit_storage_block_set_size       (iface, udisks_block_get_size (udisks_block));
  cockpit_storage_block_set_id_usage   (iface, udisks_block_get_id_usage   (udisks_block));
  cockpit_storage_block_set_id_type    (iface, udisks_block_get_id_type    (udisks_block));
  cockpit_storage_block_set_id_version (iface, udisks_block_get_id_version (udisks_block));
  cockpit_storage_block_set_id_label   (iface, udisks_block_get_id_label   (udisks_block));
  cockpit_storage_block_set_id_uuid    (iface, udisks_block_get_id_uuid    (udisks_block));

  if (udisks_partition == NULL)
    {
      cockpit_storage_block_set_partition_number (iface, 0);
      cockpit_storage_block_set_partition_table (iface, "/");
    }
  else
    {
      UDisksPartitionTable *table_for_partition;
      const gchar *objpath = "/";
      GDBusObject *o;
      UDisksBlock *b;
      StorageObject *so;

      table_for_partition = udisks_client_get_partition_table (udisks_client, udisks_partition);
      if (table_for_partition != NULL)
        {
          o = g_dbus_interface_get_object (G_DBUS_INTERFACE (table_for_partition));
          if (o != NULL)
            {
              b = udisks_object_peek_block (UDISKS_OBJECT (o));
              if (b != NULL)
                {
                  so = storage_provider_lookup_for_udisks_block (provider, b);
                  if (so != NULL)
                    {
                      objpath = g_dbus_object_get_object_path (G_DBUS_OBJECT (so));
                    }
                }
            }
        }
      cockpit_storage_block_set_partition_table (iface, objpath);
      cockpit_storage_block_set_partition_number (iface, udisks_partition_get_number (udisks_partition));
    }

  GVariantBuilder partitions;
  g_variant_builder_init (&partitions, G_VARIANT_TYPE ("a(otts)"));

  if (udisks_partition_table != NULL)
    {
      GList *ps, *l;
      ps = udisks_client_get_partitions (udisks_client, udisks_partition_table);
      for (l = ps; l != NULL; l = l->next)
        {
          UDisksPartition *p = UDISKS_PARTITION (l->data);
          GDBusObject *o;
          UDisksBlock *b;
          StorageObject *so;

          o = g_dbus_interface_get_object (G_DBUS_INTERFACE (p));
          if (o != NULL)
            {
              b = udisks_object_peek_block (UDISKS_OBJECT (o));
              if (b != NULL)
                {
                  so = storage_provider_lookup_for_udisks_block (provider, b);
                  if (so != NULL)
                    {
                      const gchar *type = "p";
                      if (udisks_partition_get_is_container (p))
                        type = "x";
                      else if (udisks_partition_get_is_contained (p))
                        type = "l";
                      g_variant_builder_add (&partitions, "(otts)",
                                             g_dbus_object_get_object_path (G_DBUS_OBJECT (so)),
                                             udisks_partition_get_offset (p),
                                             udisks_partition_get_size (p),
                                             type);
                    }
                }
            }
        }
      g_list_free_full (ps, g_object_unref);
      const gchar *type = udisks_partition_table_get_type_ (udisks_partition_table);
      if (type == NULL || type[0] == '\0')
        type = "unknown";
      cockpit_storage_block_set_partition_table_type (iface, type);
    }
  else
    cockpit_storage_block_set_partition_table_type (iface, "");

  cockpit_storage_block_set_partitions (iface, g_variant_builder_end (&partitions));

  cockpit_storage_block_set_drive
    (iface, storage_provider_translate_path (provider, udisks_block_get_drive (udisks_block)));
  cockpit_storage_block_set_crypto_backing_device
    (iface, storage_provider_translate_path (provider, udisks_block_get_crypto_backing_device (udisks_block)));
  cockpit_storage_block_set_mdraid
    (iface, storage_provider_translate_path (provider, udisks_block_get_mdraid (udisks_block)));
  cockpit_storage_block_set_mdraid_member
    (iface, storage_provider_translate_path (provider, udisks_block_get_mdraid_member (udisks_block)));

  if (udisks_filesystem)
    {
      const gchar *const *p = udisks_filesystem_get_mount_points (udisks_filesystem);
      gchar *u[g_strv_length ((gchar **)p) + 1];
      int i;
      for (i = 0; p[i]; i++)
        u[i] = g_filename_display_name (p[i]);
      u[i] = NULL;
      cockpit_storage_block_set_mounted_at (iface, (const gchar *const *)u);
      for (i = 0; u[i]; i++)
        g_free (u[i]);
    }

  GVariantIter iter;
  g_variant_iter_init (&iter, udisks_block_get_configuration (udisks_block));
  const gchar *type;
  GVariant *details;
  gboolean got_fstab = FALSE, got_crypttab = FALSE;
  while (g_variant_iter_next (&iter, "(&s*)", &type, &details))
    {
      if (strcmp (type, "fstab") == 0 && !got_fstab)
        {
          got_fstab = TRUE;
          const gchar *dir = variant_lookup (details, "dir");
          if (dir)
            {
              gs_free gchar *dir_display = g_filename_display_name (dir);
              cockpit_storage_block_set_mount_point (iface, dir_display);
            }
          const gchar *opts = variant_lookup (details, "opts");
          if (opts)
            {
              gs_free gchar *opts_locale = g_locale_to_utf8 (opts, -1, NULL, NULL, NULL);
              if (opts_locale)
                cockpit_storage_block_set_mount_options (iface, opts_locale);
              else
                g_warning ("Can't convert fstab options into UTF8");
            }
        }
      else if (strcmp (type, "crypttab") == 0 && !got_crypttab)
        {
          got_crypttab = TRUE;
          const gchar *opts = variant_lookup (details, "options");
          if (opts)
            {
              gs_free gchar *opts_locale = g_locale_to_utf8 (opts, -1, NULL, NULL, NULL);
              if (opts_locale)
                cockpit_storage_block_set_crypto_options (iface, opts_locale);
              else
                g_warning ("Can't convert crypttab options into UTF8");
            }
        }
      g_variant_unref (details);
    }

  cockpit_storage_block_set_logical_volume (iface,
     storage_provider_translate_path (provider,
                                      udisks_block_get_logical_volume (udisks_block)));

  if (udisks_physical_volume)
    {
      cockpit_storage_block_set_pv_group (iface,
         storage_provider_translate_path (provider,
                                          udisks_physical_volume_get_volume_group (udisks_physical_volume)));
      cockpit_storage_block_set_pv_size (iface, udisks_physical_volume_get_size (udisks_physical_volume));
      cockpit_storage_block_set_pv_free_size (iface, udisks_physical_volume_get_free_size (udisks_physical_volume));
    }
  else
    cockpit_storage_block_set_pv_group (iface, "/");
}