[gnome-disk-utility] Track dynamic LV data (e.g. name and size) from the PV



commit 5e71a1fe00f13e2acb0267a3c8ce264693024629
Author: David Zeuthen <davidz redhat com>
Date:   Tue Jan 12 05:29:13 2010 -0500

    Track dynamic LV data (e.g. name and size) from the PV
    
    Otherwise things wont work if a LV is renamed via e.g. lvrename(8).

 src/gdu/gdu-linux-lvm2-volume-group.c |   66 +++++++++++++++++++++++++++
 src/gdu/gdu-linux-lvm2-volume-group.h |   11 +++-
 src/gdu/gdu-linux-lvm2-volume.c       |   80 ++++++++++++++++++++++++++-------
 src/gdu/gdu-pool.c                    |    8 ---
 src/gdu/gdu-private.h                 |    3 -
 5 files changed, 138 insertions(+), 30 deletions(-)
---
diff --git a/src/gdu/gdu-linux-lvm2-volume-group.c b/src/gdu/gdu-linux-lvm2-volume-group.c
index a88b9ac..8b94917 100644
--- a/src/gdu/gdu-linux-lvm2-volume-group.c
+++ b/src/gdu/gdu-linux-lvm2-volume-group.c
@@ -559,3 +559,69 @@ gdu_linux_lvm2_volume_group_get_uuid (GduLinuxLvm2VolumeGroup *vg)
 {
         return vg->priv->uuid;
 }
+
+gboolean
+gdu_linux_lvm2_volume_group_get_lv_info (GduLinuxLvm2VolumeGroup  *vg,
+                                         const gchar              *lv_uuid,
+                                         guint                    *out_position,
+                                         gchar                   **out_name,
+                                         guint64                  *out_size)
+{
+        gchar **lvs;
+        gboolean ret;
+        guint position;
+        gchar *name;
+        guint64 size;
+        guint n;
+
+        position = G_MAXUINT;
+        name = NULL;
+        size = G_MAXUINT64;
+        ret = FALSE;
+
+        if (vg->priv->pv == NULL)
+                goto out;
+
+        lvs = gdu_device_linux_lvm2_pv_get_group_logical_volumes (vg->priv->pv);
+
+        for (n = 0; lvs != NULL && lvs[n] != NULL; n++) {
+                gchar **tokens;
+                guint m;
+
+                tokens = g_strsplit (lvs[n], ";", 0);
+
+                for (m = 0; tokens[m] != NULL; m++) {
+                        /* TODO: we need to unescape values */
+                        if (g_str_has_prefix (tokens[m], "uuid=") && g_strcmp0 (tokens[m] + 5, lv_uuid) == 0) {
+                                guint p;
+
+                                for (p = 0; tokens[p] != NULL; p++) {
+                                        /* TODO: we need to unescape values */
+                                        if (g_str_has_prefix (tokens[p], "name="))
+                                                name = g_strdup (tokens[p] + 5);
+                                        else if (g_str_has_prefix (tokens[p], "size="))
+                                                size = g_ascii_strtoull (tokens[p] + 5, NULL, 10);
+                                }
+                                position = n;
+
+                                g_strfreev (tokens);
+                                ret = TRUE;
+                                goto out;
+                        }
+                }
+                g_strfreev (tokens);
+        }
+
+ out:
+        if (ret) {
+                if (out_position != NULL)
+                        *out_position = position;
+                if (out_name != NULL)
+                        *out_name = name;
+                else
+                        g_free (name);
+                if (out_size != NULL)
+                        *out_size = size;
+        }
+        return ret;
+}
diff --git a/src/gdu/gdu-linux-lvm2-volume-group.h b/src/gdu/gdu-linux-lvm2-volume-group.h
index 824f23d..db48b98 100644
--- a/src/gdu/gdu-linux-lvm2-volume-group.h
+++ b/src/gdu/gdu-linux-lvm2-volume-group.h
@@ -61,9 +61,14 @@ typedef enum {
 } GduLinuxLvm2VolumeGroupState;
 
 GType                         gdu_linux_lvm2_volume_group_get_type      (void);
-const gchar                  *gdu_linux_lvm2_volume_group_get_uuid      (GduLinuxLvm2VolumeGroup *vg);
-GduLinuxLvm2VolumeGroupState  gdu_linux_lvm2_volume_group_get_state     (GduLinuxLvm2VolumeGroup *vg);
-GduDevice                    *gdu_linux_lvm2_volume_group_get_pv_device (GduLinuxLvm2VolumeGroup *vg);
+const gchar                  *gdu_linux_lvm2_volume_group_get_uuid      (GduLinuxLvm2VolumeGroup  *vg);
+GduLinuxLvm2VolumeGroupState  gdu_linux_lvm2_volume_group_get_state     (GduLinuxLvm2VolumeGroup  *vg);
+GduDevice                    *gdu_linux_lvm2_volume_group_get_pv_device (GduLinuxLvm2VolumeGroup  *vg);
+gboolean                      gdu_linux_lvm2_volume_group_get_lv_info   (GduLinuxLvm2VolumeGroup  *vg,
+                                                                         const gchar              *lv_uuid,
+                                                                         guint                    *out_position,
+                                                                         gchar                   **out_name,
+                                                                         guint64                  *out_size);
 
 G_END_DECLS
 
diff --git a/src/gdu/gdu-linux-lvm2-volume.c b/src/gdu/gdu-linux-lvm2-volume.c
index e483c38..8d60040 100644
--- a/src/gdu/gdu-linux-lvm2-volume.c
+++ b/src/gdu/gdu-linux-lvm2-volume.c
@@ -28,6 +28,7 @@
 #include "gdu-util.h"
 #include "gdu-pool.h"
 #include "gdu-device.h"
+#include "gdu-linux-lvm2-volume-group.h"
 #include "gdu-linux-lvm2-volume.h"
 #include "gdu-presentable.h"
 
@@ -40,7 +41,7 @@ struct _GduLinuxLvm2VolumePrivate
         gchar *group_uuid;
         gchar *uuid;
 
-        guint64 offset;
+        guint position;
         guint64 size;
 
         /* the GduDevice for the LV / mapped device (if activated) */
@@ -59,6 +60,8 @@ static void on_device_added (GduPool *pool, GduDevice *device, gpointer user_dat
 static void on_device_removed (GduPool *pool, GduDevice *device, gpointer user_data);
 static void on_device_changed (GduPool *pool, GduDevice *device, gpointer user_data);
 
+static void on_presentable_changed (GduPresentable *presentable, gpointer user_data);
+
 G_DEFINE_TYPE_WITH_CODE (GduLinuxLvm2Volume, gdu_linux_lvm2_volume, GDU_TYPE_VOLUME,
                          G_IMPLEMENT_INTERFACE (GDU_TYPE_PRESENTABLE,
                                                 gdu_linux_lvm2_volume_presentable_iface_init))
@@ -82,8 +85,12 @@ gdu_linux_lvm2_volume_finalize (GObject *object)
         g_free (volume->priv->group_uuid);
         g_free (volume->priv->uuid);
 
-        if (volume->priv->enclosing_presentable != NULL)
+        if (volume->priv->enclosing_presentable != NULL) {
+                g_signal_handlers_disconnect_by_func (volume->priv->enclosing_presentable,
+                                                      on_presentable_changed,
+                                                      volume);
                 g_object_unref (volume->priv->enclosing_presentable);
+        }
 
         if (volume->priv->lv != NULL)
                 g_object_unref (volume->priv->lv);
@@ -181,39 +188,72 @@ on_device_changed (GduPool *pool, GduDevice *device, gpointer user_data)
                 emit_changed (volume);
 }
 
+static gboolean
+update_lv_info (GduLinuxLvm2Volume *volume)
+{
+        guint position;
+        gchar *name;
+        guint64 size;
+        gboolean changed;
+
+        changed = FALSE;
+
+        if (gdu_linux_lvm2_volume_group_get_lv_info (GDU_LINUX_LVM2_VOLUME_GROUP (volume->priv->enclosing_presentable),
+                                                     volume->priv->uuid,
+                                                     &position,
+                                                     &name,
+                                                     &size)) {
+                if (volume->priv->position != position) {
+                        volume->priv->position = position;
+                        changed = TRUE;
+                }
+                if (g_strcmp0 (volume->priv->name, name) != 0) {
+                        g_free (volume->priv->name);
+                        volume->priv->name = name;
+                        changed = TRUE;
+                }
+                if (volume->priv->size != size) {
+                        volume->priv->size = size;
+                        changed = TRUE;
+                }
+        }
+
+        return changed;
+}
+
+/* Called when the VG changes */
+static void
+on_presentable_changed (GduPresentable *presentable, gpointer user_data)
+{
+        GduLinuxLvm2Volume *volume = GDU_LINUX_LVM2_VOLUME (user_data);
+
+        if (update_lv_info (volume)) {
+                g_signal_emit_by_name (volume, "changed");
+                g_signal_emit_by_name (volume->priv->pool, "presentable-changed", volume);
+        }
+}
+
 /**
  * _gdu_linux_lvm2_volume_new:
  * @pool: A #GduPool.
- * @name: The name of the logical volume.
  * @group_uuid: The UUID of the group that the logical volume belongs to.
  * @uuid: The UUID of the logical volume.
- * @offset: The offset of the logical volume.
- * @size: The size of the logical volume.
  * @enclosing_presentable: The enclosing presentable.
  *
  * Creates a new #GduLinuxLvm2Volume.
- *
- * Note that @offset is only used for laying out the volumes in e.g. a grid - it doesn't really
- * make sense to talk about the offset of a LV in LVM2.
  */
 GduLinuxLvm2Volume *
 _gdu_linux_lvm2_volume_new (GduPool        *pool,
-                            const gchar    *name,
                             const gchar    *group_uuid,
                             const gchar    *uuid,
-                            guint64         offset,
-                            guint64         size,
                             GduPresentable *enclosing_presentable)
 {
         GduLinuxLvm2Volume *volume;
 
         volume = GDU_LINUX_LVM2_VOLUME (g_object_new (GDU_TYPE_LINUX_LVM2_VOLUME, NULL));
         volume->priv->pool = g_object_ref (pool);
-        volume->priv->name = g_strdup (name);
         volume->priv->group_uuid = g_strdup (group_uuid);
         volume->priv->uuid = g_strdup (uuid);
-        volume->priv->offset = offset;
-        volume->priv->size = size;
 
         volume->priv->id = g_strdup_printf ("linux_lvm2_volume_%s_enclosed_by_%s",
                                         uuid,
@@ -222,6 +262,15 @@ _gdu_linux_lvm2_volume_new (GduPool        *pool,
         volume->priv->enclosing_presentable =
                 enclosing_presentable != NULL ? g_object_ref (enclosing_presentable) : NULL;
 
+        update_lv_info (volume);
+        /* Track the VG since we get the data like name and size from there */
+        if (volume->priv->enclosing_presentable != NULL) {
+                g_signal_connect (volume->priv->enclosing_presentable,
+                                  "changed",
+                                  G_CALLBACK (on_presentable_changed),
+                                  volume);
+        }
+
         g_signal_connect (volume->priv->pool, "device-added", G_CALLBACK (on_device_added), volume);
         g_signal_connect (volume->priv->pool, "device-removed", G_CALLBACK (on_device_removed), volume);
         g_signal_connect (volume->priv->pool, "device-changed", G_CALLBACK (on_device_changed), volume);
@@ -338,14 +387,13 @@ gdu_linux_lvm2_volume_get_offset (GduPresentable *presentable)
 {
         GduLinuxLvm2Volume *volume = GDU_LINUX_LVM2_VOLUME (presentable);
 
-        return volume->priv->offset;
+        return volume->priv->position;
 }
 
 static guint64
 gdu_linux_lvm2_volume_get_size (GduPresentable *presentable)
 {
         GduLinuxLvm2Volume *volume = GDU_LINUX_LVM2_VOLUME (presentable);
-
         return volume->priv->size;
 }
 
diff --git a/src/gdu/gdu-pool.c b/src/gdu/gdu-pool.c
index 2c57c51..5344c2c 100644
--- a/src/gdu/gdu-pool.c
+++ b/src/gdu/gdu-pool.c
@@ -1165,7 +1165,6 @@ recompute_presentables (GduPool *pool)
                         if (vg == NULL) {
                                 gchar **lvs;
                                 guint n;
-                                guint64 offset;
                                 guint64 unallocated_size;
 
                                 /* otherwise create one */
@@ -1175,7 +1174,6 @@ recompute_presentables (GduPool *pool)
 
                                 /* and create logical volume objects as well */
                                 lvs = gdu_device_linux_lvm2_pv_get_group_logical_volumes (device);
-                                offset = 0;
                                 for (n = 0; lvs != NULL && lvs[n] != NULL; n++) {
                                         const gchar *lv_desc = lvs[n];
                                         gchar **tokens;
@@ -1187,7 +1185,6 @@ recompute_presentables (GduPool *pool)
                                         tokens = g_strsplit (lv_desc, ";", 0);
                                         for (m = 0; tokens[m] != NULL; m++) {
                                                 /* TODO: we need to unescape values */
-
                                                 if (g_str_has_prefix (tokens[m], "name="))
                                                         name = g_strdup (tokens[m] + 5);
                                                 else if (g_str_has_prefix (tokens[m], "uuid="))
@@ -1200,16 +1197,11 @@ recompute_presentables (GduPool *pool)
                                                 GduLinuxLvm2Volume *volume;
 
                                                 volume = _gdu_linux_lvm2_volume_new (pool,
-                                                                                     name,
                                                                                      vg_uuid,
                                                                                      uuid,
-                                                                                     offset,
-                                                                                     size,
                                                                                      GDU_PRESENTABLE (vg));
                                                 new_presentables = g_list_prepend (new_presentables, volume);
 
-                                                offset += size;
-
                                         } else {
                                                 g_warning ("Malformed LMV2 LV in group with UUID %s: "
                                                            "pos=%d name=%s uuid=%s size=%" G_GUINT64_FORMAT,
diff --git a/src/gdu/gdu-private.h b/src/gdu/gdu-private.h
index 406ba2d..594d1a8 100644
--- a/src/gdu/gdu-private.h
+++ b/src/gdu/gdu-private.h
@@ -131,11 +131,8 @@ _gdu_linux_lvm2_volume_group_new (GduPool        *pool,
 void _gdu_linux_lvm2_volume_group_rewrite_enclosing_presentable (GduLinuxLvm2VolumeGroup *vg);
 
 GduLinuxLvm2Volume *_gdu_linux_lvm2_volume_new (GduPool        *pool,
-                                                const gchar    *name,
                                                 const gchar    *group_uuid,
                                                 const gchar    *uuid,
-                                                guint64         offset,
-                                                guint64         size,
                                                 GduPresentable *enclosing_presentable);
 
 void _gdu_linux_lvm2_volume_rewrite_enclosing_presentable (GduLinuxLvm2Volume *volume);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]