Exemple #1
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 */
}
Exemple #2
0
void
storage_volume_group_update_block (StorageVolumeGroup *self,
                                   StorageBlock *block)
{

  GUdevDevice *device;
  StorageLogicalVolume *volume;
  const gchar *block_vg_name;
  const gchar *block_lv_name;
  GVariant *pv_info;

  device = storage_block_get_udev (block);
  if (device)
    {
      block_vg_name = g_udev_device_get_property (device, "DM_VG_NAME");
      block_lv_name = g_udev_device_get_property (device, "DM_LV_NAME");

      if (g_strcmp0 (block_vg_name, storage_volume_group_get_name (self)) == 0)
        {
          volume = g_hash_table_lookup (self->logical_volumes, block_lv_name);
          storage_block_update_lv (block, volume);
        }
      g_object_unref (device);
    }

  pv_info = g_hash_table_lookup (self->physical_volumes, storage_block_get_device (block));
  if (!pv_info)
    {
      const gchar *const *symlinks;
      int i;
      symlinks = storage_block_get_symlinks (block);
      for (i = 0; symlinks[i]; i++)
        {
          pv_info = g_hash_table_lookup (self->physical_volumes, symlinks[i]);
          if (pv_info)
            break;
        }
    }

  if (pv_info)
    {
      storage_block_update_pv (block, self, pv_info);
    }
  else
    {
      LvmPhysicalVolumeBlock *pv = storage_block_get_physical_volume_block (block);
      if (pv && g_strcmp0 (lvm_physical_volume_block_get_volume_group (pv),
                           storage_volume_group_get_object_path (self)) == 0)
        storage_block_update_pv (block, NULL, NULL);
    }
}
Exemple #3
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;
}
Exemple #4
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 */
}
Exemple #5
0
static gboolean
handle_empty_device (LvmVolumeGroup *group,
                     GDBusMethodInvocation *invocation,
                     const gchar *member_device_objpath,
                     GVariant *options)
{
  StorageJob *job;
  StorageDaemon *daemon;
  StorageManager *manager;
  const gchar *member_device_file = NULL;
  StorageBlock *member_device = NULL;

  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;
    }

  member_device_file = storage_block_get_device (member_device);

  job = storage_daemon_launch_spawned_job (daemon, member_device,
                                           "lvm-vg-empty-device",
                                           storage_invocation_get_caller_uid (invocation),
                                           NULL, /* GCancellable */
                                           0,    /* uid_t run_as_uid */
                                           0,    /* uid_t run_as_euid */
                                           NULL,  /* input_string */
                                           "pvmove", member_device_file,
                                           NULL);

  g_signal_connect_data (job, "completed", G_CALLBACK (on_empty_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 */
}
Exemple #6
0
gboolean
storage_block_is_unused (StorageBlock *self,
                    GError **error)
{
  const gchar *device_file;
  int fd;

  g_return_val_if_fail (STORAGE_IS_BLOCK (self), FALSE);

  device_file = storage_block_get_device (self);
  fd = open (device_file, O_RDONLY | O_EXCL);
  if (fd < 0)
    {
      g_set_error (error, UDISKS_ERROR, UDISKS_ERROR_FAILED,
                   "Error opening device %s: %m",
                   device_file);
      return FALSE;
    }
  close (fd);
  return TRUE;
}
Exemple #7
0
static void
update_progress_for_device (const gchar *operation,
                            const gchar *dev,
                            double progress)
{
  StorageDaemon *daemon;
  StorageManager *manager;
  GList *jobs, *l;

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

  for (l = jobs; l; l = g_list_next (l))
    {
      UDisksJob *job = l->data;
      const gchar *const *job_objects;
      int i;

      if (g_strcmp0 (udisks_job_get_operation (job), operation) != 0)
        continue;

      job_objects = udisks_job_get_objects (job);
      for (i = 0; job_objects[i]; i++)
        {
          StorageBlock *block;
          gboolean found = FALSE;

          block = storage_manager_find_block (manager, job_objects[i]);
          if (block)
            {
              if (g_strcmp0 (storage_block_get_device (block), dev) == 0)
                {
                  found = TRUE;
                }
              else
                {
                  const gchar **symlinks;
                  int j;

                  symlinks = storage_block_get_symlinks (block);
                  for (j = 0; symlinks[j]; j++)
                    {
                      if (g_strcmp0 (symlinks[j], dev) == 0)
                        {
                          found = TRUE;
                          break;
                        }
                    }
                }
            }

          if (found)
            {
              udisks_job_set_progress (job, progress);
              udisks_job_set_progress_valid (job, TRUE);
            }
        }
    }

  g_list_free_full (jobs, g_object_unref);
}