[gnome-disk-utility] Track dynamic LV data (e.g. name and size) from the PV
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Track dynamic LV data (e.g. name and size) from the PV
- Date: Tue, 12 Jan 2010 12:11:18 +0000 (UTC)
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]