]> sourceware.org Git - lvm2.git/commitdiff
Add experimental code for activation of thinp targets
authorZdenek Kabelac <zkabelac@redhat.com>
Thu, 29 Sep 2011 08:56:38 +0000 (08:56 +0000)
committerZdenek Kabelac <zkabelac@redhat.com>
Thu, 29 Sep 2011 08:56:38 +0000 (08:56 +0000)
No dm messages yes - just a base functionality in the steps of other targets.
For now usable only for debugging and tracing.

lib/activate/dev_manager.c
lib/metadata/lv_manip.c
lib/metadata/merge.c
lib/metadata/metadata-exported.h
lib/thin/thin.c

index b364d9197088bdfb8bec2ceb4cc04fd18b993440..ef0c59b5d65ced0dc04ac1e0ec3accacc5204556 100644 (file)
@@ -1485,7 +1485,13 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
        } else if (lv_is_cow(seg->lv) && !layer) {
                if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, laopts, "cow"))
                        return_0;
+       } else if (lv_is_thin_volume(seg->lv)) {
+               if (!_add_new_lv_to_dtree(dm, dtree, seg->pool_lv, laopts, NULL))
+                       return_0;
        } else {
+               if (lv_is_thin_pool(seg->lv) &&
+                   !_add_new_lv_to_dtree(dm, dtree, seg->pool_metadata_lv, laopts, NULL))
+                       return_0;
                /* Add any LVs used by this segment */
                for (s = 0; s < seg->area_count; s++) {
                        if ((seg_type(seg, s) == AREA_LV) &&
index 85241e7de1ee477c92ed679f6633118cca137436..b3b9e83fc8828f90884716a0cc59af7e4934874d 100644 (file)
@@ -2602,9 +2602,17 @@ int lv_extend(struct logical_volume *lv,
                r = _lv_extend_layered_lv(ah, lv, extents, 0,
                                          stripes, stripe_size);
 
-               if (r && segtype_is_thin_pool(segtype))
-                       r = lv_add_segment(ah, ah->area_count, 1, first_seg(lv)->pool_metadata_lv,
-                                          get_segtype_from_string(lv->vg->cmd, "striped"), 0, 0, 0);
+               if (r && segtype_is_thin_pool(segtype)) {
+                       /* FIXME: resize metadata size here for now */
+                       struct logical_volume *tmeta = first_seg(lv)->pool_metadata_lv;
+                       if ((r = lv_add_segment(ah, ah->area_count, 1, tmeta,
+                                               get_segtype_from_string(lv->vg->cmd, "striped"), 0, 0, 0))) {
+                               if (!(r = lv_extend(tmeta, first_seg(tmeta)->segtype,
+                                                   1, 0, 1, 0, 10, NULL, allocatable_pvs, ALLOC_INHERIT)))
+                                       stack;
+                       } else
+                               stack;
+               }
        }
        alloc_destroy(ah);
        return r;
@@ -4106,6 +4114,13 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, struct l
        if (seg_is_thin_pool(lp) && lp->zero)
                first_seg(lv)->zero_new_blocks = 1;
 
+       if (seg_is_thin_pool(lp)) {
+               /* FIXME: add lvcreate params - maybe -c/--chunksize?,
+                * use lowwatermark  via lvm.conf global for all thinpools ?*/
+               first_seg(lv)->data_block_size = 128;
+               first_seg(lv)->low_water_mark = 4096;
+       }
+
        if (lp->log_count &&
            !seg_is_raid(first_seg(lv)) && seg_is_mirrored(first_seg(lv))) {
                if (!add_mirror_log(cmd, lv, lp->log_count,
index d89eb12c2ec5f7c67e12a7a7fb0d2b5d776227b7..97399815906a94c151d09a571ef3101b4deb3f2e 100644 (file)
@@ -201,6 +201,12 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
                                                  lv->name, seg_count);
                                        inc_error_count;
                                }
+
+                               if (seg->data_block_size < 128 || seg->data_block_size > 2097152) {
+                                       log_error("LV %s: thin pool segment %u  data block size %d is out of range",
+                                                 lv->name, seg_count, seg->data_block_size);
+                                       inc_error_count;
+                               }
                        } else {
                                if (seg->pool_metadata_lv) {
                                        log_error("LV %s: segment %u must not have thin pool metadata LV set",
@@ -231,6 +237,12 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
                                                  lv->name, seg_count);
                                        inc_error_count;
                                }
+
+                               if (seg->device_id >= (1 << 24)) {
+                                       log_error("LV %s: thin volume segment %u pool LV to large device id %d",
+                                                 lv->name, seg_count, seg->device_id);
+                                       inc_error_count;
+                               }
                        } else {
                                if (seg->pool_lv) {
                                        log_error("LV %s: segment %u must not have thin pool LV set",
index fe51e73a8dd1d7f8d7e5111f7ecd73b0ef0abcfe..97e738128601315d7eb916dfcdf2253a5dbe1da9 100644 (file)
@@ -335,9 +335,11 @@ struct lv_segment {
        struct lv_segment_area *meta_areas;     /* For RAID */
        struct logical_volume *pool_metadata_lv;/* For thin_pool */
        uint64_t transaction_id;                /* For thin_pool */
-       uint32_t zero_new_blocks;               /* For thin_pool */
+       uint64_t low_water_mark;                /* For thin_pool */
+       uint32_t data_block_size;               /* For thin_pool, 128..2097152 */
+       unsigned zero_new_blocks;               /* For thin_pool */
        struct logical_volume *pool_lv;         /* For thin */
-       uint64_t device_id;                     /* For thin */
+       uint32_t device_id;                     /* For thin, 24bit */
 
        struct logical_volume *replicator;/* For replicator-devs - link to replicator LV */
        struct logical_volume *rlog_lv; /* For replicators */
index 33d5f08d229a832567ab8a1be741f02b562322d2..8d6f474df7f8938270ad362a1070286d485e43f9 100644 (file)
@@ -70,6 +70,12 @@ static int _thin_pool_text_import(struct lv_segment *seg, const struct dm_config
        if (!dm_config_get_uint64(sn, "transaction_id", &seg->transaction_id))
                return SEG_LOG_ERROR("Could not read transaction_id for");
 
+       if (!dm_config_get_uint64(sn, "low_water_mark", &seg->low_water_mark))
+               return SEG_LOG_ERROR("Could not read low_water_mark");
+
+       if (!dm_config_get_uint32(sn, "data_block_size", &seg->data_block_size))
+               return SEG_LOG_ERROR("Could not read data_block_size");
+
        if (dm_config_has_node(sn, "zero_new_blocks") &&
            !dm_config_get_uint32(sn, "zero_new_blocks", &seg->zero_new_blocks))
                return SEG_LOG_ERROR("Could not read zero_new_blocks for");
@@ -92,12 +98,45 @@ static int _thin_pool_text_export(const struct lv_segment *seg, struct formatter
        outf(f, "pool = \"%s\"", seg_lv(seg, 0)->name);
        outf(f, "metadata = \"%s\"", seg->pool_metadata_lv->name);
        outf(f, "transaction_id = %" PRIu64, seg->transaction_id);
+       outf(f, "low_water_mark = %" PRIu64, seg->low_water_mark);
+       outf(f, "data_block_size = %d", seg->data_block_size);
        if (seg->zero_new_blocks)
                outf(f, "zero_new_blocks = 1");
 
        return 1;
 }
 
+#ifdef DEVMAPPER_SUPPORT
+static int _thin_pool_add_target_line(struct dev_manager *dm,
+                                struct dm_pool *mem __attribute__((unused)),
+                                struct cmd_context *cmd __attribute__((unused)),
+                                void **target_state __attribute__((unused)),
+                                struct lv_segment *seg,
+                                const struct lv_activate_opts *laopts __attribute__((unused)),
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count __attribute__((unused)))
+{
+       char *metadata_dlid, *pool_dlid;
+
+       if (!(metadata_dlid = build_dm_uuid(mem, seg->pool_metadata_lv->lvid.s, NULL))) {
+               log_error("Failed to build uuid for metadata LV %s.", seg->pool_metadata_lv->name);
+               return 0;
+       }
+
+       if (!(pool_dlid = build_dm_uuid(mem, seg_lv(seg, 0)->lvid.s, NULL))) {
+               log_error("Failed to build uuid for pool LV %s.", seg_lv(seg, 0)->name);
+               return 0;
+       }
+
+       if (!dm_tree_node_add_thin_pool_target(node, len, 0, metadata_dlid, pool_dlid,
+                                              seg->data_block_size, seg->low_water_mark,
+                                              seg->zero_new_blocks ? 0 : 1))
+               return_0;
+
+       return 1;
+}
+#endif
+
 static const char *_thin_name(const struct lv_segment *seg)
 {
        return seg->segtype->name;
@@ -126,7 +165,7 @@ static int _thin_text_import(struct lv_segment *seg, const struct dm_config_node
                        return SEG_LOG_ERROR("Unknown origin %s in", lv_name);
        }
 
-       if (!dm_config_get_uint64(sn, "device_id", &seg->device_id))
+       if (!dm_config_get_uint32(sn, "device_id", &seg->device_id))
                return SEG_LOG_ERROR("Could not read device_id for");
 
        return 1;
@@ -135,7 +174,7 @@ static int _thin_text_import(struct lv_segment *seg, const struct dm_config_node
 static int _thin_text_export(const struct lv_segment *seg, struct formatter *f)
 {
        outf(f, "thin_pool = \"%s\"", seg->pool_lv->name);
-       outf(f, "device_id = %" PRIu64, seg->device_id);
+       outf(f, "device_id = %d", seg->device_id);
 
        if (seg->origin)
                outf(f, "origin = \"%s\"", seg->origin->name);
@@ -144,6 +183,28 @@ static int _thin_text_export(const struct lv_segment *seg, struct formatter *f)
 }
 
 #ifdef DEVMAPPER_SUPPORT
+static int _thin_add_target_line(struct dev_manager *dm,
+                                struct dm_pool *mem __attribute__((unused)),
+                                struct cmd_context *cmd __attribute__((unused)),
+                                void **target_state __attribute__((unused)),
+                                struct lv_segment *seg,
+                                const struct lv_activate_opts *laopts __attribute__((unused)),
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count __attribute__((unused)))
+{
+       char *thin_pool_dlid;
+
+       if (!(thin_pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, NULL))) {
+               log_error("Failed to build uuid for thin pool LV %s.", seg->pool_lv->name);
+               return 0;
+       }
+
+       if (!dm_tree_node_add_thin_target(node, len, 0, thin_pool_dlid, seg->device_id))
+               return_0;
+
+       return 1;
+}
+
 static int _thin_target_percent(void **target_state __attribute__((unused)),
                                percent_t *percent,
                                struct dm_pool *mem __attribute__((unused)),
@@ -194,6 +255,10 @@ static struct segtype_handler _thin_pool_ops = {
        .text_import = _thin_pool_text_import,
        .text_import_area_count = _thin_pool_text_import_area_count,
        .text_export = _thin_pool_text_export,
+#ifdef DEVMAPPER_SUPPORT
+       .add_target_line = _thin_pool_add_target_line,
+       .target_present = _thin_target_present,
+#endif
        .modules_needed = _thin_modules_needed,
        .destroy = _thin_destroy,
 };
@@ -203,6 +268,7 @@ static struct segtype_handler _thin_ops = {
        .text_import = _thin_text_import,
        .text_export = _thin_text_export,
 #ifdef DEVMAPPER_SUPPORT
+       .add_target_line = _thin_add_target_line,
        .target_percent = _thin_target_percent,
        .target_present = _thin_target_present,
 #endif
This page took 0.053952 seconds and 5 git commands to generate.