Beispiel #1
0
static gboolean
handle_delete (CockpitStorageVolumeGroup *object,
               GDBusMethodInvocation *invocation)
{
  StorageVolumeGroup *group = STORAGE_VOLUME_GROUP(object);
  StorageProvider *provider = storage_object_get_provider (group->object);
  GError *error = NULL;

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

  if (!storage_cleanup_volume_group (provider,
                                     group->lvm_volume_group,
                                     &error)
      || !lvm_volume_group_call_delete_sync (group->lvm_volume_group,
                                             TRUE,
                                             null_asv (),
                                             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);
    }
  else
    cockpit_storage_volume_group_complete_delete (object, invocation);

  return TRUE;
}
Beispiel #2
0
static void
storage_volume_group_dispose (GObject *obj)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (obj);
  GHashTableIter iter;
  const gchar *path;
  gpointer value;

  self->need_publish = FALSE;

  /* Dispose all the volumes, should unpublish */
  g_hash_table_iter_init (&iter, self->logical_volumes);
  while (g_hash_table_iter_next (&iter, NULL, &value))
      g_object_run_dispose (value);
  g_hash_table_remove_all (self->logical_volumes);
  g_hash_table_remove_all (self->physical_volumes);

  if (self->info)
    {
      g_variant_unref (self->info);
      self->info = NULL;
    }

  update_all_blocks (self);

  path = storage_volume_group_get_object_path (self);
  if (path != NULL)
    storage_daemon_unpublish (storage_daemon_get (), path, self);

  G_OBJECT_CLASS (storage_volume_group_parent_class)->dispose (obj);
}
Beispiel #3
0
static void
storage_volume_group_set_property (GObject *obj,
                              guint prop_id,
                              const GValue *value,
                              GParamSpec *pspec)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (obj);

  switch (prop_id)
    {
    case PROP_NAME:
      g_free (self->name);
      self->name = g_value_dup_string (value);
      break;

    case PROP_MANAGER:
      g_assert (self->manager == NULL);
      self->manager = g_value_get_object (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
      break;
    }
}
Beispiel #4
0
static gboolean
handle_create_thin_pool_volume (CockpitStorageVolumeGroup *object,
                                GDBusMethodInvocation *invocation,
                                const gchar *arg_name,
                                guint64 arg_size)
{
  StorageVolumeGroup *group = STORAGE_VOLUME_GROUP(object);
  GError *error = NULL;
  gs_free gchar *result = NULL;

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

  if (!lvm_volume_group_call_create_thin_pool_volume_sync (group->lvm_volume_group,
                                                           arg_name,
                                                           arg_size,
                                                           null_asv (),
                                                           &result,
                                                           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);
    }
  else
    cockpit_storage_volume_group_complete_create_thin_pool_volume (object, invocation);

  return TRUE;
}
Beispiel #5
0
static gboolean
handle_create_thin_volume (LvmVolumeGroup *group,
                           GDBusMethodInvocation *invocation,
                           const gchar *arg_name,
                           guint64 arg_size,
                           const gchar *arg_pool,
                           GVariant *options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  CompleteClosure *complete;
  StorageJob *job;
  StorageDaemon *daemon;
  StorageLogicalVolume *pool;
  gchar *size;

  daemon = storage_daemon_get ();

  pool = storage_daemon_find_thing (daemon, arg_pool, STORAGE_TYPE_LOGICAL_VOLUME);
  if (pool == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED,
                                             "Not a valid logical volume");
      return TRUE;
    }

  arg_size -= arg_size % 512;

  size = g_strdup_printf ("%" G_GUINT64_FORMAT "b", arg_size);

  job = storage_daemon_launch_spawned_job (daemon, self,
                                           "lvm-vg-create-volume",
                                           storage_invocation_get_caller_uid (invocation),
                                           NULL, /* GCancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
                                           NULL,  /* input_string */
                                           "lvcreate",
                                           storage_volume_group_get_name (self),
                                           "--thinpool", storage_logical_volume_get_name (pool),
                                           "-V", size, "-n", arg_name, NULL);

  complete = g_new0 (CompleteClosure, 1);
  complete->invocation = g_object_ref (invocation);
  complete->wait_thing = g_object_ref (self);
  complete->wait_name = g_strdup (arg_name);

  /* Wait for the job to finish */
  g_signal_connect (job, "completed", G_CALLBACK (on_create_complete), complete);

  /* Wait for the object to appear */
  complete->wait_sig = g_signal_connect_data (daemon,
                                              "published::StorageLogicalVolume",
                                              G_CALLBACK (on_create_logical_volume),
                                              complete, complete_closure_free, 0);

  g_free (size);
  g_object_unref (pool);
  return TRUE;
}
Beispiel #6
0
static void
on_lvm_volume_group_notify (GObject *object,
                            GParamSpec *pspec,
                            gpointer user_data)
{
  StorageVolumeGroup *volume_group = STORAGE_VOLUME_GROUP (user_data);
  storage_volume_group_update (volume_group);
}
Beispiel #7
0
static void
storage_volume_group_finalize (GObject *obj)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (obj);

  g_hash_table_unref (self->logical_volumes);
  g_free (self->name);

  G_OBJECT_CLASS (storage_volume_group_parent_class)->finalize (obj);
}
Beispiel #8
0
static gboolean
handle_poll (LvmVolumeGroup *group,
             GDBusMethodInvocation *invocation)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);

  storage_volume_group_poll (self);
  lvm_volume_group_complete_poll (group, invocation);

  return TRUE;
}
Beispiel #9
0
static void
storage_volume_group_finalize (GObject *object)
{
  StorageVolumeGroup *volume_group = STORAGE_VOLUME_GROUP (object);

  g_signal_handlers_disconnect_by_func (volume_group->lvm_volume_group,
                                        G_CALLBACK (on_lvm_volume_group_notify),
                                        volume_group);
  g_object_unref (volume_group->lvm_volume_group);

  G_OBJECT_CLASS (storage_volume_group_parent_class)->finalize (object);
}
Beispiel #10
0
static gboolean
handle_create_plain_volume (LvmVolumeGroup *group,
                            GDBusMethodInvocation *invocation,
                            const gchar *arg_name,
                            guint64 arg_size,
                            GVariant *options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  CompleteClosure *complete;
  StorageJob *job;
  StorageDaemon *daemon;
  GPtrArray *argv;

  daemon = storage_daemon_get ();

  arg_size -= arg_size % 512;

  argv = g_ptr_array_new_with_free_func (g_free);
  g_ptr_array_add (argv, g_strdup ("lvcreate"));
  g_ptr_array_add (argv, g_strdup (storage_volume_group_get_name (self)));
  g_ptr_array_add (argv, g_strdup_printf ("-L%" G_GUINT64_FORMAT "b", arg_size));
  g_ptr_array_add (argv, g_strdup ("-n"));
  g_ptr_array_add (argv, g_strdup (arg_name));
  g_ptr_array_add (argv, NULL);

  job = storage_daemon_launch_spawned_jobv (daemon, self,
                                            "lvm-vg-create-volume",
                                            storage_invocation_get_caller_uid (invocation),
                                            NULL, /* GCancellable */
                                            0,    /* uid_t run_as_uid */
                                            0,    /* uid_t run_as_euid */
                                            NULL,  /* input_string */
                                            (const gchar **)argv->pdata);

  complete = g_new0 (CompleteClosure, 1);
  complete->invocation = g_object_ref (invocation);
  complete->wait_thing = g_object_ref (self);
  complete->wait_name = g_strdup (arg_name);

  /* Wait for the job to finish */
  g_signal_connect (job, "completed", G_CALLBACK (on_create_complete), complete);

  /* Wait for the object to appear */
  complete->wait_sig = g_signal_connect_data (daemon,
                                              "published::StorageLogicalVolume",
                                              G_CALLBACK (on_create_logical_volume),
                                              complete, complete_closure_free, 0);

  g_ptr_array_free (argv, TRUE);
  return TRUE;
}
Beispiel #11
0
static gboolean
handle_add_device (LvmVolumeGroup *group,
                   GDBusMethodInvocation  *invocation,
                   const gchar *new_member_device_objpath,
                   GVariant *options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  StorageJob *job;
  StorageDaemon *daemon;
  StorageManager *manager;
  GError *error = NULL;
  StorageBlock *new_member_device = NULL;

  daemon = storage_daemon_get ();
  manager = storage_daemon_get_manager (daemon);

  new_member_device = storage_manager_find_block (manager, new_member_device_objpath);
  if (new_member_device == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED,
                                             "The given object is not a valid block");
    }
  else if (!storage_block_is_unused (new_member_device, &error))
    {
      g_dbus_method_invocation_take_error (invocation, error);
    }
  else if (!storage_util_wipe_block (storage_block_get_device (new_member_device), &error))
    {
      g_dbus_method_invocation_take_error (invocation, error);
    }
  else
    {
      job = storage_daemon_launch_spawned_job (daemon, self,
                                               "lvm-vg-add-device",
                                               storage_invocation_get_caller_uid (invocation),
                                               NULL, /* GCancellable */
                                               0,    /* uid_t run_as_uid */
                                               0,    /* uid_t run_as_euid */
                                               NULL,  /* input_string */
                                               "vgextend",
                                               storage_volume_group_get_name (self),
                                               storage_block_get_device (new_member_device),
                                               NULL);

      g_signal_connect_data (job, "completed", G_CALLBACK (on_adddev_complete),
                             g_object_ref (invocation), (GClosureNotify)g_object_unref, 0);
    }

  g_clear_object (&new_member_device);
  return TRUE; /* returning TRUE means that we handled the method invocation */
}
Beispiel #12
0
static gboolean
handle_delete (LvmVolumeGroup *group,
               GDBusMethodInvocation *invocation,
               gboolean arg_wipe,
               GVariant *arg_options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  VolumeGroupDeleteJobData *data;
  StorageDaemon *daemon;
  StorageJob *job;
  GList *l;

  daemon = storage_daemon_get ();

  data = g_new0 (VolumeGroupDeleteJobData, 1);
  data->vgname = g_strdup (storage_volume_group_get_name (self));

  /* Find physical volumes to wipe. */
  if (arg_wipe)
    {
      GPtrArray *devices = g_ptr_array_new ();
      GList *blocks = storage_manager_get_blocks (storage_daemon_get_manager (daemon));
      for (l = blocks; l; l = l->next)
        {
          LvmPhysicalVolumeBlock *physical_volume;
          physical_volume = storage_block_get_physical_volume_block (l->data);
          if (physical_volume
              && g_strcmp0 (lvm_physical_volume_block_get_volume_group (physical_volume),
                            storage_volume_group_get_object_path (self)) == 0)
            g_ptr_array_add (devices, g_strdup (storage_block_get_device (l->data)));
        }
      g_list_free_full (blocks, g_object_unref);
      g_ptr_array_add (devices, NULL);
      data->devices = (gchar **)g_ptr_array_free (devices, FALSE);
    }

  job = storage_daemon_launch_threaded_job (daemon, self,
                                            "lvm-vg-delete",
                                            storage_invocation_get_caller_uid (invocation),
                                            volume_group_delete_job_thread,
                                            data,
                                            volume_group_delete_job_free,
                                            NULL);

  g_signal_connect_data (job, "completed", G_CALLBACK (on_delete_complete),
                         g_object_ref (invocation), (GClosureNotify)g_object_unref, 0);

  return TRUE;
}
Beispiel #13
0
static gboolean
handle_empty_device (CockpitStorageVolumeGroup *object,
                     GDBusMethodInvocation *invocation,
                     const gchar *arg_objpath)
{
  StorageVolumeGroup *group = STORAGE_VOLUME_GROUP(object);
  GError *error = NULL;
  const gchar *block_path = "/";

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

  StorageProvider *provider = storage_object_get_provider (group->object);
  Daemon *daemon = storage_provider_get_daemon (provider);
  GDBusObjectManagerServer *object_manager_server = daemon_get_object_manager (daemon);
  GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object_manager_server);

  StorageObject *block_object =
    STORAGE_OBJECT (g_dbus_object_manager_get_object (object_manager, arg_objpath));
  UDisksBlock *udisks_block = storage_object_get_udisks_block (block_object);

  if (udisks_block)
    block_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (udisks_block));

  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (group->lvm_volume_group),
                                    G_MAXINT);

  if (!lvm_volume_group_call_empty_device_sync (group->lvm_volume_group,
                                                block_path,
                                                null_asv (),
                                                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);
    }
  else
    cockpit_storage_volume_group_complete_empty_device (object, invocation);

  g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (group->lvm_volume_group),
                                    -1);

  return TRUE;
}
Beispiel #14
0
static gboolean
handle_create_thin_volume (CockpitStorageVolumeGroup *object,
                           GDBusMethodInvocation *invocation,
                           const gchar *arg_name,
                           guint64 arg_size,
                           const gchar *arg_pool)
{
  StorageVolumeGroup *group = STORAGE_VOLUME_GROUP(object);
  GError *error = NULL;
  gs_free gchar *result = NULL;
  const gchar *pool_path = "/";

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

  StorageProvider *provider = storage_object_get_provider (group->object);
  Daemon *daemon = storage_provider_get_daemon (provider);
  GDBusObjectManagerServer *object_manager_server = daemon_get_object_manager (daemon);
  GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object_manager_server);

  StorageObject *pool_object =
    STORAGE_OBJECT (g_dbus_object_manager_get_object (object_manager, arg_pool));
  LvmLogicalVolume *lvm_pool_lvol = storage_object_get_lvm_logical_volume (pool_object);

  if (lvm_pool_lvol)
    pool_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (lvm_pool_lvol));

  if (!lvm_volume_group_call_create_thin_volume_sync (group->lvm_volume_group,
                                                      arg_name,
                                                      arg_size,
                                                      pool_path,
                                                      null_asv (),
                                                      &result,
                                                      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);
    }
  else
    cockpit_storage_volume_group_complete_create_thin_pool_volume (object, invocation);

  return TRUE;
}
Beispiel #15
0
static void
storage_volume_group_constructed (GObject *object)
{
  StorageVolumeGroup *volume_group = STORAGE_VOLUME_GROUP (object);

  volume_group->lvm_volume_group = g_object_ref (storage_object_get_lvm_volume_group (volume_group->object));
  g_signal_connect (volume_group->lvm_volume_group,
                    "notify",
                    G_CALLBACK (on_lvm_volume_group_notify),
                    volume_group);

  storage_volume_group_update (volume_group);

  if (G_OBJECT_CLASS (storage_volume_group_parent_class)->constructed != NULL)
    G_OBJECT_CLASS (storage_volume_group_parent_class)->constructed (object);
}
Beispiel #16
0
static void
on_create_logical_volume (StorageDaemon *daemon,
                          StorageLogicalVolume *volume,
                          gpointer user_data)
{
  CompleteClosure *complete = user_data;

  if (g_str_equal (storage_logical_volume_get_name (volume), complete->wait_name) &&
      storage_logical_volume_get_volume_group (volume) == STORAGE_VOLUME_GROUP (complete->wait_thing))
    {
      /* All creates have the same signature */
      lvm_volume_group_complete_create_plain_volume (NULL, complete->invocation,
                                                     storage_logical_volume_get_object_path (volume));
      g_signal_handler_disconnect (daemon, complete->wait_sig);
    }
}
Beispiel #17
0
static gboolean
handle_remove_device (LvmVolumeGroup *group,
                      GDBusMethodInvocation *invocation,
                      const gchar *member_device_objpath,
                      gboolean wipe,
                      GVariant *options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  VolumeGroupRemdevJobData *data;
  StorageDaemon *daemon;
  StorageManager *manager;
  StorageBlock *member_device;
  StorageJob *job;

  daemon = storage_daemon_get ();
  manager = storage_daemon_get_manager (daemon);

  member_device = storage_manager_find_block (manager, member_device_objpath);
  if (member_device == NULL)
    {
      g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED,
                                             "The given object is not a valid block");
      return TRUE;
    }

  data = g_new0 (VolumeGroupRemdevJobData, 1);
  data->wipe = wipe;
  data->vgname = g_strdup (storage_volume_group_get_name (self));
  data->pvname = g_strdup (storage_block_get_device (member_device));

  job = storage_daemon_launch_threaded_job (daemon, self,
                                            "lvm-vg-rem-device",
                                            storage_invocation_get_caller_uid (invocation),
                                            volume_group_remdev_job_thread,
                                            data,
                                            volume_group_remdev_job_free,
                                            NULL);

  g_signal_connect_data (job, "completed", G_CALLBACK (on_remdev_complete),
                         g_object_ref (invocation), (GClosureNotify)g_object_unref, 0);

  g_object_unref (member_device);
  return TRUE; /* returning TRUE means that we handled the method invocation */
}
Beispiel #18
0
static void
storage_volume_group_get_property (GObject *object,
                                   guint prop_id,
                                   GValue *value,
                                   GParamSpec *pspec)
{
  StorageVolumeGroup *volume_group = STORAGE_VOLUME_GROUP (object);

  switch (prop_id)
    {
    case PROP_OBJECT:
      g_value_set_object (value, volume_group->object);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}
Beispiel #19
0
static gboolean
handle_rename (LvmVolumeGroup *group,
               GDBusMethodInvocation *invocation,
               const gchar *new_name,
               GVariant *options)
{
  StorageVolumeGroup *self = STORAGE_VOLUME_GROUP (group);
  CompleteClosure *complete;
  StorageJob *job;
  StorageDaemon *daemon;

  daemon = storage_daemon_get ();

  job = storage_daemon_launch_spawned_job (daemon, self,
                                           "lvm-vg-rename",
                                           storage_invocation_get_caller_uid (invocation),
                                           NULL, /* GCancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
                                           NULL,  /* input_string */
                                           "vgrename",
                                           storage_volume_group_get_name (self),
                                           new_name,
                                           NULL);

  complete = g_new0 (CompleteClosure, 1);
  complete->invocation = g_object_ref (invocation);
  complete->wait_name = g_strdup (new_name);

  /* Wait for the job to finish */
  g_signal_connect (job, "completed", G_CALLBACK (on_rename_complete), complete);

  /* Wait for the object to appear */
  complete->wait_sig = g_signal_connect_data (daemon,
                                              "published::StorageVolumeGroup",
                                              G_CALLBACK (on_rename_volume_group),
                                              complete, complete_closure_free, 0);

  return TRUE;
}
Beispiel #20
0
static gboolean
handle_poll (CockpitStorageVolumeGroup *object,
             GDBusMethodInvocation *invocation)
{
  StorageVolumeGroup *group = STORAGE_VOLUME_GROUP(object);
  GError *error = NULL;

  if (!lvm_volume_group_call_poll_sync (group->lvm_volume_group,
                                        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);
    }
  else
    cockpit_storage_volume_group_complete_poll (object, invocation);

  return TRUE;
}