Beispiel #1
0
static gboolean
handle_mount (CockpitStorageBlock *object,
              GDBusMethodInvocation *invocation)
{
  StorageBlock *block = STORAGE_BLOCK(object);
  GError *error = NULL;

  if (!auth_check_sender_role (invocation, COCKPIT_ROLE_STORAGE_ADMIN))
    return TRUE;

  UDisksObject *udisks_object =
    (UDisksObject *) g_dbus_interface_get_object(G_DBUS_INTERFACE (block->udisks_block));
  if (udisks_object == NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR,
                                             COCKPIT_ERROR_FAILED,
                                             "No object!?");
      g_error_free (error);
      return TRUE;
    }

  UDisksFilesystem *fsys = udisks_object_peek_filesystem (udisks_object);
  if (fsys == NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR,
                                             COCKPIT_ERROR_FAILED,
                                             "Block device is not a filesystem");
      g_error_free (error);
      return TRUE;
    }

  if (!udisks_filesystem_call_mount_sync (fsys,
                                          g_variant_new ("a{sv}", NULL),
                                          NULL,
                                          NULL,
                                          &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 TRUE;
    }

  cockpit_storage_block_complete_mount (object, invocation);
  return TRUE;
}
Beispiel #2
0
int
main (int argc, char *argv[])
{
  gint ret;
  dev_t block_device;
  UDisksClient *client;
  GError *error;
  struct stat statbuf;
  UDisksObject *object;
  UDisksFilesystem *filesystem;
  GVariantBuilder builder;

  ret = 1;
  client = NULL;
  object = NULL;

  g_type_init ();

  if (argc < 2 || strlen (argv[1]) == 0)
    {
      g_printerr ("%s: this program is only supposed to be invoked by umount(8).\n", argv[0]);
      goto out;
    }

  if (stat (argv[1], &statbuf) < 0)
    {
      g_printerr ("%s: error calling stat on %s: %m\n", argv[0], argv[1]);
      goto out;
    }

  if (S_ISBLK (statbuf.st_mode))
    block_device = statbuf.st_rdev;
  else
    block_device = statbuf.st_dev;

  error = NULL;
  client = udisks_client_new_sync (NULL, /* GCancellable */
                                   &error);
  if (client == NULL)
    {
      g_printerr ("Error connecting to the udisks daemon: %s\n", error->message);
      g_error_free (error);
      goto out;
    }

  object = lookup_object_for_block (client, block_device);
  if (object == NULL)
    {
      g_printerr ("Error finding object for block device %d:%d\n", major (block_device), minor (block_device));
      goto out;
    }

  filesystem = udisks_object_peek_filesystem (object);
  if (filesystem == NULL)
    {
      g_printerr ("Block device %d:%d is not a mountable filesystem.\n", major (block_device), minor (block_device));
      goto out;
    }

  error = NULL;
  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
  if (!udisks_filesystem_call_unmount_sync (filesystem,
                                            g_variant_builder_end (&builder), /* options */
                                            NULL, /* GCancellable */
                                            &error))
    {
      g_printerr ("Error unmounting block device %d:%d: %s\n", major (block_device), minor (block_device), error->message);
      g_error_free (error);
      goto out;
    }

  ret = 0;

 out:
  if (object != NULL)
    g_object_unref (object);
  if (client != NULL)
    g_object_unref (client);
  return ret;
}
Beispiel #3
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, "/");
}
Beispiel #4
0
/**
 * udisks_linux_drive_object_is_not_in_use:
 * @object: A #UDisksLinuxDriveObject.
 * @cancellable: (allow-none): A #GCancellable or %NULL.
 * @error: A #GError or %NULL.
 *
 * Checks if the drive represented by @object is in use and sets
 * @error if so.
 *
 * Returns: %TRUE if @object is not is use, %FALSE if @error is set.
 */
gboolean
udisks_linux_drive_object_is_not_in_use (UDisksLinuxDriveObject   *object,
                                         GCancellable             *cancellable,
                                         GError                  **error)
{
  GDBusObjectManagerServer *object_manager;
  const gchar *drive_object_path;
  gboolean ret = TRUE;
  GList *objects = NULL;
  GList *l;

  g_return_val_if_fail (UDISKS_IS_LINUX_DRIVE_OBJECT (object), FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  drive_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));

  object_manager = udisks_daemon_get_object_manager (object->daemon);
  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));

  /* Visit all block devices related to the drive... */
  for (l = objects; l != NULL; l = l->next)
    {
      GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data);
      UDisksBlock *block;
      UDisksFilesystem *filesystem;

      if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object))
        continue;

      block = udisks_object_peek_block (UDISKS_OBJECT (iter_object));
      filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (iter_object));

      if (g_strcmp0 (udisks_block_get_drive (block), drive_object_path) != 0)
        continue;

      /* bail if block device is mounted */
      if (filesystem != NULL)
        {
          if (g_strv_length ((gchar **) udisks_filesystem_get_mount_points (filesystem)) > 0)
            {
              g_set_error (error,
                           UDISKS_ERROR,
                           UDISKS_ERROR_DEVICE_BUSY,
                           "Device %s is mounted",
                           udisks_block_get_preferred_device (block));
              ret = FALSE;
              goto out;
            }
        }

      /* bail if block device is unlocked (LUKS) */
      if (is_block_unlocked (objects, g_dbus_object_get_object_path (G_DBUS_OBJECT (iter_object))))
        {
          g_set_error (error,
                       UDISKS_ERROR,
                       UDISKS_ERROR_DEVICE_BUSY,
                       "Encrypted device %s is unlocked",
                       udisks_block_get_preferred_device (block));
          ret = FALSE;
          goto out;
        }
    }

 out:
  g_list_free_full (objects, g_object_unref);
  return ret;
}