]> sourceware.org Git - lvm2.git/commitdiff
metadata: add infrastructure to track LV history
authorPeter Rajnoha <prajnoha@redhat.com>
Tue, 1 Mar 2016 14:18:42 +0000 (15:18 +0100)
committerPeter Rajnoha <prajnoha@redhat.com>
Thu, 3 Mar 2016 10:26:51 +0000 (11:26 +0100)
Add new structures and new fields in existing structures to support
tracking history of LVs (the LVs which don't exist - the have been
removed already):

  - new "struct historical_logical_volume"
    This structure keeps information specific to historical LVs
    (historical LV is very reduced form of struct logical_volume +
     it contains a few specific fields to track historical LV
     properties like removal time and connections among other LVs).

  - new "struct generic_logical_volume"
    Wrapper for "struct historical_logical_volume" and
    "struct logical_volume" to make it possible to handle volumes
    in uniform way, no matter if it's live or historical one.

  - new "struct glv_list"
    Wrapper for "struct generic_logical_volume" so it can be
    added to a list.

  - new "indirect_glvs" field in "struct logical_volume"
    List that stores references to all indirect users of this LV - this
    interconnects live LV with historical descendant LVs or even live
    descendant LVs.

  - new "indirect_origin" field in "struct lv_segment"
    Reference to indirect origin of this segment - this interconnects
    live LV (segment) with historical ancestor.

  - new "this_glv" field in "struct logical_volume"
    This references an existing generic_logical_volume wrapper for this
    LV, if used. It can be NULL if not needed - which means we're not
    handling historical LVs at all.

  - new "historical_lvs" field in "struct volume group
    List of all historical LVs read from VG metadata.

lib/metadata/lv.h
lib/metadata/lv_manip.c
lib/metadata/metadata-exported.h
lib/metadata/vg.c
lib/metadata/vg.h
lib/report/report.c
tools/reporter.c

index 4b42eb7f54a5d1dee14fdffd70e1a101670f10a9..f554bcef6dc07810b2114768db2c65220d4f3728 100644 (file)
@@ -49,6 +49,15 @@ struct logical_volume {
        struct dm_list segments;
        struct dm_list tags;
        struct dm_list segs_using_this_lv;
+       struct dm_list indirect_glvs; /* For keeping track of historical LVs in ancestry chain */
+
+       /*
+        * this_glv variable is used as a helper for handling historical LVs.
+        * If this LVs has no role at all in keeping track of historical LVs,
+        * the this_glv variable is NULL. See also comments for struct
+        * generic_logical_volume and struct historical_logical_volume below.
+        */
+       struct generic_logical_volume *this_glv;
 
        uint64_t timestamp;
        unsigned new_lock_args:1;
@@ -56,6 +65,45 @@ struct logical_volume {
        const char *lock_args;
 };
 
+/*
+ * With the introduction of tracking historical LVs, we need to make
+ * a difference between live LV (struct logical_volume) and historical LV
+ * (struct historical_logical_volume). To minimize the impact of this change
+ * and to minimize the changes needed in the existing  code, we use a
+ * little trick here - when processing LVs (e.g. while reporting LV
+ * properties), each historical LV is represented as dummy LV which is
+ * an instance of struct logical_volume with all its properties set to
+ * blank (hence "dummy LV") and with this_glv pointing to the struct
+ * historical_logical_volume. This way all the existing code working with
+ * struct logical_volume will see this historical LV as dummy live LV while
+ * the code that needs to recognize between live and historical LV will
+ * check this_glv first and then it will work either with the live
+ * or historical LV properties appropriately.
+ */
+struct generic_logical_volume;
+
+/*
+ * historical logical volume is an LV that has been removed already.
+ * This is used to keep track of LV history.
+ */
+struct historical_logical_volume {
+       union lvid lvid;
+       const char *name;
+       struct volume_group *vg;
+       uint64_t timestamp;
+       uint64_t timestamp_removed;
+       struct generic_logical_volume *indirect_origin;
+       struct dm_list indirect_glvs; /* list of struct generic_logical_volume */
+};
+
+struct generic_logical_volume {
+       int is_historical;
+       union {
+               struct logical_volume *live;                    /* is_historical=0 */
+               struct historical_logical_volume *historical;   /* is_historical=1 */
+       };
+};
+
 struct lv_with_info_and_seg_status;
 
 /* LV dependencies */
index 1b431c1b4e25d7bf9fb677107341e262170f6d2b..069042c0f40b3362a2ac7495feb7b2227bcaebea 100644 (file)
@@ -5320,6 +5320,7 @@ struct logical_volume *alloc_lv(struct dm_pool *mem)
        dm_list_init(&lv->segments);
        dm_list_init(&lv->tags);
        dm_list_init(&lv->segs_using_this_lv);
+       dm_list_init(&lv->indirect_glvs);
        dm_list_init(&lv->rsites);
 
        return lv;
index 8376a54e6bd3c0af12361787401e4ab999451e91..97cba5117d7ecaacd7e4bb0d8a21c73cb7d12db0 100644 (file)
@@ -447,6 +447,7 @@ struct lv_segment {
        uint32_t chunk_size;    /* For snapshots/thin_pool.  In sectors. */
                                /* For thin_pool, 128..2097152. */
        struct logical_volume *origin;  /* snap and thin */
+       struct generic_logical_volume *indirect_origin;
        struct logical_volume *merge_lv; /* thin, merge descendent lv into this ancestor */
        struct logical_volume *cow;
        struct dm_list origin_list;
@@ -505,6 +506,11 @@ struct lv_list {
        struct logical_volume *lv;
 };
 
+struct glv_list {
+       struct dm_list list;
+       struct generic_logical_volume *glv;
+};
+
 struct vg_list {
        struct dm_list list;
        struct volume_group *vg;
index 1456fbb50c21b3424443d23da4a6edc87db9c733..90c459e191ab8df603dd35d903398e3ca638ee77 100644 (file)
@@ -64,6 +64,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
        dm_list_init(&vg->pv_write_list);
        dm_list_init(&vg->pvs_outdated);
        dm_list_init(&vg->lvs);
+       dm_list_init(&vg->historical_lvs);
        dm_list_init(&vg->tags);
        dm_list_init(&vg->removed_lvs);
        dm_list_init(&vg->removed_pvs);
index f41def8e76194b0b862f27ba6a422c762f1ff9a1..c5197cb3313f07d93f0335bb603b77c3b08df58b 100644 (file)
@@ -128,6 +128,7 @@ struct volume_group {
         * - one for the user-visible mirror LV
         */
        struct dm_list lvs;
+       struct dm_list historical_lvs;
 
        struct dm_list tags;
 
index 43987b1d37120f063adf87e819c67ada1b1b2439..056afd2d3ccc58264db9613e6c2124fd0250c03e 100644 (file)
@@ -3386,6 +3386,7 @@ static struct volume_group _dummy_vg = {
        .lvm1_system_id = (char *) "",
        .pvs = DM_LIST_HEAD_INIT(_dummy_vg.pvs),
        .lvs = DM_LIST_HEAD_INIT(_dummy_vg.lvs),
+       .historical_lvs = DM_LIST_HEAD_INIT(_dummy_vg.historical_lvs),
        .tags = DM_LIST_HEAD_INIT(_dummy_vg.tags),
 };
 
@@ -3396,6 +3397,7 @@ static struct volume_group _unknown_vg = {
        .lvm1_system_id = (char *) "",
        .pvs = DM_LIST_HEAD_INIT(_unknown_vg.pvs),
        .lvs = DM_LIST_HEAD_INIT(_unknown_vg.lvs),
+       .historical_lvs = DM_LIST_HEAD_INIT(_unknown_vg.historical_lvs),
        .tags = DM_LIST_HEAD_INIT(_unknown_vg.tags),
 };
 
index 1a24698b35b5b7e0d8f66f776289edf1feaffe4c..0c73a0955da7b6c7e978743f677dca60f395df05 100644 (file)
@@ -244,6 +244,7 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
                .name = "",
                .pvs = DM_LIST_HEAD_INIT(_free_vg.pvs),
                .lvs = DM_LIST_HEAD_INIT(_free_vg.lvs),
+               .historical_lvs = DM_LIST_HEAD_INIT(_free_vg.historical_lvs),
                .tags = DM_LIST_HEAD_INIT(_free_vg.tags),
        };
 
@@ -256,6 +257,7 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
                .tags = DM_LIST_HEAD_INIT(_free_logical_volume.tags),
                .segments = DM_LIST_HEAD_INIT(_free_logical_volume.segments),
                .segs_using_this_lv = DM_LIST_HEAD_INIT(_free_logical_volume.segs_using_this_lv),
+               .indirect_glvs = DM_LIST_HEAD_INIT(_free_logical_volume.indirect_glvs),
                .snapshot_segs = DM_LIST_HEAD_INIT(_free_logical_volume.snapshot_segs),
        };
 
This page took 0.058149 seconds and 5 git commands to generate.