Пример #1
0
/**
 * udisks_daemon_util_on_user_seat:
 * @daemon: A #UDisksDaemon.
 * @object: The #GDBusObject that the call is on or %NULL.
 * @user: The user to check for.
 *
 * Checks whether the device represented by @object (if any) is plugged into
 * a seat where the caller represented by @user is logged in and active.
 *
 * This works if @object is a drive or a block object.
 *
 * Returns: %TRUE if @object is on the same seat as one of @user's
 *  active sessions, %FALSE otherwise.
 */
gboolean
udisks_daemon_util_on_user_seat (UDisksDaemon          *daemon,
                                 UDisksObject          *object,
                                 uid_t                  user)
{
#if !defined(HAVE_LIBSYSTEMD_LOGIN)
  /* if we don't have systemd, assume it's always the same seat */
  return TRUE;
#else
  gboolean ret = FALSE;
  char *session = NULL;
  char *seat = NULL;
  const gchar *drive_seat;
  UDisksObject *drive_object = NULL;
  UDisksDrive *drive = NULL;

  /* if we don't have logind, assume it's always the same seat */
  if (!LOGIND_AVAILABLE())
    return TRUE;

  if (UDISKS_IS_LINUX_BLOCK_OBJECT (object))
    {
      UDisksLinuxBlockObject *linux_block_object;
      UDisksBlock *block;
      linux_block_object = UDISKS_LINUX_BLOCK_OBJECT (object);
      block = udisks_object_get_block (UDISKS_OBJECT (linux_block_object));
      if (block != NULL)
        {
          drive_object = udisks_daemon_find_object (daemon, udisks_block_get_drive (block));
          g_object_unref (block);
        }
    }
  else if (UDISKS_IS_LINUX_DRIVE_OBJECT (object))
    {
      drive_object = g_object_ref (object);
    }

  if (drive_object == NULL)
    goto out;

  drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object));
  if (drive == NULL)
    goto out;

  drive_seat = udisks_drive_get_seat (drive);

  if (drive_seat != NULL && sd_uid_is_on_seat (user, TRUE, drive_seat) > 0)
    {
      ret = TRUE;
      goto out;
    }

 out:
  free (seat);
  free (session);
  g_clear_object (&drive_object);
  g_clear_object (&drive);
  return ret;
#endif /* HAVE_LIBSYSTEMD_LOGIN */
}
Пример #2
0
static UDisksBlock *
peek_block_for_logical_volume (UDisksLogicalVolume *volume,
                               UDisksDaemon        *daemon)
{
  UDisksBlock *ret = NULL;
  GDBusObject *object;
  GList *l, *objects = NULL;
  UDisksBlockLVM2 *block_lvm2;

  object = g_dbus_interface_get_object (G_DBUS_INTERFACE (volume));
  if (object == NULL)
    goto out;

  objects = udisks_daemon_get_objects (daemon);
  for (l = objects; l != NULL; l = l->next)
    {
      block_lvm2 = udisks_object_peek_block_lvm2 (UDISKS_OBJECT(l->data));
      if (block_lvm2 &&
          g_strcmp0 (udisks_block_lvm2_get_logical_volume (block_lvm2),
                     g_dbus_object_get_object_path (object)) == 0)
        {
          ret = udisks_object_peek_block (UDISKS_OBJECT(l->data));
          goto out;
        }
    }

 out:
  g_list_free_full (objects, g_object_unref);
  return ret;
}
Пример #3
0
static gboolean
handle_delete (UDisksLogicalVolume   *_volume,
               GDBusMethodInvocation *invocation,
               GVariant              *options)
{
  GError *error = NULL;
  UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume);
  UDisksLinuxLogicalVolumeObject *object = NULL;
  UDisksDaemon *daemon = NULL;
  uid_t caller_uid;
  gboolean teardown_flag = FALSE;
  UDisksLinuxVolumeGroupObject *group_object;
  LVJobData data;

  g_variant_lookup (options, "tear-down", "b", &teardown_flag);

  if (!common_setup (volume, invocation, options,
                     N_("Authentication is required to delete a logical volume"),
                     &object, &daemon, &caller_uid, NULL))
    goto out;

  if (teardown_flag &&
      !teardown_logical_volume (_volume,
                                daemon,
                                invocation,
                                options,
                                &error))
    {
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  group_object = udisks_linux_logical_volume_object_get_volume_group (object);
  data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
  data.lv_name = udisks_linux_logical_volume_object_get_name (object);

  if (!udisks_daemon_launch_threaded_job_sync (daemon,
                                               UDISKS_OBJECT (object),
                                               "lvm-lvol-delete",
                                               caller_uid,
                                               lvremove_job_func,
                                               &data,
                                               NULL, /* user_data_free_func */
                                               NULL, /* GCancellable */
                                               &error))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             UDISKS_ERROR,
                                             UDISKS_ERROR_FAILED,
                                             "Error deleting logical volume: %s",
                                             error->message);
      goto out;
    }

  udisks_logical_volume_complete_delete (_volume, invocation);

 out:
  g_clear_object (&object);
  return TRUE;
}
Пример #4
0
UDisksBlock *
udisks_client_get_block_for_dev (UDisksClient *client,
                                 dev_t         block_device_number)
{
  UDisksBlock *ret = NULL;
  GList *l, *object_proxies = NULL;

  g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);

  object_proxies = g_dbus_object_manager_get_objects (client->object_manager);
  for (l = object_proxies; l != NULL; l = l->next)
    {
      UDisksObject *object = UDISKS_OBJECT (l->data);
      UDisksBlock *block;

      block = udisks_object_get_block (object);
      if (block == NULL)
        continue;

      if (udisks_block_get_device_number (block) == block_device_number)
        {
          ret = block;
          goto out;
        }
      g_object_unref (block);
    }

 out:
  g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
  g_list_free (object_proxies);
  return ret;
}
Пример #5
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;
}
Пример #6
0
static gboolean
handle_cache_detach_or_split (UDisksLogicalVolume  *volume_,
                              GDBusMethodInvocation  *invocation,
                              GVariant               *options,
                              gboolean               destroy)
{
#ifndef HAVE_LVMCACHE

  g_dbus_method_invocation_return_error (invocation,
                                         UDISKS_ERROR,
                                         UDISKS_ERROR_FAILED,
                                         N_("LVMCache not enabled at compile time."));
  return TRUE;

#else

  GError *error = NULL;
  UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (volume_);
  UDisksLinuxLogicalVolumeObject *object = NULL;
  UDisksDaemon *daemon;
  uid_t caller_uid;
  UDisksLinuxVolumeGroupObject *group_object;
  LVJobData data;

  if (!common_setup (volume, invocation, options,
                     N_("Authentication is required to split cache pool LV off of a cache LV"),
                     &object, &daemon, &caller_uid, NULL))
    goto out;

  group_object = udisks_linux_logical_volume_object_get_volume_group (object);
  data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
  data.lv_name = udisks_linux_logical_volume_object_get_name (object);
  data.destroy = destroy;

  if (!udisks_daemon_launch_threaded_job_sync (daemon,
                                               UDISKS_OBJECT (object),
                                               "lvm-lv-split-cache",
                                               caller_uid,
                                               lvcache_detach_job_func,
                                               &data,
                                               NULL, /* user_data_free_func */
                                               NULL, /* GCancellable */
                                               &error))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             UDISKS_ERROR,
                                             UDISKS_ERROR_FAILED,
                                             N_("Error converting volume: %s"),
                                             error->message);
      goto out;
    }

  udisks_logical_volume_complete_cache_split (volume_, invocation);
out:
  g_clear_object (&object);

  return TRUE;

#endif /* HAVE_LVMCACHE */
}
Пример #7
0
static void
on_udisks_object_added (GDBusObjectManager *manager,
                        GDBusObject *object,
                        gpointer user_data)
{
  FormatData *data = user_data;

  if (data->invocation == NULL)
    return;

  UDisksObject *udisks_object = UDISKS_OBJECT (object);
  UDisksJob *udisks_job = udisks_object_peek_job (udisks_object);
  if (udisks_job)
    {
      const gchar *us = g_dbus_proxy_get_object_path (G_DBUS_PROXY (data->block));
      const gchar *const *them = udisks_job_get_objects (udisks_job);
      for (int i = 0; them[i]; i++)
        {
          if (strcmp (them[i], us) == 0)
            {
              g_dbus_method_invocation_return_value (data->invocation, g_variant_new ("()"));
              g_clear_object (&data->invocation);
              break;
            }
        }
    }
}
Пример #8
0
static UDisksObject *
wait_for_logical_volume_block_object (UDisksDaemon *daemon,
                                      gpointer      user_data)
{
  UDisksLinuxLogicalVolumeObject *volume_object = user_data;
  const gchar *volume_objpath;
  GList *objects, *l;
  UDisksObject *ret = NULL;

  volume_objpath = g_dbus_object_get_object_path (G_DBUS_OBJECT (volume_object));

  objects = udisks_daemon_get_objects (daemon);
  for (l = objects; l != NULL; l = l->next)
    {
      UDisksObject *object = UDISKS_OBJECT (l->data);
      UDisksBlockLVM2 *block;

      block = udisks_object_peek_block_lvm2 (object);
      if (block == NULL)
        continue;

      if (g_strcmp0 (udisks_block_lvm2_get_logical_volume (block), volume_objpath) == 0)
        {
          ret = g_object_ref (object);
          goto out;
        }
    }

 out:
  g_list_free_full (objects, g_object_unref);
  return ret;
}
Пример #9
0
static gboolean
handle_rename (UDisksLogicalVolume   *_volume,
               GDBusMethodInvocation *invocation,
               const gchar           *new_name,
               GVariant              *options)
{
  GError *error = NULL;
  UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume);
  UDisksLinuxLogicalVolumeObject *object = NULL;
  UDisksDaemon *daemon;
  uid_t caller_uid;
  UDisksLinuxVolumeGroupObject *group_object;
  const gchar *lv_objpath;
  LVJobData data;

  if (!common_setup (volume, invocation, options,
                     N_("Authentication is required to rename a logical volume"),
                     &object, &daemon, &caller_uid, NULL))
    goto out;

  group_object = udisks_linux_logical_volume_object_get_volume_group (object);
  data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
  data.lv_name = udisks_linux_logical_volume_object_get_name (object);
  data.new_lv_name = new_name;

  if (!udisks_daemon_launch_threaded_job_sync (daemon,
                                               UDISKS_OBJECT (object),
                                               "lvm-lvol-rename",
                                               caller_uid,
                                               lvrename_job_func,
                                               &data,
                                               NULL, /* user_data_free_func */
                                               NULL, /* GCancellable */
                                               &error))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             UDISKS_ERROR,
                                             UDISKS_ERROR_FAILED,
                                             "Error renaming logical volume: %s",
                                             error->message);
      goto out;
    }

  lv_objpath = wait_for_logical_volume_path (group_object, new_name, &error);
  if (lv_objpath == NULL)
    {
      g_prefix_error (&error,
                      "Error waiting for logical volume object for %s",
                      new_name);
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  udisks_logical_volume_complete_rename (_volume, invocation, lv_objpath);

 out:
  g_clear_object (&object);
  return TRUE;
}
Пример #10
0
static UDisksObject *
wait_for_logical_volume_object (UDisksDaemon *daemon,
                                gpointer      user_data)
{
  struct WaitData *data = user_data;
  return UDISKS_OBJECT (udisks_linux_volume_group_object_find_logical_volume_object (data->group_object,
                                                                                     data->name));
}
Пример #11
0
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);
}
Пример #12
0
static void
on_examine_action_clicked (NotifyNotification  *notification,
                           const gchar         *action,
                           gpointer             user_data)
{
  GduSdMonitor *monitor = GDU_SD_MONITOR (user_data);
  const gchar *device_file = NULL;
  gchar *command_line = NULL;
  GAppInfo *app_info = NULL;
  GError *error = NULL;

  if (g_strcmp0 (action, "examine-smart") == 0)
    {
      if (monitor->ata_smart_problems != NULL)
        {
          UDisksObject *object = UDISKS_OBJECT (monitor->ata_smart_problems->data);
          if (object != NULL)
            {
              UDisksDrive *drive = udisks_object_peek_drive (object);
              if (drive != NULL)
                {
                  UDisksBlock *block = udisks_client_get_block_for_drive (monitor->client,
                                                                          drive,
                                                                          TRUE); /* get_physical */
                  if (block != NULL)
                    {
                      device_file = udisks_block_get_device (block);
                      g_object_ref (block);
                    }
                }
            }
        }
    }
  else
    {
      g_assert_not_reached ();
    }

  if (device_file != NULL)
    command_line = g_strdup_printf ("gnome-disks --block-device %s", device_file);
  else
    command_line = g_strdup_printf ("gnome-disks");


  app_info = g_app_info_create_from_commandline (command_line,
                                                 NULL, /* application name */
                                                 G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION,
                                                 NULL);
  if (!g_app_info_launch (app_info, NULL, NULL, &error))
    {
      g_warning ("Error launching gnome-disks: %s (%s, %d)",
                 error->message, g_quark_to_string (error->domain), error->code);
      g_clear_error (&error);
    }
  g_clear_object (&app_info);
  g_free (command_line);
}
Пример #13
0
static gboolean
handle_resize (UDisksLogicalVolume   *_volume,
               GDBusMethodInvocation *invocation,
               guint64                new_size,
               GVariant              *options)
{
  GError *error = NULL;
  UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume);
  UDisksLinuxLogicalVolumeObject *object = NULL;
  UDisksDaemon *daemon;
  uid_t caller_uid;
  UDisksLinuxVolumeGroupObject *group_object;
  LVJobData data;

  if (!common_setup (volume, invocation, options,
                     N_("Authentication is required to resize a logical volume"),
                     &object, &daemon, &caller_uid, NULL))
    goto out;

  group_object = udisks_linux_logical_volume_object_get_volume_group (object);
  data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
  data.lv_name = udisks_linux_logical_volume_object_get_name (object);
  data.new_lv_size = new_size;

  data.resize_fs = FALSE;
  data.force = FALSE;
  g_variant_lookup (options, "resize_fsys", "b", &(data.resize_fs));
  g_variant_lookup (options, "force", "b", &(data.force));

  if (!udisks_daemon_launch_threaded_job_sync (daemon,
                                               UDISKS_OBJECT (object),
                                               "lvm-lvol-resize",
                                               caller_uid,
                                               lvresize_job_func,
                                               &data,
                                               NULL, /* user_data_free_func */
                                               NULL, /* GCancellable */
                                               &error))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             UDISKS_ERROR,
                                             UDISKS_ERROR_FAILED,
                                             "Error resizing logical volume: %s",
                                             error->message);
      goto out;
    }

  udisks_logical_volume_complete_resize (_volume, invocation);

 out:
  g_clear_object (&object);
  return TRUE;
}
Пример #14
0
static gboolean
cleanup_block_walker (UDisksClient *client,
                      UDisksBlock *block,
                      gboolean is_leaf,
                      gpointer user_data,
                      GError **error)
{
  StorageProvider *provider = user_data;
  UDisksObject *object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block)));
  UDisksEncrypted *enc = udisks_object_peek_encrypted (object);

  if (enc)
    {
      UDisksBlock *cleartext = udisks_client_get_cleartext_block (client, block);
      if (cleartext)
        {
          /* The crypto backing device is unlocked and the cleartext
             device has been cleaned up.  Lock the backing device so
             that we can format or wipe it later.
          */
          if (enc && !udisks_encrypted_call_lock_sync (enc,
                                                       g_variant_new ("a{sv}", NULL),
                                                       NULL,
                                                       error))
            return FALSE;
        }
      else
        {
          /* The crypto backing device is locked and the cleartext
             device has not been cleaned up (since it doesn't exist).
             Remove its remembered configs.
          */
          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, block, config);
            }
          g_list_free_full (remembered_configs, (GDestroyNotify)g_variant_unref);
        }
    }

  storage_remove_config (provider, block, udisks_block_get_configuration (block));

  return TRUE;
}
Пример #15
0
/**
 * udisks_linux_drive_object_get_block:
 * @object: A #UDisksLinuxDriveObject.
 * @get_hw: If the drive is multipath, set to %TRUE to get a path device instead of the multipath device.
 *
 * Gets a #UDisksLinuxBlockObject representing a block device associated with @object.
 *
 * Returns: A #UDisksLinuxBlockObject or %NULL. The returned object
 * must be freed with g_object_unref().
 */
UDisksLinuxBlockObject *
udisks_linux_drive_object_get_block (UDisksLinuxDriveObject   *object,
                                     gboolean                  get_hw)
{
  GDBusObjectManagerServer *object_manager;
  UDisksLinuxBlockObject *ret;
  GList *objects;
  GList *l;

  /* TODO: actually look at @get_hw */

  ret = NULL;

  object_manager = udisks_daemon_get_object_manager (object->daemon);
  objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (object_manager));
  for (l = objects; l != NULL; l = l->next)
    {
      GDBusObjectSkeleton *iter_object = G_DBUS_OBJECT_SKELETON (l->data);
      UDisksBlock *block;
      UDisksLinuxDevice *device;
      gboolean is_disk;

      if (!UDISKS_IS_LINUX_BLOCK_OBJECT (iter_object))
        continue;

      device = udisks_linux_block_object_get_device (UDISKS_LINUX_BLOCK_OBJECT (iter_object));
      is_disk = (g_strcmp0 (g_udev_device_get_devtype (device->udev_device), "disk") == 0);
      g_object_unref (device);

      if (!is_disk)
        continue;

      block = udisks_object_peek_block (UDISKS_OBJECT (iter_object));
      if (g_strcmp0 (udisks_block_get_drive (block),
                     g_dbus_object_get_object_path (G_DBUS_OBJECT (object))) == 0)
        {
          ret = g_object_ref (iter_object);
          goto out;
        }
    }

 out:
  g_list_foreach (objects, (GFunc) g_object_unref, NULL);
  g_list_free (objects);
  return ret;
}
Пример #16
0
static gboolean
common_setup (UDisksLinuxLogicalVolume           *volume,
              GDBusMethodInvocation              *invocation,
              GVariant                           *options,
              const gchar                        *auth_err_msg,
              UDisksLinuxLogicalVolumeObject    **object,
              UDisksDaemon                      **daemon,
              uid_t                              *out_uid,
              gid_t                              *out_gid)
{
  gboolean rc = FALSE;
  GError *error = NULL;

  *object = udisks_daemon_util_dup_object (volume, &error);
  if (*object == NULL)
    {
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  *daemon = udisks_linux_logical_volume_object_get_daemon (*object);

  if (!udisks_daemon_util_get_caller_uid_sync (*daemon,
                                               invocation,
                                               NULL /* GCancellable */,
                                               out_uid,
                                               out_gid,
                                               NULL,
                                               &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_clear_error (&error);
      goto out;
    }

  /* Policy check. */
  UDISKS_DAEMON_CHECK_AUTHORIZATION (*daemon,
                                     UDISKS_OBJECT (*object),
                                     lvm2_policy_action_id,
                                     options,
                                     auth_err_msg,
                                     invocation);
  rc = TRUE;
 out:
  return rc;
}
Пример #17
0
UDisksManager *
udisks_client_get_manager (UDisksClient *client)
{
  UDisksManager *ret = NULL;
  GDBusObject *obj;

  g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);

  obj = g_dbus_object_manager_get_object (client->object_manager, "/org/freedesktop/UDisks2/Manager");
  if (obj == NULL)
    goto out;

  ret = udisks_object_peek_manager (UDISKS_OBJECT (obj));
  g_object_unref (obj);

 out:
  return ret;
}
Пример #18
0
static gboolean
is_block_unlocked (GList *objects, const gchar *crypto_object_path)
{
  gboolean ret = FALSE;
  GList *l;
  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 (g_strcmp0 (udisks_block_get_crypto_backing_device (block), crypto_object_path) == 0)
            {
              ret = TRUE;
              goto out;
            }
        }
    }
 out:
  return ret;
}
Пример #19
0
static void
update_drive_with_id (UDisksLinuxProvider *provider,
                      const gchar         *id)
{
  GHashTableIter iter;
  UDisksLinuxDriveObject *drive_object;

  /* TODO: could have a GHashTable from id to UDisksLinuxDriveObject */
  g_hash_table_iter_init (&iter, provider->sysfs_path_to_drive);
  while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &drive_object))
    {
      UDisksDrive *drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object));
      if (drive != NULL)
        {
          if (g_strcmp0 (udisks_drive_get_id (drive), id) == 0)
            {
              //udisks_debug ("synthesizing change event on drive with id %s", id);
              udisks_linux_drive_object_uevent (drive_object, "change", NULL);
            }
          g_object_unref (drive);
        }
    }
}
Пример #20
0
static gboolean
handle_activate (UDisksLogicalVolume *_volume,
                 GDBusMethodInvocation *invocation,
                 GVariant *options)
{
  GError *error = NULL;
  UDisksLinuxLogicalVolume *volume = UDISKS_LINUX_LOGICAL_VOLUME (_volume);
  UDisksLinuxLogicalVolumeObject *object = NULL;
  UDisksDaemon *daemon;
  uid_t caller_uid;
  UDisksLinuxVolumeGroupObject *group_object;
  UDisksObject *block_object = NULL;
  LVJobData data;

  if (!common_setup (volume, invocation, options,
                     N_("Authentication is required to activate a logical volume"),
                     &object, &daemon, &caller_uid, NULL))
    goto out;

  group_object = udisks_linux_logical_volume_object_get_volume_group (object);
  data.vg_name = udisks_linux_volume_group_object_get_name (group_object);
  data.lv_name = udisks_linux_logical_volume_object_get_name (object);

  if (!udisks_daemon_launch_threaded_job_sync (daemon,
                                               UDISKS_OBJECT (object),
                                               "lvm-lvol-activate",
                                               caller_uid,
                                               lvactivate_job_func,
                                               &data,
                                               NULL, /* user_data_free_func */
                                               NULL, /* GCancellable */
                                               &error))

    {
      g_dbus_method_invocation_return_error (invocation,
                                             UDISKS_ERROR,
                                             UDISKS_ERROR_FAILED,
                                             "Error activating logical volume: %s",
                                             error->message);
      goto out;
    }

  block_object = udisks_daemon_wait_for_object_sync (daemon,
                                                     wait_for_logical_volume_block_object,
                                                     object,
                                                     NULL,
                                                     10, /* timeout_seconds */
                                                     &error);
  if (block_object == NULL)
    {
      g_prefix_error (&error,
                      "Error waiting for block object for %s",
                      udisks_logical_volume_get_name (_volume));
      g_dbus_method_invocation_take_error (invocation, error);
      goto out;
    }

  udisks_logical_volume_complete_activate (_volume, invocation,
                                           g_dbus_object_get_object_path (G_DBUS_OBJECT (block_object)));

 out:
  g_clear_object (&block_object);
  g_clear_object (&object);
  return TRUE;
}
Пример #21
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, "/");
}
Пример #22
0
static void
udisks_client_get_object_info_for_drive (UDisksClient     *client,
                                         UDisksDrive      *drive,
                                         UDisksPartition  *partition,
                                         UDisksObjectInfo *info)
{
  const gchar *vendor;
  const gchar *model;
  const gchar *media;
  const gchar *const *media_compat;
  gboolean media_available;
  gboolean media_removable;
  gint rotation_rate;
  guint64 size;
  gchar *size_str;
  guint n;
  GString *desc_str;
  DriveType desc_type;
  gchar *hyphenated_connection_bus;
  const gchar *connection_bus;
  UDisksBlock *block = NULL;
  gchar *s;
  const gchar *cs;
  UDisksBlock *block_for_partition = NULL;

  g_return_if_fail (UDISKS_IS_DRIVE (drive));

  size_str = NULL;

  vendor = udisks_drive_get_vendor (drive);
  model = udisks_drive_get_model (drive);
  size = udisks_drive_get_size (drive);
  media_removable = udisks_drive_get_media_removable (drive);
  media_available = udisks_drive_get_media_available (drive);
  rotation_rate = udisks_drive_get_rotation_rate (drive);
  if (size > 0)
    size_str = udisks_client_get_size_for_display (client, size, FALSE, FALSE);
  media = udisks_drive_get_media (drive);
  media_compat = udisks_drive_get_media_compatibility (drive);
  connection_bus = udisks_drive_get_connection_bus (drive);
  if (strlen (connection_bus) > 0)
    hyphenated_connection_bus = g_strdup_printf ("-%s", connection_bus);
  else
    hyphenated_connection_bus = g_strdup ("");

  /* Name is easy - that's just "$vendor $model" */
  if (strlen (vendor) == 0)
    vendor = NULL;
  if (strlen (model) == 0)
    model = NULL;
  info->name = g_strdup_printf ("%s%s%s",
                                vendor != NULL ? vendor : "",
                                vendor != NULL ? " " : "",
                                model != NULL ? model : "");

  desc_type = DRIVE_TYPE_UNSET;
  desc_str = g_string_new (NULL);
  for (n = 0; n < G_N_ELEMENTS (media_data) - 1; n++)
    {
      /* media_compat */
      if (strv_has (media_compat, media_data[n].id))
        {
          if (info->icon == NULL)
            info->icon = g_themed_icon_new_with_default_fallbacks (media_data[n].drive_icon);
          if (info->icon_symbolic == NULL)
            info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (media_data[n].drive_icon_symbolic);
          if (strstr (desc_str->str, media_data[n].media_family) == NULL)
            {
              if (desc_str->len > 0)
                g_string_append (desc_str, "/");
              g_string_append (desc_str, g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_family));
            }
          desc_type = media_data[n].media_type;
        }

      if (media_removable && media_available)
        {
          /* media */
          if (g_strcmp0 (media, media_data[n].id) == 0)
            {
              if (info->media_description == NULL)
                {
                  switch (media_data[n].media_type)
                    {
                    case DRIVE_TYPE_UNSET:
                      g_assert_not_reached ();
                      break;
                    case DRIVE_TYPE_DRIVE:
                      /* Translators: Used to describe drive without removable media. The %s is the type, e.g. 'Thumb' */
                      info->media_description = g_strdup_printf (C_("drive-with-fixed-media", "%s Drive"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
                      break;
                    case DRIVE_TYPE_DISK:
                      /* Translators: Used to describe generic media. The %s is the type, e.g. 'Zip' or 'Floppy' */
                      info->media_description = g_strdup_printf (C_("drive-with-generic-media", "%s Disk"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
                      break;
                    case DRIVE_TYPE_CARD:
                      /* Translators: Used to describe flash media. The %s is the type, e.g. 'SD' or 'CompactFlash' */
                      info->media_description = g_strdup_printf (C_("flash-media", "%s Card"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
                      break;
                    case DRIVE_TYPE_DISC:
                      /* Translators: Used to describe optical discs. The %s is the type, e.g. 'CD-R' or 'DVD-ROM' */
                      info->media_description = g_strdup_printf (C_("optical-media", "%s Disc"), g_dpgettext2 (GETTEXT_PACKAGE, "media-type", media_data[n].media_name));
                      break;
                    }
                }
              if (info->media_icon == NULL)
                info->media_icon = g_themed_icon_new_with_default_fallbacks (media_data[n].media_icon);
              if (info->media_icon_symbolic == NULL)
                info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (media_data[n].media_icon_symbolic);
            }
        }
    }

  switch (desc_type)
    {
    case DRIVE_TYPE_UNSET:
      if (media_removable)
        {
          if (size_str != NULL)
            {
              /* Translators: Used to describe a drive. The %s is the size, e.g. '20 GB' */
              info->description = g_strdup_printf (C_("drive-with-size", "%s Drive"), size_str);
            }
          else
            {
              /* Translators: Used to describe a drive we know very little about (removable media or size not known) */
              info->description = g_strdup (C_("generic-drive", "Drive"));
            }
        }
      else
        {
          if (rotation_rate == 0)
            {
              if (size_str != NULL)
                {
                  /* Translators: Used to describe a non-rotating drive (rotation rate either unknown
                   * or it's a solid-state drive). The %s is the size, e.g. '20 GB'.  */
                  info->description = g_strdup_printf (C_("disk-non-rotational", "%s Disk"), size_str);
                }
              else
                {
                  /* Translators: Used to describe a non-rotating drive (rotation rate either unknown
                   * or it's a solid-state drive). The drive is either using removable media or its
                   * size not known. */
                  info->description = g_strdup (C_("disk-non-rotational", "Disk"));
                }
            }
          else
            {
              if (size_str != NULL)
                {
                  /* Translators: Used to describe a hard-disk drive (HDD). The %s is the size, e.g. '20 GB'.  */
                  info->description = g_strdup_printf (C_("disk-hdd", "%s Hard Disk"), size_str);
                }
              else
                {
                  /* Translators: Used to describe a hard-disk drive (HDD) (removable media or size not known) */
                  info->description = g_strdup (C_("disk-hdd", "Hard Disk"));
                }
            }
        }
      break;

    case DRIVE_TYPE_CARD:
      /* Translators: Used to describe a card reader. The %s is the card type e.g. 'CompactFlash'.  */
      info->description = g_strdup_printf (C_("drive-card-reader", "%s Card Reader"), desc_str->str);
      break;

    case DRIVE_TYPE_DRIVE: /* explicit fall-through */
    case DRIVE_TYPE_DISK: /* explicit fall-through */
    case DRIVE_TYPE_DISC:
      if (!media_removable && size_str != NULL)
        {
          /* Translators: Used to describe drive. The first %s is the size e.g. '20 GB' and the
           * second %s is the drive type e.g. 'Thumb'.
           */
          info->description = g_strdup_printf (C_("drive-with-size-and-type", "%s %s Drive"), size_str, desc_str->str);
        }
      else
        {
          /* Translators: Used to describe drive. The first %s is the drive type e.g. 'Thumb'.
           */
          info->description = g_strdup_printf (C_("drive-with-type", "%s Drive"), desc_str->str);
        }
      break;
    }
  g_string_free (desc_str, TRUE);

  /* fallback for icon */
  if (info->icon == NULL)
    {
      if (media_removable)
        {
          s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus);
        }
      else
        {
          if (rotation_rate == 0)
            s = g_strdup_printf ("drive-harddisk-solidstate%s", hyphenated_connection_bus);
          else
            s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus);
        }
      info->icon = g_themed_icon_new_with_default_fallbacks (s);
      g_free (s);
    }
  /* fallback for icon_symbolic */
  if (info->icon_symbolic == NULL)
    {
      if (media_removable)
        {
          s = g_strdup_printf ("drive-removable-media%s-symbolic", hyphenated_connection_bus);
        }
      else
        {
          if (rotation_rate == 0)
            s = g_strdup_printf ("drive-harddisk-solidstate%s-symbolic", hyphenated_connection_bus);
          else
            s = g_strdup_printf ("drive-harddisk%s-symbolic", hyphenated_connection_bus);
        }
      info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (s);
      g_free (s);
    }
  /* fallback for media_icon */
  if (media_removable && media_available && info->media_icon == NULL)
    {
      if (media_removable)
        {
          s = g_strdup_printf ("drive-removable-media%s", hyphenated_connection_bus);
        }
      else
        {
          if (rotation_rate == 0)
            s = g_strdup_printf ("drive-harddisk-solidstate%s", hyphenated_connection_bus);
          else
            s = g_strdup_printf ("drive-harddisk%s", hyphenated_connection_bus);
        }
      info->media_icon = g_themed_icon_new_with_default_fallbacks (s);
      g_free (s);
    }
  /* fallback for media_icon_symbolic */
  if (media_removable && media_available && info->media_icon_symbolic == NULL)
    {
      if (media_removable)
        {
          s = g_strdup_printf ("drive-removable-media%s-symbolic", hyphenated_connection_bus);
        }
      else
        {
          if (rotation_rate == 0)
            s = g_strdup_printf ("drive-harddisk-solidstate%s-symbolic", hyphenated_connection_bus);
          else
            s = g_strdup_printf ("drive-harddisk%s-symbolic", hyphenated_connection_bus);
        }
      info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (s);
      g_free (s);
    }

  /* prepend a qualifier to the media description, based on the disc state */
  if (udisks_drive_get_optical_blank (drive))
    {
      /* Translators: String used for a blank disc. The %s is the disc type e.g. "CD-RW Disc" */
      s = g_strdup_printf (C_("optical-media", "Blank %s"), info->media_description);
      g_free (info->media_description);
      info->media_description = s;
    }
  else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 &&
           udisks_drive_get_optical_num_data_tracks (drive) > 0)
    {
      /* Translators: String used for a mixed disc. The %s is the disc type e.g. "CD-ROM Disc" */
      s = g_strdup_printf (C_("optical-media", "Mixed %s"), info->media_description);
      g_free (info->media_description);
      info->media_description = s;
    }
  else if (udisks_drive_get_optical_num_audio_tracks (drive) > 0 &&
           udisks_drive_get_optical_num_data_tracks (drive) == 0)
    {
      /* Translators: String used for an audio disc. The %s is the disc type e.g. "CD-ROM Disc" */
      s = g_strdup_printf (C_("optical-media", "Audio %s"), info->media_description);
      g_free (info->media_description);
      info->media_description = s;
    }

  /* Apply UDISKS_NAME, UDISKS_ICON_NAME, UDISKS_SYMBOLIC_ICON_NAME hints, if available */
  block = udisks_client_get_block_for_drive (client, drive, TRUE);
  if (block != NULL)
    {
      cs = udisks_block_get_hint_name (block);
      if (cs != NULL && strlen (cs) > 0)
        {
          g_free (info->description);
          g_free (info->media_description);
          info->description = g_strdup (cs);
          info->media_description = g_strdup (cs);
        }

      cs = udisks_block_get_hint_icon_name (block);
      if (cs != NULL && strlen (cs) > 0)
        {
          g_clear_object (&info->icon);
          g_clear_object (&info->media_icon);
          info->icon = g_themed_icon_new_with_default_fallbacks (cs);
          info->media_icon = g_themed_icon_new_with_default_fallbacks (cs);
        }

      cs = udisks_block_get_hint_symbolic_icon_name (block);
      if (cs != NULL && strlen (cs) > 0)
        {
          g_clear_object (&info->icon_symbolic);
          g_clear_object (&info->media_icon_symbolic);
          info->icon_symbolic = g_themed_icon_new_with_default_fallbacks (cs);
          info->media_icon_symbolic = g_themed_icon_new_with_default_fallbacks (cs);
        }
    }

  if (partition != NULL)
    {
      GDBusObject *object_for_partition;
      object_for_partition = g_dbus_interface_get_object (G_DBUS_INTERFACE (partition));
      if (object_for_partition != NULL)
        block_for_partition = udisks_object_peek_block (UDISKS_OBJECT (object_for_partition));
    }
  if (block_for_partition == NULL)
    block_for_partition = block;

  if (partition != NULL)
    {
      /* Translators: Used to describe a partition of a drive.
       *              The %d is the partition number.
       *              The %s is the description for the drive (e.g. "2 GB Thumb Drive").
       */
      s = g_strdup_printf (C_("part-drive", "Partition %d of %s"),
                           udisks_partition_get_number (partition), info->description);
      g_free (info->description);
      info->description = s;
    }

  /* calculate and set one-liner */
  if (block != NULL)
    {
      const gchar *drive_revision = udisks_drive_get_revision (drive);
      if (strlen (drive_revision) > 0)
        {
          /* Translators: String used for one-liner description of drive.
           *              The first %s is the description of the object (e.g. "80 GB Disk" or "Partition 2 of 2 GB Thumb Drive").
           *              The second %s is the name of the object (e.g. "INTEL SSDSA2MH080G1GC").
           *              The third %s is the fw revision (e.g "45ABX21").
           *              The fourth %s is the special device file (e.g. "/dev/sda").
           */
          info->one_liner = g_strdup_printf (C_("one-liner-drive", "%s — %s [%s] (%s)"),
                                             info->description,
                                             info->name,
                                             drive_revision,
                                             udisks_block_get_preferred_device (block_for_partition));
        }
      else
        {
          /* Translators: String used for one-liner description of drive w/o known fw revision.
           *              The first %s is the description of the object (e.g. "80 GB Disk").
           *              The second %s is the name of the object (e.g. "INTEL SSDSA2MH080G1GC").
           *              The third %s is the special device file (e.g. "/dev/sda").
           */
          info->one_liner = g_strdup_printf (C_("one-liner-drive", "%s — %s (%s)"),
                                             info->description,
                                             info->name,
                                             udisks_block_get_preferred_device (block_for_partition));
        }
    }

  g_free (hyphenated_connection_bus);
  g_free (size_str);

  info->sort_key = g_strdup_printf ("00_drive_%s", udisks_drive_get_sort_key (drive));

  g_clear_object (&block);
}
Пример #23
0
/**
 * udisks_daemon_util_on_same_seat:
 * @daemon: A #UDisksDaemon.
 * @object: The #GDBusObject that the call is on or %NULL.
 * @process: The process to check for.
 *
 * Checks whether the device represented by @object (if any) is plugged into
 * a seat where the caller represented by @process is logged in.
 *
 * This works if @object is a drive or a block object.
 *
 * Returns: %TRUE if @object and @process is on the same seat, %FALSE otherwise.
 */
gboolean
udisks_daemon_util_on_same_seat (UDisksDaemon          *daemon,
                                 UDisksObject          *object,
                                 pid_t                  process)
{
#if !defined(HAVE_LIBSYSTEMD_LOGIN)
  /* if we don't have systemd, assume it's always the same seat */
  return TRUE;
#else
  gboolean ret = FALSE;
  char *session = NULL;
  char *seat = NULL;
  const gchar *drive_seat;
  UDisksObject *drive_object = NULL;
  UDisksDrive *drive = NULL;

  /* if we don't have logind, assume it's always the same seat */
  if (!LOGIND_AVAILABLE())
    return TRUE;

  if (UDISKS_IS_LINUX_BLOCK_OBJECT (object))
    {
      UDisksLinuxBlockObject *linux_block_object;
      UDisksBlock *block;
      linux_block_object = UDISKS_LINUX_BLOCK_OBJECT (object);
      block = udisks_object_get_block (UDISKS_OBJECT (linux_block_object));
      if (block != NULL)
        {
          drive_object = udisks_daemon_find_object (daemon, udisks_block_get_drive (block));
          g_object_unref (block);
        }
    }
  else if (UDISKS_IS_LINUX_DRIVE_OBJECT (object))
    {
      drive_object = g_object_ref (object);
    }

  if (drive_object == NULL)
    goto out;

  drive = udisks_object_get_drive (UDISKS_OBJECT (drive_object));
  if (drive == NULL)
    goto out;

  /* It's not unexpected to not find a session, nor a seat associated with @process */
  if (sd_pid_get_session (process, &session) == 0)
    sd_session_get_seat (session, &seat);

  /* If we don't know the seat of the caller, we assume the device is always on another seat */
  if (seat == NULL)
    goto out;

  drive_seat = udisks_drive_get_seat (drive);
  if (g_strcmp0 (seat, drive_seat) == 0)
    {
      ret = TRUE;
      goto out;
    }

 out:
  free (seat);
  free (session);
  g_clear_object (&drive_object);
  g_clear_object (&drive);
  return ret;
#endif /* HAVE_LIBSYSTEMD_LOGIN */
}
Пример #24
0
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);
}
Пример #25
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;
}
Пример #26
0
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);
}