[gnome-disk-utility] Catch up with udisks API changes and implement Expansion for Linux's MD RAID
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Catch up with udisks API changes and implement Expansion for Linux's MD RAID
- Date: Fri, 5 Feb 2010 22:16:23 +0000 (UTC)
commit 9b5be85d80d1ce18190e6f44ae3d86ee30160a97
Author: David Zeuthen <davidz redhat com>
Date: Fri Feb 5 17:14:33 2010 -0500
Catch up with udisks API changes and implement Expansion for Linux's MD RAID
Screenshots here
http://people.freedesktop.org/~david/gdu-mdraid-expansion/
src/gdu-gtk/gdu-add-component-linux-md-dialog.c | 119 ++++++++++++------
src/gdu-gtk/gdu-add-component-linux-md-dialog.h | 11 +-
src/gdu-gtk/gdu-edit-linux-md-dialog.c | 53 ++++++--
src/gdu-gtk/gdu-edit-linux-md-dialog.h | 4 +-
src/gdu-gtk/gdu-gtk-enums.h | 14 ++
src/gdu-gtk/gdu-gtk-enumtypes.h | 2 +
src/gdu/gdu-callbacks.h | 10 +-
src/gdu/gdu-device.c | 72 +++++++++---
src/gdu/gdu-device.h | 15 ++-
src/palimpsest/gdu-section-linux-md-drive.c | 154 ++++++++++++++++++-----
10 files changed, 350 insertions(+), 104 deletions(-)
---
diff --git a/src/gdu-gtk/gdu-add-component-linux-md-dialog.c b/src/gdu-gtk/gdu-add-component-linux-md-dialog.c
index 5988c7f..18dfbe0 100644
--- a/src/gdu-gtk/gdu-add-component-linux-md-dialog.c
+++ b/src/gdu-gtk/gdu-add-component-linux-md-dialog.c
@@ -35,12 +35,14 @@
struct GduAddComponentLinuxMdDialogPrivate
{
GtkWidget *disk_selection_widget;
+ GduAddComponentLinuxMdFlags flags;
};
enum {
PROP_0,
- PROP_DRIVE,
- PROP_SIZE
+ PROP_DRIVES,
+ PROP_SIZE,
+ PROP_FLAGS,
};
G_DEFINE_TYPE (GduAddComponentLinuxMdDialog, gdu_add_component_linux_md_dialog, GDU_TYPE_DIALOG)
@@ -55,6 +57,26 @@ gdu_add_component_linux_md_dialog_finalize (GObject *object)
}
static void
+gdu_add_component_linux_md_dialog_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GduAddComponentLinuxMdDialog *dialog = GDU_ADD_COMPONENT_LINUX_MD_DIALOG (object);
+
+ switch (property_id) {
+
+ case PROP_FLAGS:
+ dialog->priv->flags = g_value_get_flags (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
gdu_add_component_linux_md_dialog_get_property (GObject *object,
guint property_id,
GValue *value,
@@ -63,14 +85,18 @@ gdu_add_component_linux_md_dialog_get_property (GObject *object,
GduAddComponentLinuxMdDialog *dialog = GDU_ADD_COMPONENT_LINUX_MD_DIALOG (object);
switch (property_id) {
- case PROP_DRIVE:
- g_value_take_object (value, gdu_add_component_linux_md_dialog_get_drive (dialog));
+ case PROP_DRIVES:
+ g_value_take_boxed (value, gdu_add_component_linux_md_dialog_get_drives (dialog));
break;
case PROP_SIZE:
g_value_set_uint64 (value, gdu_add_component_linux_md_dialog_get_size (dialog));
break;
+ case PROP_FLAGS:
+ g_value_set_flags (value, dialog->priv->flags);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -151,6 +177,7 @@ gdu_add_component_linux_md_dialog_constructed (GObject *object)
GtkWidget *image;
GtkWidget *label;
gchar *s;
+ gchar *s2;
GIcon *icon;
GduPresentable *p;
GduDevice *d;
@@ -162,6 +189,7 @@ gdu_add_component_linux_md_dialog_constructed (GObject *object)
gchar *component_size_str;
gchar *array_name;
gchar *array_name_vpd;
+ GduDiskSelectionWidgetFlags flags;
slaves = gdu_linux_md_drive_get_slaves (GDU_LINUX_MD_DRIVE (gdu_dialog_get_presentable (GDU_DIALOG (dialog))));
slave = GDU_DEVICE (slaves->data);
@@ -178,10 +206,6 @@ gdu_add_component_linux_md_dialog_constructed (GObject *object)
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- GTK_STOCK_ADD,
- GTK_RESPONSE_APPLY);
-
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
icon = gdu_presentable_get_icon (gdu_dialog_get_presentable (GDU_DIALOG (dialog)));
@@ -200,7 +224,29 @@ gdu_add_component_linux_md_dialog_constructed (GObject *object)
d = gdu_presentable_get_device (p);
pool = gdu_presentable_get_pool (p);
- s = g_strdup_printf (_("Add Component to %s"), array_name);
+ flags = GDU_DISK_SELECTION_WIDGET_FLAGS_NONE;
+ if (dialog->priv->flags & GDU_ADD_COMPONENT_LINUX_MD_FLAGS_SPARE) {
+ s = g_strdup_printf (_("Add spare to %s"), array_name);
+ s2 = g_strdup_printf (_("Select a device to create a %s spare on for the RAID Array \"%s\" (%s)"),
+ component_size_str,
+ array_name,
+ array_name_vpd);
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_ADD,
+ GTK_RESPONSE_APPLY);
+ } else if (dialog->priv->flags & GDU_ADD_COMPONENT_LINUX_MD_FLAGS_EXPANSION) {
+ s = g_strdup_printf (_("Expand %s"), array_name);
+ s2 = g_strdup_printf (_("Select one or more devices to use %s on for expanding the RAID Array \"%s\" (%s)"),
+ component_size_str,
+ array_name,
+ array_name_vpd);
+ flags |= GDU_DISK_SELECTION_WIDGET_FLAGS_ALLOW_MULTIPLE;
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
+ _("_Expand"),
+ GTK_RESPONSE_APPLY);
+ } else {
+ g_assert_not_reached ();
+ }
gtk_window_set_title (GTK_WINDOW (dialog), s);
g_free (s);
@@ -210,21 +256,13 @@ gdu_add_component_linux_md_dialog_constructed (GObject *object)
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_width_chars (GTK_LABEL (label), 70); /* TODO: hate */
- /* Translators: The first %s is the size (e.g. "42 GB") and the two following %s are the
- * name and vpd_name of the array (e.g. "Saturn" and "6 TB RAID-6")
- */
- s = g_strdup_printf (_("Select a disk to create a %s component on for the RAID Array \"%s\" (%s)"),
- component_size_str,
- array_name,
- array_name_vpd);
- gtk_label_set_markup (GTK_LABEL (label), s);
- g_free (s);
+ gtk_label_set_markup (GTK_LABEL (label), s2);
+ g_free (s2);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
/* --- */
- disk_selection_widget = gdu_disk_selection_widget_new (pool,
- GDU_DISK_SELECTION_WIDGET_FLAGS_NONE);
+ disk_selection_widget = gdu_disk_selection_widget_new (pool, flags);
g_signal_connect (disk_selection_widget,
"is-drive-ignored",
G_CALLBACK (on_is_drive_ignored),
@@ -269,17 +307,18 @@ gdu_add_component_linux_md_dialog_class_init (GduAddComponentLinuxMdDialogClass
g_type_class_add_private (klass, sizeof (GduAddComponentLinuxMdDialogPrivate));
+ object_class->set_property = gdu_add_component_linux_md_dialog_set_property;
object_class->get_property = gdu_add_component_linux_md_dialog_get_property;
object_class->constructed = gdu_add_component_linux_md_dialog_constructed;
object_class->finalize = gdu_add_component_linux_md_dialog_finalize;
g_object_class_install_property (object_class,
- PROP_DRIVE,
- g_param_spec_object ("drive",
- NULL,
- NULL,
- GDU_TYPE_DRIVE,
- G_PARAM_READABLE));
+ PROP_DRIVES,
+ g_param_spec_boxed ("drives",
+ NULL,
+ NULL,
+ G_TYPE_PTR_ARRAY,
+ G_PARAM_READABLE));
g_object_class_install_property (object_class,
PROP_SIZE,
@@ -290,6 +329,17 @@ gdu_add_component_linux_md_dialog_class_init (GduAddComponentLinuxMdDialogClass
G_MAXUINT64,
0,
G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class,
+ PROP_FLAGS,
+ g_param_spec_flags ("flags",
+ NULL,
+ NULL,
+ GDU_TYPE_ADD_COMPONENT_LINUX_MD_FLAGS,
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_NONE,
+ G_PARAM_READABLE|
+ G_PARAM_WRITABLE|
+ G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -301,31 +351,28 @@ gdu_add_component_linux_md_dialog_init (GduAddComponentLinuxMdDialog *dialog)
}
GtkWidget *
-gdu_add_component_linux_md_dialog_new (GtkWindow *parent,
- GduLinuxMdDrive *linux_md_drive)
+gdu_add_component_linux_md_dialog_new (GtkWindow *parent,
+ GduAddComponentLinuxMdFlags flags,
+ GduLinuxMdDrive *linux_md_drive)
{
g_return_val_if_fail (GDU_IS_LINUX_MD_DRIVE (linux_md_drive), NULL);
return GTK_WIDGET (g_object_new (GDU_TYPE_ADD_COMPONENT_LINUX_MD_DIALOG,
"transient-for", parent,
"presentable", linux_md_drive,
+ "flags", flags,
NULL));
}
-GduDrive *
-gdu_add_component_linux_md_dialog_get_drive (GduAddComponentLinuxMdDialog *dialog)
+GPtrArray *
+gdu_add_component_linux_md_dialog_get_drives (GduAddComponentLinuxMdDialog *dialog)
{
GPtrArray *drives;
- GduDrive *ret;
g_return_val_if_fail (GDU_IS_ADD_COMPONENT_LINUX_MD_DIALOG (dialog), NULL);
- ret = NULL;
drives = gdu_disk_selection_widget_get_selected_drives (GDU_DISK_SELECTION_WIDGET (dialog->priv->disk_selection_widget));
- if (drives->len > 0)
- ret = g_object_ref (GDU_DRIVE (drives->pdata[0]));
- g_ptr_array_unref (drives);
- return ret;
+ return drives;
}
guint64
diff --git a/src/gdu-gtk/gdu-add-component-linux-md-dialog.h b/src/gdu-gtk/gdu-add-component-linux-md-dialog.h
index 24658e3..44ad189 100644
--- a/src/gdu-gtk/gdu-add-component-linux-md-dialog.h
+++ b/src/gdu-gtk/gdu-add-component-linux-md-dialog.h
@@ -52,11 +52,12 @@ struct GduAddComponentLinuxMdDialogClass
GduDialogClass parent_class;
};
-GType gdu_add_component_linux_md_dialog_get_type (void) G_GNUC_CONST;
-GtkWidget *gdu_add_component_linux_md_dialog_new (GtkWindow *parent,
- GduLinuxMdDrive *linux_md_drive);
-GduDrive *gdu_add_component_linux_md_dialog_get_drive (GduAddComponentLinuxMdDialog *dialog);
-guint64 gdu_add_component_linux_md_dialog_get_size (GduAddComponentLinuxMdDialog *dialog);
+GType gdu_add_component_linux_md_dialog_get_type (void) G_GNUC_CONST;
+GtkWidget *gdu_add_component_linux_md_dialog_new (GtkWindow *parent,
+ GduAddComponentLinuxMdFlags flags,
+ GduLinuxMdDrive *linux_md_drive);
+GPtrArray *gdu_add_component_linux_md_dialog_get_drives (GduAddComponentLinuxMdDialog *dialog);
+guint64 gdu_add_component_linux_md_dialog_get_size (GduAddComponentLinuxMdDialog *dialog);
G_END_DECLS
diff --git a/src/gdu-gtk/gdu-edit-linux-md-dialog.c b/src/gdu-gtk/gdu-edit-linux-md-dialog.c
index c6664b9..8cae427 100644
--- a/src/gdu-gtk/gdu-edit-linux-md-dialog.c
+++ b/src/gdu-gtk/gdu-edit-linux-md-dialog.c
@@ -43,14 +43,16 @@ struct GduEditLinuxMdDialogPrivate
GduDetailsElement *component_state_element;
GduDetailsElement *component_device_element;
- GduButtonElement *component_new_button;
+ GduButtonElement *add_spare_button;
+ GduButtonElement *expand_button;
GduButtonElement *component_attach_button;
GduButtonElement *component_remove_button;
};
enum {
- NEW_BUTTON_CLICKED_SIGNAL,
+ ADD_SPARE_BUTTON_CLICKED_SIGNAL,
+ EXPAND_BUTTON_CLICKED_SIGNAL,
ATTACH_BUTTON_CLICKED_SIGNAL,
REMOVE_BUTTON_CLICKED_SIGNAL,
LAST_SIGNAL
@@ -106,11 +108,22 @@ gdu_edit_linux_md_dialog_class_init (GduEditLinuxMdDialogClass *klass)
object_class->constructed = gdu_edit_linux_md_dialog_constructed;
object_class->finalize = gdu_edit_linux_md_dialog_finalize;
- signals[NEW_BUTTON_CLICKED_SIGNAL] =
- g_signal_new ("new-button-clicked",
+ signals[ADD_SPARE_BUTTON_CLICKED_SIGNAL] =
+ g_signal_new ("add-spare-button-clicked",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GduEditLinuxMdDialogClass, new_button_clicked),
+ G_STRUCT_OFFSET (GduEditLinuxMdDialogClass, add_spare_button_clicked),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[EXPAND_BUTTON_CLICKED_SIGNAL] =
+ g_signal_new ("expand-button-clicked",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduEditLinuxMdDialogClass, expand_button_clicked),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
@@ -164,11 +177,19 @@ gdu_edit_linux_md_dialog_new (GtkWindow *parent,
/* ---------------------------------------------------------------------------------------------------- */
static void
-on_component_new_button_clicked (GduButtonElement *button_element,
+on_add_spare_button_clicked (GduButtonElement *button_element,
gpointer user_data)
{
GduEditLinuxMdDialog *dialog = GDU_EDIT_LINUX_MD_DIALOG (user_data);
- g_signal_emit (dialog, signals[NEW_BUTTON_CLICKED_SIGNAL], 0);
+ g_signal_emit (dialog, signals[ADD_SPARE_BUTTON_CLICKED_SIGNAL], 0);
+}
+
+static void
+on_expand_button_clicked (GduButtonElement *button_element,
+ gpointer user_data)
+{
+ GduEditLinuxMdDialog *dialog = GDU_EDIT_LINUX_MD_DIALOG (user_data);
+ g_signal_emit (dialog, signals[EXPAND_BUTTON_CLICKED_SIGNAL], 0);
}
static void
@@ -466,14 +487,24 @@ gdu_edit_linux_md_dialog_constructed (GObject *object)
elements = g_ptr_array_new_with_free_func (g_object_unref);
button_element = gdu_button_element_new (GTK_STOCK_NEW,
- _("_New Component"),
- _("Add a new component to the array"));
+ _("Add _Spare"),
+ _("Add a spare to the array"));
g_signal_connect (button_element,
"clicked",
- G_CALLBACK (on_component_new_button_clicked),
+ G_CALLBACK (on_add_spare_button_clicked),
dialog);
g_ptr_array_add (elements, button_element);
- dialog->priv->component_attach_button = button_element;
+ dialog->priv->add_spare_button = button_element;
+
+ button_element = gdu_button_element_new (GTK_STOCK_NEW,
+ _("_Expand Array"),
+ _("Increase the capacity of the array"));
+ g_signal_connect (button_element,
+ "clicked",
+ G_CALLBACK (on_expand_button_clicked),
+ dialog);
+ g_ptr_array_add (elements, button_element);
+ dialog->priv->expand_button = button_element;
button_element = gdu_button_element_new (GTK_STOCK_ADD,
_("_Attach Component"),
diff --git a/src/gdu-gtk/gdu-edit-linux-md-dialog.h b/src/gdu-gtk/gdu-edit-linux-md-dialog.h
index 11bb72f..408ce71 100644
--- a/src/gdu-gtk/gdu-edit-linux-md-dialog.h
+++ b/src/gdu-gtk/gdu-edit-linux-md-dialog.h
@@ -49,7 +49,9 @@ struct GduEditLinuxMdDialogClass
{
GduDialogClass parent_class;
- void (*new_button_clicked) (GduEditLinuxMdDialog *dialog);
+ void (*add_spare_button_clicked) (GduEditLinuxMdDialog *dialog);
+ void (*expand_button_clicked) (GduEditLinuxMdDialog *dialog);
+
void (*attach_button_clicked) (GduEditLinuxMdDialog *dialog,
GduDevice *slave);
void (*remove_button_clicked) (GduEditLinuxMdDialog *dialog,
diff --git a/src/gdu-gtk/gdu-gtk-enums.h b/src/gdu-gtk/gdu-gtk-enums.h
index 4232571..26b4927 100644
--- a/src/gdu-gtk/gdu-gtk-enums.h
+++ b/src/gdu-gtk/gdu-gtk-enums.h
@@ -105,4 +105,18 @@ typedef enum {
GDU_DISK_SELECTION_WIDGET_FLAGS_ALLOW_DISKS_WITH_INSUFFICIENT_SPACE = (1<<1)
} GduDiskSelectionWidgetFlags;
+/**
+ * GduAddComponentLinuxMdFlags:
+ * @GDU_ADD_COMPONENT_LINUX_MD_FLAGS_NONE: No flags set.
+ * @GDU_ADD_COMPONENT_LINUX_MD_FLAGS_SPARE: The dialog is for selecting a spare.
+ * @GDU_ADD_COMPONENT_LINUX_MD_FLAGS_EXPANSION: The dialog is for selecting a device used for expansion.
+ *
+ * Flags used when creating a #GduAddComponentLinuxMdDialog.
+ */
+typedef enum {
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_NONE = 0,
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_SPARE = (1<<0),
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_EXPANSION = (1<<1)
+} GduAddComponentLinuxMdFlags;
+
#endif /* GDU_GTK_ENUMS_H */
diff --git a/src/gdu-gtk/gdu-gtk-enumtypes.h b/src/gdu-gtk/gdu-gtk-enumtypes.h
index 0e299a8..14638ff 100644
--- a/src/gdu-gtk/gdu-gtk-enumtypes.h
+++ b/src/gdu-gtk/gdu-gtk-enumtypes.h
@@ -19,6 +19,8 @@ GType gdu_format_dialog_flags_get_type (void) G_GNUC_CONST;
#define GDU_TYPE_FORMAT_DIALOG_FLAGS (gdu_format_dialog_flags_get_type ())
GType gdu_disk_selection_widget_flags_get_type (void) G_GNUC_CONST;
#define GDU_TYPE_DISK_SELECTION_WIDGET_FLAGS (gdu_disk_selection_widget_flags_get_type ())
+GType gdu_add_component_linux_md_flags_get_type (void) G_GNUC_CONST;
+#define GDU_TYPE_ADD_COMPONENT_LINUX_MD_FLAGS (gdu_add_component_linux_md_flags_get_type ())
G_END_DECLS
#endif /* __GDU_GTK_ENUM_TYPES_H__ */
diff --git a/src/gdu/gdu-callbacks.h b/src/gdu/gdu-callbacks.h
index 5d20ced..dc6e661 100644
--- a/src/gdu/gdu-callbacks.h
+++ b/src/gdu/gdu-callbacks.h
@@ -101,9 +101,13 @@ typedef void (*GduDeviceLinuxMdCheckCompletedFunc) (GduDevice *device,
GError *error,
gpointer user_data);
-typedef void (*GduDeviceLinuxMdAddComponentCompletedFunc) (GduDevice *device,
- GError *error,
- gpointer user_data);
+typedef void (*GduDeviceLinuxMdAddSpareCompletedFunc) (GduDevice *device,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*GduDeviceLinuxMdExpandCompletedFunc) (GduDevice *device,
+ GError *error,
+ gpointer user_data);
typedef void (*GduDeviceLinuxMdRemoveComponentCompletedFunc) (GduDevice *device,
GError *error,
diff --git a/src/gdu/gdu-device.c b/src/gdu/gdu-device.c
index 10eaca6..6d31ab7 100644
--- a/src/gdu/gdu-device.c
+++ b/src/gdu/gdu-device.c
@@ -2430,14 +2430,14 @@ gdu_device_op_linux_md_check (GduDevice *device,
typedef struct {
GduDevice *device;
- GduDeviceLinuxMdAddComponentCompletedFunc callback;
+ GduDeviceLinuxMdAddSpareCompletedFunc callback;
gpointer user_data;
-} LinuxMdAddComponentData;
+} LinuxMdAddSpareData;
static void
-op_add_component_to_linux_md_array_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
+op_add_spare_to_linux_md_array_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
{
- LinuxMdAddComponentData *data = user_data;
+ LinuxMdAddSpareData *data = user_data;
_gdu_error_fixup (error);
if (data->callback != NULL)
data->callback (data->device, error, data->user_data);
@@ -2446,26 +2446,68 @@ op_add_component_to_linux_md_array_cb (DBusGProxy *proxy, GError *error, gpointe
}
void
-gdu_device_op_linux_md_add_component (GduDevice *device,
- const char *component_objpath,
- GduDeviceLinuxMdAddComponentCompletedFunc callback,
- gpointer user_data)
+gdu_device_op_linux_md_add_spare (GduDevice *device,
+ const char *component_objpath,
+ GduDeviceLinuxMdAddSpareCompletedFunc callback,
+ gpointer user_data)
{
char *options[16];
- LinuxMdAddComponentData *data;
+ LinuxMdAddSpareData *data;
- data = g_new0 (LinuxMdAddComponentData, 1);
+ data = g_new0 (LinuxMdAddSpareData, 1);
data->device = g_object_ref (device);
data->callback = callback;
data->user_data = user_data;
options[0] = NULL;
- org_freedesktop_UDisks_Device_linux_md_add_component_async (device->priv->proxy,
- component_objpath,
- (const char **) options,
- op_add_component_to_linux_md_array_cb,
- data);
+ org_freedesktop_UDisks_Device_linux_md_add_spare_async (device->priv->proxy,
+ component_objpath,
+ (const char **) options,
+ op_add_spare_to_linux_md_array_cb,
+ data);
+}
+
+/* -------------------------------------------------------------------------------- */
+
+typedef struct {
+ GduDevice *device;
+ GduDeviceLinuxMdExpandCompletedFunc callback;
+ gpointer user_data;
+} LinuxMdExpandData;
+
+static void
+op_expand_to_linux_md_array_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
+{
+ LinuxMdExpandData *data = user_data;
+ _gdu_error_fixup (error);
+ if (data->callback != NULL)
+ data->callback (data->device, error, data->user_data);
+ g_object_unref (data->device);
+ g_free (data);
+}
+
+void
+gdu_device_op_linux_md_expand (GduDevice *device,
+ GPtrArray *component_objpaths,
+ GduDeviceLinuxMdExpandCompletedFunc callback,
+ gpointer user_data)
+{
+ char *options[16];
+ LinuxMdExpandData *data;
+
+ data = g_new0 (LinuxMdExpandData, 1);
+ data->device = g_object_ref (device);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ options[0] = NULL;
+
+ org_freedesktop_UDisks_Device_linux_md_expand_async (device->priv->proxy,
+ component_objpaths,
+ (const char **) options,
+ op_expand_to_linux_md_array_cb,
+ data);
}
/* -------------------------------------------------------------------------------- */
diff --git a/src/gdu/gdu-device.h b/src/gdu/gdu-device.h
index 4b29d0b..01bfc01 100644
--- a/src/gdu/gdu-device.h
+++ b/src/gdu/gdu-device.h
@@ -306,10 +306,17 @@ void gdu_device_op_linux_md_check (GduDevice *devic
/* ---------------------------------------------------------------------------------------------------- */
-void gdu_device_op_linux_md_add_component (GduDevice *device,
- const char *component_objpath,
- GduDeviceLinuxMdAddComponentCompletedFunc callback,
- gpointer user_data);
+void gdu_device_op_linux_md_add_spare (GduDevice *device,
+ const char *component_objpath,
+ GduDeviceLinuxMdAddSpareCompletedFunc callback,
+ gpointer user_data);
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+void gdu_device_op_linux_md_expand (GduDevice *device,
+ GPtrArray *component_objpaths,
+ GduDeviceLinuxMdExpandCompletedFunc callback,
+ gpointer user_data);
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/palimpsest/gdu-section-linux-md-drive.c b/src/palimpsest/gdu-section-linux-md-drive.c
index 48637af..e696c80 100644
--- a/src/palimpsest/gdu-section-linux-md-drive.c
+++ b/src/palimpsest/gdu-section-linux-md-drive.c
@@ -593,10 +593,10 @@ on_components_dialog_attach_button_clicked (GduEditLinuxMdDialog *_dialog,
slave_flags = gdu_linux_md_drive_get_slave_flags (linux_md_drive, slave_device);
if (slave_flags & GDU_LINUX_MD_DRIVE_SLAVE_FLAGS_NOT_ATTACHED) {
- gdu_device_op_linux_md_add_component (device,
- gdu_device_get_object_path (slave_device),
- attach_component_op_callback,
- g_object_ref (gdu_section_get_shell (GDU_SECTION (section))));
+ gdu_device_op_linux_md_add_spare (device,
+ gdu_device_get_object_path (slave_device),
+ attach_component_op_callback,
+ g_object_ref (gdu_section_get_shell (GDU_SECTION (section))));
}
out:
@@ -609,8 +609,13 @@ on_components_dialog_attach_button_clicked (GduEditLinuxMdDialog *_dialog,
typedef struct {
GduShell *shell;
GduLinuxMdDrive *linux_md_drive;
- GduDrive *drive_to_add_to;
+ GduDevice *linux_md_drive_device;
+ GPtrArray *drives_to_add_to;
+ GPtrArray *created_components_object_paths;
+ guint next_volume_number;
+ gboolean failed;
guint64 size;
+ gboolean is_expansion;
} AddComponentData;
static void
@@ -620,11 +625,17 @@ add_component_data_free (AddComponentData *data)
g_object_unref (data->shell);
if (data->linux_md_drive != NULL)
g_object_unref (data->linux_md_drive);
- if (data->drive_to_add_to != NULL)
- g_object_unref (data->drive_to_add_to);
+ if (data->linux_md_drive_device != NULL)
+ g_object_unref (data->linux_md_drive_device);
+ if (data->drives_to_add_to != NULL)
+ g_ptr_array_unref (data->drives_to_add_to);
+ if (data->created_components_object_paths != NULL)
+ g_ptr_array_unref (data->created_components_object_paths);
g_free (data);
}
+static void do_create_volumes (AddComponentData *data);
+
static void
add_component_cb (GduDevice *device,
GError *error,
@@ -643,9 +654,13 @@ add_component_cb (GduDevice *device,
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
g_error_free (error);
+ data->failed = TRUE;
+ } else {
+ /* Onwards to the next one */
+ data->next_volume_number++;
}
- add_component_data_free (data);
+ do_create_volumes (data);
}
static void
@@ -667,30 +682,89 @@ new_component_create_volume_cb (GduDrive *drive,
error,
_("Error creating component for RAID array"));
g_error_free (error);
- add_component_data_free (data);
+ data->failed = TRUE;
+ do_create_volumes (data);
} else {
GduDevice *component_device;
- GduDevice *array_device;
component_device = gdu_presentable_get_device (GDU_PRESENTABLE (volume));
- array_device = gdu_presentable_get_device (GDU_PRESENTABLE (data->linux_md_drive));
- gdu_device_op_linux_md_add_component (array_device,
- gdu_device_get_object_path (component_device),
- add_component_cb,
- data);
+ if (data->is_expansion) {
+ /* If expanding, just queue up object paths ... */
+ g_ptr_array_add (data->created_components_object_paths,
+ g_strdup (gdu_device_get_object_path (component_device)));
+ /* ... and continue onwards to the next volume */
+ data->next_volume_number++;
+ do_create_volumes (data);
+ } else {
+ gdu_device_op_linux_md_add_spare (data->linux_md_drive_device,
+ gdu_device_get_object_path (component_device),
+ add_component_cb,
+ data);
+ }
- g_object_unref (array_device);
g_object_unref (component_device);
g_object_unref (volume);
}
}
static void
-on_components_dialog_new_button_clicked (GduEditLinuxMdDialog *_dialog,
- gpointer user_data)
+expand_md_cb (GduDevice *device,
+ GError *error,
+ gpointer user_data)
+{
+ AddComponentData *data = user_data;
+
+ if (error != NULL) {
+ GtkWidget *dialog;
+ dialog = gdu_error_dialog_new_for_drive (GTK_WINDOW (gdu_shell_get_toplevel (data->shell)),
+ device,
+ _("Error expanding RAID Array"),
+ error);
+ gtk_widget_show_all (dialog);
+ gtk_window_present (GTK_WINDOW (dialog));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ g_error_free (error);
+ data->failed = TRUE;
+ }
+
+ add_component_data_free (data);
+}
+
+static void
+do_create_volumes (AddComponentData *data)
+{
+ if (data->failed) {
+ /* Failed - already shown dialogs */
+ add_component_data_free (data);
+ } else if (data->next_volume_number == data->drives_to_add_to->len) {
+ /* Done! */
+
+ if (data->is_expansion) {
+ gdu_device_op_linux_md_expand (data->linux_md_drive_device,
+ data->created_components_object_paths,
+ expand_md_cb,
+ data);
+ } else {
+ add_component_data_free (data);
+ }
+ } else {
+ GduDrive *drive;
+ drive = data->drives_to_add_to->pdata[data->next_volume_number];
+ gdu_drive_create_volume (drive,
+ data->size,
+ gdu_device_linux_md_get_name (data->linux_md_drive_device),
+ GDU_CREATE_VOLUME_FLAGS_LINUX_MD,
+ (GAsyncReadyCallback) new_component_create_volume_cb,
+ data);
+ }
+}
+
+static void
+generic_add_component (GduSectionLinuxMdDrive *section,
+ gboolean is_expansion)
{
- GduSectionLinuxMdDrive *section = GDU_SECTION_LINUX_MD_DRIVE (user_data);
GduLinuxMdDrive *linux_md_drive;
GduDevice *device;
GtkWidget *dialog;
@@ -708,7 +782,11 @@ on_components_dialog_new_button_clicked (GduEditLinuxMdDialog *_dialog,
if (device == NULL)
goto out;
- dialog = gdu_add_component_linux_md_dialog_new (toplevel, linux_md_drive);
+ dialog = gdu_add_component_linux_md_dialog_new (toplevel,
+ is_expansion ?
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_EXPANSION :
+ GDU_ADD_COMPONENT_LINUX_MD_FLAGS_SPARE,
+ linux_md_drive);
gtk_widget_show_all (dialog);
response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_hide (dialog);
@@ -718,15 +796,13 @@ on_components_dialog_new_button_clicked (GduEditLinuxMdDialog *_dialog,
data = g_new0 (AddComponentData, 1);
data->shell = g_object_ref (gdu_section_get_shell (GDU_SECTION (section)));
data->linux_md_drive = g_object_ref (linux_md_drive);
- data->drive_to_add_to = gdu_add_component_linux_md_dialog_get_drive (GDU_ADD_COMPONENT_LINUX_MD_DIALOG (dialog));
+ data->linux_md_drive_device = g_object_ref (device);
+ data->drives_to_add_to = gdu_add_component_linux_md_dialog_get_drives (GDU_ADD_COMPONENT_LINUX_MD_DIALOG (dialog));
data->size = gdu_add_component_linux_md_dialog_get_size (GDU_ADD_COMPONENT_LINUX_MD_DIALOG (dialog));
+ data->is_expansion = is_expansion;
+ data->created_components_object_paths = g_ptr_array_new_with_free_func (g_free);
- gdu_drive_create_volume (data->drive_to_add_to,
- data->size,
- gdu_device_linux_md_get_name (device),
- GDU_CREATE_VOLUME_FLAGS_LINUX_MD,
- (GAsyncReadyCallback) new_component_create_volume_cb,
- data);
+ do_create_volumes (data);
out:
if (dialog != NULL)
@@ -735,6 +811,22 @@ on_components_dialog_new_button_clicked (GduEditLinuxMdDialog *_dialog,
g_object_unref (device);
}
+static void
+on_components_dialog_expand_button_clicked (GduEditLinuxMdDialog *dialog,
+ gpointer user_data)
+{
+ GduSectionLinuxMdDrive *section = GDU_SECTION_LINUX_MD_DRIVE (user_data);
+ generic_add_component (section, TRUE);
+}
+
+static void
+on_components_dialog_add_spare_button_clicked (GduEditLinuxMdDialog *dialog,
+ gpointer user_data)
+{
+ GduSectionLinuxMdDrive *section = GDU_SECTION_LINUX_MD_DRIVE (user_data);
+ generic_add_component (section, FALSE);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -752,8 +844,12 @@ on_edit_components_button_clicked (GduButtonElement *button_element,
dialog = gdu_edit_linux_md_dialog_new (toplevel, GDU_LINUX_MD_DRIVE (p));
g_signal_connect (dialog,
- "new-button-clicked",
- G_CALLBACK (on_components_dialog_new_button_clicked),
+ "add-spare-button-clicked",
+ G_CALLBACK (on_components_dialog_add_spare_button_clicked),
+ section);
+ g_signal_connect (dialog,
+ "expand-button-clicked",
+ G_CALLBACK (on_components_dialog_expand_button_clicked),
section);
g_signal_connect (dialog,
"attach-button-clicked",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]