master - pool: callback handle cache
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c0c1ada88eef8e...
Commit: c0c1ada88eef8e112515f5415dc4dd89b4191214
Parent: 120bd2d6b13fb7a297ff6cfc9fe59c0b241ab46f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:24:34 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:45 2014 +0200
pool: callback handle cache
Extend the callback functionality to handle also cache pools.
cache_check is now executed on cachepool metadata when
it's activated and deactivated.
---
lib/activate/dev_manager.c | 172 +++++++++++++++++++++++++++++---------------
1 files changed, 114 insertions(+), 58 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 0305bb4..d5fe620 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1703,114 +1703,153 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
return 1;
}
-struct thin_cb_data {
- const struct logical_volume *pool_lv;
+struct pool_cb_data {
struct dev_manager *dm;
+ const struct logical_volume *pool_lv;
+
+ int skip_zero; /* to skip zeroed device header (check first 64B) */
+ int exec; /* which binary to call */
+ int opts;
+ const char *defaults;
+ const char *global;
};
-static int _thin_pool_callback(struct dm_tree_node *node,
- dm_node_callback_t type, void *cb_data)
+static int _pool_callback(struct dm_tree_node *node,
+ dm_node_callback_t type, void *cb_data)
{
- int ret, status;
- const struct thin_cb_data *data = cb_data;
- const char *dmdir = dm_dir();
+ int ret, status, fd;
+ char *split;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
- const char *thin_check =
- find_config_tree_str_allow_empty(data->pool_lv->vg->cmd, global_thin_check_executable_CFG, NULL);
- const struct logical_volume *mlv = first_seg(data->pool_lv)->metadata_lv;
- size_t len = strlen(dmdir) + 2 * (strlen(mlv->vg->name) + strlen(mlv->name)) + 3;
- char meta_path[len];
+ const struct pool_cb_data *data = cb_data;
+ const struct logical_volume *pool_lv = data->pool_lv;
+ const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
+ long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
int args = 0;
- const char *argv[19]; /* Max supported 15 args */
- char *split, *dm_name;
+ const char *argv[19] = { /* Max supported 15 args */
+ find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL) /* argv[0] */
+ };
- if (!thin_check[0])
+ if (!*argv[0])
return 1; /* Checking disabled */
- if (!(dm_name = dm_build_dm_name(data->dm->mem, mlv->vg->name,
- mlv->name, NULL)) ||
- (dm_snprintf(meta_path, len, "%s/%s", dmdir, dm_name) < 0)) {
- log_error("Failed to build thin metadata path.");
- return 0;
- }
-
- if ((cn = find_config_tree_node(mlv->vg->cmd, global_thin_check_options_CFG, NULL))) {
+ if ((cn = find_config_tree_node(mlv->vg->cmd, data->opts, NULL))) {
for (cv = cn->v; cv && args < 16; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
- "global/thin_check_options");
+ "global/%s_check_options",
+ data->global);
return 0;
}
argv[++args] = cv->v.str;
}
} else {
/* Use default options (no support for options with spaces) */
- if (!(split = dm_pool_strdup(data->dm->mem, DEFAULT_THIN_CHECK_OPTIONS))) {
- log_error("Failed to duplicate thin check string.");
+ if (!(split = dm_pool_strdup(data->dm->mem, data->defaults))) {
+ log_error("Failed to duplicate defaults.");
return 0;
}
args = dm_split_words(split, 16, 0, (char**) argv + 1);
}
if (args == 16) {
- log_error("Too many options for thin check command.");
+ log_error("Too many options for %s command.", argv[0]);
return 0;
}
- argv[0] = thin_check;
- argv[++args] = meta_path;
- argv[++args] = NULL;
+ if (!(argv[++args] = lv_dmpath_dup(data->dm->mem, mlv))) {
+ log_error("Failed to build pool metadata path.");
+ return 0;
+ }
- if (!(ret = exec_cmd(data->pool_lv->vg->cmd, (const char * const *)argv,
+ if (data->skip_zero) {
+ if ((fd = open(argv[args], O_RDONLY)) < 0) {
+ log_sys_error("open", argv[args]);
+ return 0;
+ }
+ /* let's assume there is no problem to read 64 bytes */
+ if (read(fd, buf, sizeof(buf)) < sizeof(buf)) {
+ log_sys_error("read", argv[args]);
+ return 0;
+ }
+ for (ret = 0; ret < DM_ARRAY_SIZE(buf); ++ret)
+ if (buf[ret])
+ break;
+
+ if (close(fd))
+ log_sys_error("close", argv[args]);
+
+ if (ret == DM_ARRAY_SIZE(buf)) {
+ log_debug("%s skipped, detect empty disk header on %s.",
+ argv[0], argv[args]);
+ return 1;
+ }
+ }
+
+ if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv,
&status, 0))) {
switch (type) {
case DM_NODE_CALLBACK_PRELOADED:
- log_err_once("Check of thin pool %s/%s failed (status:%d). "
- "Manual repair required (thin_dump --repair %s)!",
- data->pool_lv->vg->name, data->pool_lv->name,
- status, meta_path);
+ log_err_once("Check of pool %s failed (status:%d). "
+ "Manual repair required!",
+ display_lvname(pool_lv), status);
break;
default:
- log_warn("WARNING: Integrity check of metadata for thin pool "
- "%s/%s failed.",
- data->pool_lv->vg->name, data->pool_lv->name);
+ log_warn("WARNING: Integrity check of metadata for pool "
+ "%s failed.", display_lvname(pool_lv));
}
/*
* FIXME: What should we do here??
*
* Maybe mark the node, so it's not activating
- * as thin_pool but as error/linear and let the
+ * as pool but as error/linear and let the
* dm tree resolve the issue.
*/
}
- dm_pool_free(data->dm->mem, dm_name);
-
return ret;
}
-static int _thin_pool_register_callback(struct dev_manager *dm,
- struct dm_tree_node *node,
- const struct logical_volume *lv)
+static int _pool_register_callback(struct dev_manager *dm,
+ struct dm_tree_node *node,
+ const struct logical_volume *lv)
{
- struct thin_cb_data *data;
+ struct pool_cb_data *data;
- /* Skip metadata testing for unused pool. */
- if (!first_seg(lv)->transaction_id ||
- ((first_seg(lv)->transaction_id == 1) &&
- pool_has_message(first_seg(lv), NULL, 0)))
+ /* Skip metadata testing for unused thin pool. */
+ if (lv_is_thin_pool(lv) &&
+ (!first_seg(lv)->transaction_id ||
+ ((first_seg(lv)->transaction_id == 1) &&
+ pool_has_message(first_seg(lv), NULL, 0))))
return 1;
- if (!(data = dm_pool_alloc(dm->mem, sizeof(*data)))) {
+ if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) {
log_error("Failed to allocated path for callback.");
return 0;
}
data->dm = dm;
- data->pool_lv = lv;
- dm_tree_node_set_callback(node, _thin_pool_callback, data);
+ if (lv_is_thin_pool(lv)) {
+ data->pool_lv = lv;
+ data->skip_zero = 1;
+ data->exec = global_thin_check_executable_CFG;
+ data->opts = global_thin_check_options_CFG;
+ data->defaults = DEFAULT_THIN_CHECK_OPTIONS;
+ data->global = "thin";
+ } else if (lv_is_cache(lv)) { /* cache pool */
+ data->pool_lv = first_seg(lv)->pool_lv;
+ data->skip_zero = dm->activation;
+ data->exec = global_cache_check_executable_CFG;
+ data->opts = global_cache_check_options_CFG;
+ data->defaults = DEFAULT_CACHE_CHECK_OPTIONS;
+ data->global = "cache";
+ } else {
+ log_error(INTERNAL_ERROR "Registering unsupported pool callback.");
+ return 0;
+ }
+
+ dm_tree_node_set_callback(node, _pool_callback, data);
return 1;
}
@@ -1825,7 +1864,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
struct seg_list *sl;
struct dm_list *snh;
struct lv_segment *seg;
- struct dm_tree_node *thin_node;
+ struct dm_tree_node *node;
const char *uuid;
if (lv_is_cache_pool(lv)) {
@@ -1857,8 +1896,8 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* FIXME Implement dm_tree_node_skip_childrens optimisation */
if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)))
- dm_tree_node_skip_childrens(thin_node, 1);
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)))
+ dm_tree_node_skip_childrens(node, 1);
#endif
}
@@ -1887,8 +1926,21 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* TODO: extend _cached_info() to return dnode */
if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
- !_thin_pool_register_callback(dm, thin_node, lv))
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
+ !_pool_register_callback(dm, node, lv))
+ return_0;
+ }
+ }
+
+ if (!origin_only && lv_is_cache(lv)) {
+ if (!dm->activation) {
+ /* Setup callback for non-activation partial tree */
+ /* Activation gets own callback when needed */
+ /* TODO: extend _cached_info() to return dnode */
+ if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
+ return_0;
+ if ((node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
+ !_pool_register_callback(dm, node, lv))
return_0;
}
}
@@ -2633,7 +2685,11 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
/* Setup thin pool callback */
if (lv_is_thin_pool(lv) && layer &&
- !_thin_pool_register_callback(dm, dnode, lv))
+ !_pool_register_callback(dm, dnode, lv))
+ return_0;
+
+ if (lv_is_cache(lv) &&
+ !_pool_register_callback(dm, dnode, lv))
return_0;
if (read_ahead == DM_READ_AHEAD_AUTO) {
9 years, 9 months
master - pool: move code to pool source file
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=120bd2d6b13fb7...
Commit: 120bd2d6b13fb7a297ff6cfc9fe59c0b241ab46f
Parent: 4db5d78cefa99c053ba1f0bf73aa0eb55cafb279
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Jul 8 15:19:47 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:57:25 2014 +0200
pool: move code to pool source file
More code is used commonly for all pool types (cache & thin)
---
lib/metadata/pool_manip.c | 233 +++++++++++++++++++++++++++++++++++++++++++++
lib/metadata/thin_manip.c | 230 --------------------------------------------
2 files changed, 233 insertions(+), 230 deletions(-)
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index ab52ff1..e32b109 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -23,6 +23,7 @@
#include "segtype.h"
#include "lv_alloc.h"
#include "defaults.h"
+#include "display.h"
int attach_pool_metadata_lv(struct lv_segment *pool_seg,
struct logical_volume *metadata_lv)
@@ -41,6 +42,26 @@ int attach_pool_metadata_lv(struct lv_segment *pool_seg,
return add_seg_to_segs_using_this_lv(metadata_lv, pool_seg);
}
+int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv)
+{
+ struct logical_volume *lv = pool_seg->metadata_lv;
+
+ if (!lv ||
+ !lv_is_pool_metadata(lv) ||
+ !remove_seg_from_segs_using_this_lv(lv, pool_seg)) {
+ log_error(INTERNAL_ERROR "Logical volume %s is not valid pool.",
+ display_lvname(pool_seg->lv));
+ return 0;
+ }
+
+ lv_set_visible(lv);
+ lv->status &= ~(THIN_POOL_METADATA | CACHE_POOL_METADATA);
+ *metadata_lv = lv;
+ pool_seg->metadata_lv = NULL;
+
+ return 1;
+}
+
int attach_pool_data_lv(struct lv_segment *pool_seg,
struct logical_volume *pool_data_lv)
{
@@ -326,3 +347,215 @@ bad:
return 0;
}
+
+struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
+ const char *name, uint32_t read_ahead,
+ uint32_t stripes, uint32_t stripe_size,
+ uint64_t size, alloc_policy_t alloc,
+ struct dm_list *pvh)
+{
+ struct logical_volume *metadata_lv;
+ /* FIXME: Make lvm2api usable */
+ struct lvcreate_params lvc = {
+ .activate = CHANGE_ALY,
+ .alloc = alloc,
+ .major = -1,
+ .minor = -1,
+ .permission = LVM_READ | LVM_WRITE,
+ .pvh = pvh,
+ .read_ahead = read_ahead,
+ .stripe_size = stripe_size,
+ .stripes = stripes,
+ .zero = 1,
+ };
+
+ dm_list_init(&lvc.tags);
+
+ if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
+ pool_lv->vg->extent_size)))
+ return_0;
+
+ if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
+ return_0;
+
+ /* FIXME: allocate properly space for metadata_lv */
+
+ if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc)))
+ return_0;
+
+ if (!lv_rename_update(pool_lv->vg->cmd, metadata_lv, name, 0))
+ return_0;
+
+ return metadata_lv;
+}
+
+static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg,
+ uint32_t extents,
+ struct dm_list *pvh)
+{
+ struct logical_volume *lv;
+
+ /* FIXME: Make lvm2api usable */
+ struct lvcreate_params lp = {
+ .activate = CHANGE_ALY,
+ .alloc = ALLOC_INHERIT,
+ .extents = extents,
+ .major = -1,
+ .minor = -1,
+ .permission = LVM_READ | LVM_WRITE,
+ .pvh = pvh ? : &vg->pvs,
+ .read_ahead = DM_READ_AHEAD_AUTO,
+ .stripes = 1,
+ .zero = 1,
+ .temporary = 1,
+ };
+
+ dm_list_init(&lp.tags);
+
+ if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
+ return_0;
+
+ /* FIXME: Maybe using silent mode ? */
+ if (!(lv = lv_create_single(vg, &lp)))
+ return_0;
+
+ /* Spare LV should not be active */
+ if (!deactivate_lv_local(vg->cmd, lv)) {
+ log_error("Unable to deactivate pool metadata spare LV. "
+ "Manual intervention required.");
+ return 0;
+ }
+
+ if (!vg_set_pool_metadata_spare(lv))
+ return_0;
+
+ return lv;
+}
+
+/*
+ * Create/resize pool metadata spare LV
+ * Caller does vg_write(), vg_commit() with pool creation
+ * extents is 0, max size is determined
+ */
+int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
+ struct dm_list *pvh, int poolmetadataspare)
+{
+ struct logical_volume *lv = vg->pool_metadata_spare_lv;
+ uint32_t seg_mirrors;
+ struct lv_segment *seg;
+ const struct lv_list *lvl;
+
+ if (!extents)
+ /* Find maximal size of metadata LV */
+ dm_list_iterate_items(lvl, &vg->lvs)
+ if (lv_is_pool_metadata(lvl->lv) &&
+ (lvl->lv->le_count > extents))
+ extents = lvl->lv->le_count;
+
+ if (!poolmetadataspare) {
+ /* TODO: Not showing when lvm.conf would define 'n' ? */
+ if (DEFAULT_POOL_METADATA_SPARE && extents)
+ /* Warn if there would be any user */
+ log_warn("WARNING: recovery of pools without pool "
+ "metadata spare LV is not automated.");
+ return 1;
+ }
+
+ if (!lv) {
+ if (!_alloc_pool_metadata_spare(vg, extents, pvh))
+ return_0;
+
+ return 1;
+ }
+
+ seg = last_seg(lv);
+ seg_mirrors = lv_mirror_count(lv);
+
+ /* Check spare LV is big enough and preserve segtype */
+ if ((lv->le_count < extents) && seg &&
+ !lv_extend(lv, seg->segtype,
+ seg->area_count / seg_mirrors,
+ seg->stripe_size,
+ seg_mirrors,
+ seg->region_size,
+ extents - lv->le_count, NULL,
+ pvh, lv->alloc, 0))
+ return_0;
+
+ return 1;
+}
+
+int vg_set_pool_metadata_spare(struct logical_volume *lv)
+{
+ char new_name[NAME_LEN];
+ struct volume_group *vg = lv->vg;
+
+ if (vg->pool_metadata_spare_lv) {
+ if (vg->pool_metadata_spare_lv == lv)
+ return 1;
+ if (!vg_remove_pool_metadata_spare(vg))
+ return_0;
+ }
+
+ if (dm_snprintf(new_name, sizeof(new_name), "%s_pmspare", lv->name) < 0) {
+ log_error("Can't create pool metadata spare. Name of pool LV "
+ "%s is too long.", lv->name);
+ return 0;
+ }
+
+ if (!lv_rename_update(vg->cmd, lv, new_name, 0))
+ return_0;
+
+ lv_set_hidden(lv);
+ lv->status |= POOL_METADATA_SPARE;
+ vg->pool_metadata_spare_lv = lv;
+
+ return 1;
+}
+
+int vg_remove_pool_metadata_spare(struct volume_group *vg)
+{
+ char new_name[NAME_LEN];
+ char *c;
+
+ struct logical_volume *lv = vg->pool_metadata_spare_lv;
+
+ if (!(lv->status & POOL_METADATA_SPARE)) {
+ log_error(INTERNAL_ERROR "LV %s is not pool metadata spare.",
+ lv->name);
+ return 0;
+ }
+
+ vg->pool_metadata_spare_lv = NULL;
+ lv->status &= ~POOL_METADATA_SPARE;
+ lv_set_visible(lv);
+
+ /* Cut off suffix _pmspare */
+ (void) dm_strncpy(new_name, lv->name, sizeof(new_name));
+ if (!(c = strchr(new_name, '_'))) {
+ log_error(INTERNAL_ERROR "LV %s has no suffix for pool metadata spare.",
+ new_name);
+ return 0;
+ }
+ *c = 0;
+
+ /* If the name is in use, generate new lvol%d */
+ if (find_lv_in_vg(vg, new_name) &&
+ !generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
+ log_error("Failed to generate unique name for "
+ "pool metadata spare logical volume.");
+ return 0;
+ }
+
+ log_print_unless_silent("Renaming existing pool metadata spare "
+ "logical volume \"%s/%s\" to \"%s/%s\".",
+ vg->name, lv->name, vg->name, new_name);
+
+ if (!lv_rename_update(vg->cmd, lv, new_name, 0))
+ return_0;
+
+ /* To display default warning */
+ (void) handle_pool_metadata_spare(vg, 0, 0, 0);
+
+ return 1;
+}
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index b2ebaa1..33ab31c 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -20,24 +20,6 @@
#include "defaults.h"
#include "display.h"
-int detach_pool_metadata_lv(struct lv_segment *pool_seg, struct logical_volume **metadata_lv)
-{
- struct logical_volume *lv = pool_seg->metadata_lv;
-
- if (!lv || !lv_is_thin_pool_metadata(lv) ||
- !remove_seg_from_segs_using_this_lv(lv, pool_seg)) {
- log_error(INTERNAL_ERROR "LV %s is invalid thin pool.", pool_seg->lv->name);
- return 0;
- }
-
- lv_set_visible(lv);
- lv->status &= ~THIN_POOL_METADATA;
- *metadata_lv = lv;
- pool_seg->metadata_lv = NULL;
-
- return 1;
-}
-
int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
struct logical_volume *lv, uint32_t delete_id,
int no_update)
@@ -540,215 +522,3 @@ const char *get_pool_discards_name(thin_discards_t discards)
return "unknown";
}
-
-struct logical_volume *alloc_pool_metadata(struct logical_volume *pool_lv,
- const char *name, uint32_t read_ahead,
- uint32_t stripes, uint32_t stripe_size,
- uint64_t size, alloc_policy_t alloc,
- struct dm_list *pvh)
-{
- struct logical_volume *metadata_lv;
- /* FIXME: Make lvm2api usable */
- struct lvcreate_params lvc = {
- .activate = CHANGE_ALY,
- .alloc = alloc,
- .major = -1,
- .minor = -1,
- .permission = LVM_READ | LVM_WRITE,
- .pvh = pvh,
- .read_ahead = read_ahead,
- .stripe_size = stripe_size,
- .stripes = stripes,
- .zero = 1,
- };
-
- dm_list_init(&lvc.tags);
-
- if (!(lvc.extents = extents_from_size(pool_lv->vg->cmd, size,
- pool_lv->vg->extent_size)))
- return_0;
-
- if (!(lvc.segtype = get_segtype_from_string(pool_lv->vg->cmd, "striped")))
- return_0;
-
- /* FIXME: allocate properly space for metadata_lv */
-
- if (!(metadata_lv = lv_create_single(pool_lv->vg, &lvc)))
- return_0;
-
- if (!lv_rename_update(pool_lv->vg->cmd, metadata_lv, name, 0))
- return_0;
-
- return metadata_lv;
-}
-
-static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg,
- uint32_t extents,
- struct dm_list *pvh)
-{
- struct logical_volume *lv;
-
- /* FIXME: Make lvm2api usable */
- struct lvcreate_params lp = {
- .activate = CHANGE_ALY,
- .alloc = ALLOC_INHERIT,
- .extents = extents,
- .major = -1,
- .minor = -1,
- .permission = LVM_READ | LVM_WRITE,
- .pvh = pvh ? : &vg->pvs,
- .read_ahead = DM_READ_AHEAD_AUTO,
- .stripes = 1,
- .zero = 1,
- .temporary = 1,
- };
-
- dm_list_init(&lp.tags);
-
- if (!(lp.segtype = get_segtype_from_string(vg->cmd, "striped")))
- return_0;
-
- /* FIXME: Maybe using silent mode ? */
- if (!(lv = lv_create_single(vg, &lp)))
- return_0;
-
- /* Spare LV should not be active */
- if (!deactivate_lv_local(vg->cmd, lv)) {
- log_error("Unable to deactivate pool metadata spare LV. "
- "Manual intervention required.");
- return 0;
- }
-
- if (!vg_set_pool_metadata_spare(lv))
- return_0;
-
- return lv;
-}
-
-/*
- * Create/resize pool metadata spare LV
- * Caller does vg_write(), vg_commit() with pool creation
- * extents is 0, max size is determined
- */
-int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
- struct dm_list *pvh, int poolmetadataspare)
-{
- struct logical_volume *lv = vg->pool_metadata_spare_lv;
- uint32_t seg_mirrors;
- struct lv_segment *seg;
- const struct lv_list *lvl;
-
- if (!extents)
- /* Find maximal size of metadata LV */
- dm_list_iterate_items(lvl, &vg->lvs)
- if (lv_is_thin_pool_metadata(lvl->lv) &&
- (lvl->lv->le_count > extents))
- extents = lvl->lv->le_count;
-
- if (!poolmetadataspare) {
- /* TODO: Not showing when lvm.conf would define 'n' ? */
- if (DEFAULT_POOL_METADATA_SPARE && extents)
- /* Warn if there would be any user */
- log_warn("WARNING: recovery of pools without pool "
- "metadata spare LV is not automated.");
- return 1;
- }
-
- if (!lv) {
- if (!_alloc_pool_metadata_spare(vg, extents, pvh))
- return_0;
-
- return 1;
- }
-
- seg = last_seg(lv);
- seg_mirrors = lv_mirror_count(lv);
-
- /* Check spare LV is big enough and preserve segtype */
- if ((lv->le_count < extents) && seg &&
- !lv_extend(lv, seg->segtype,
- seg->area_count / seg_mirrors,
- seg->stripe_size,
- seg_mirrors,
- seg->region_size,
- extents - lv->le_count, NULL,
- pvh, lv->alloc, 0))
- return_0;
-
- return 1;
-}
-
-int vg_set_pool_metadata_spare(struct logical_volume *lv)
-{
- char new_name[NAME_LEN];
- struct volume_group *vg = lv->vg;
-
- if (vg->pool_metadata_spare_lv) {
- if (vg->pool_metadata_spare_lv == lv)
- return 1;
- if (!vg_remove_pool_metadata_spare(vg))
- return_0;
- }
-
- if (dm_snprintf(new_name, sizeof(new_name), "%s_pmspare", lv->name) < 0) {
- log_error("Can't create pool metadata spare. Name of pool LV "
- "%s is too long.", lv->name);
- return 0;
- }
-
- if (!lv_rename_update(vg->cmd, lv, new_name, 0))
- return_0;
-
- lv_set_hidden(lv);
- lv->status |= POOL_METADATA_SPARE;
- vg->pool_metadata_spare_lv = lv;
-
- return 1;
-}
-
-int vg_remove_pool_metadata_spare(struct volume_group *vg)
-{
- char new_name[NAME_LEN];
- char *c;
-
- struct logical_volume *lv = vg->pool_metadata_spare_lv;
-
- if (!(lv->status & POOL_METADATA_SPARE)) {
- log_error(INTERNAL_ERROR "LV %s is not pool metadata spare.",
- lv->name);
- return 0;
- }
-
- vg->pool_metadata_spare_lv = NULL;
- lv->status &= ~POOL_METADATA_SPARE;
- lv_set_visible(lv);
-
- /* Cut off suffix _pmspare */
- (void) dm_strncpy(new_name, lv->name, sizeof(new_name));
- if (!(c = strchr(new_name, '_'))) {
- log_error(INTERNAL_ERROR "LV %s has no suffix for pool metadata spare.",
- new_name);
- return 0;
- }
- *c = 0;
-
- /* If the name is in use, generate new lvol%d */
- if (find_lv_in_vg(vg, new_name) &&
- !generate_lv_name(vg, "lvol%d", new_name, sizeof(new_name))) {
- log_error("Failed to generate unique name for "
- "pool metadata spare logical volume.");
- return 0;
- }
-
- log_print_unless_silent("Renaming existing pool metadata spare "
- "logical volume \"%s/%s\" to \"%s/%s\".",
- vg->name, lv->name, vg->name, new_name);
-
- if (!lv_rename_update(vg->cmd, lv, new_name, 0))
- return_0;
-
- /* To display default warning */
- (void) handle_pool_metadata_spare(vg, 0, 0, 0);
-
- return 1;
-}
9 years, 9 months
master - display: show C only for cache and cachepool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4db5d78cefa99c...
Commit: 4db5d78cefa99c053ba1f0bf73aa0eb55cafb279
Parent: ba048612a3dcb9ca35c54f05a006ec458da4164f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:26:56 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:44 2014 +0200
display: show C only for cache and cachepool
Keep target type (attr6) as the cache data and metadata volume has.
(i.e. when will show 'raid' type if metadata is raid)
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7891d76..6cbf221 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index d8fd320..f2c9b12 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -640,14 +640,12 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
/* Origin takes precedence over mirror and thin volume */
else if (lv_is_origin(lv) || lv_is_external_origin(lv))
repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
- else if (lv_is_cache_pool_metadata(lv))
+ else if (lv_is_pool_metadata(lv) ||
+ lv_is_pool_metadata_spare(lv) ||
+ lv_is_raid_metadata(lv))
repstr[0] = 'e';
else if (lv_is_cache_type(lv))
repstr[0] = 'C';
- else if (lv_is_thin_pool_metadata(lv) ||
- lv_is_pool_metadata_spare(lv) ||
- (lv->status & RAID_META))
- repstr[0] = 'e';
else if (lv->status & RAID)
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
else if (lv->status & MIRRORED)
@@ -739,7 +737,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
if (lv_is_thin_pool(lv) || lv_is_thin_volume(lv))
repstr[6] = 't';
- else if (lv_is_cache_type(lv))
+ else if (lv_is_cache_pool(lv) || lv_is_cache(lv))
repstr[6] = 'C';
else if (lv_is_raid_type(lv))
repstr[6] = 'r';
9 years, 9 months
master - lvchange: just skip on cache pool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ba048612a3dcb9...
Commit: ba048612a3dcb9ca35c54f05a006ec458da4164f
Parent: 8932d4a6257cfb842adb43c71d650515ef041ba6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jul 9 17:55:10 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:06 2014 +0200
lvchange: just skip on cache pool
---
tools/lvchange.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 9bd6a88..992efde 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -215,6 +215,9 @@ static int _lvchange_activate(struct cmd_context *cmd, struct logical_volume *lv
activate = (activation_change_t) arg_uint_value(cmd, activate_ARG, CHANGE_AY);
+ if (lv_is_cache_pool(lv))
+ return 1;
+
if (lv_activation_skip(lv, activate, arg_count(cmd, ignoreactivationskip_ARG)))
return 1;
@@ -951,11 +954,6 @@ static int _lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
return EINVALID_CMD_LINE;
}
- if (lv_is_cache_pool(lv)) {
- log_error("Can't change cache pool logical volume.");
- return ECMD_FAILED;
- }
-
if (lv_is_origin(lv) && !lv_is_thin_volume(lv) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
9 years, 9 months
master - lv_is_pool: add new defines
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8932d4a6257cfb...
Commit: 8932d4a6257cfb842adb43c71d650515ef041ba6
Parent: 56c5ad7b194f5b991ae3835abca1c951450f34df
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:14:08 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:50:06 2014 +0200
lv_is_pool: add new defines
Defines for lv_is_pool() and lv_is_pool_metadata()
Also update comments for prompts for their current meaning.
(Though maybe they should be renamed)
---
lib/metadata/metadata-exported.h | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index bfb4651..f2521db 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -187,6 +187,8 @@
#define lv_is_cache_type(lv) (((lv)->status & (CACHE | CACHE_POOL | CACHE_POOL_DATA | CACHE_POOL_METADATA)) ? 1 : 0)
#define lv_is_virtual(lv) (((lv)->status & (VIRTUAL)) ? 1 : 0)
+#define lv_is_pool(lv) (((lv)->status & (CACHE_POOL | THIN_POOL)) ? 1 : 0)
+#define lv_is_pool_metadata(lv) (((lv)->status & (CACHE_POOL_METADATA | THIN_POOL_METADATA)) ? 1 : 0)
#define lv_is_pool_metadata_spare(lv) (((lv)->status & (POOL_METADATA_SPARE)) ? 1 : 0)
/* Ordered list - see lv_manip.c */
@@ -196,13 +198,11 @@ typedef enum {
AREA_LV
} area_type_t;
-/*
- * Whether or not to force an operation.
- */
+/* Whether or not to force an operation */
typedef enum {
PROMPT = 0, /* Issue yes/no prompt to confirm operation */
- DONT_PROMPT = 1, /* Skip yes/no prompt */
- DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
+ DONT_PROMPT = 1, /* Add more prompts */
+ DONT_PROMPT_OVERRIDE = 2 /* Add even more dangerous prompts */
} force_t;
typedef enum {
9 years, 9 months
master - lvconvert: snapshot prompts to confirm conversion
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=56c5ad7b194f5b...
Commit: 56c5ad7b194f5b991ae3835abca1c951450f34df
Parent: 64828d877edbf1907557d76e44eb86d00f7a1f3a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 22:33:31 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:49:55 2014 +0200
lvconvert: snapshot prompts to confirm conversion
Since the type passed LV is changed and content of data detroyed,
query user with prompt to confirm this operation.
Also add a proper wiping of header.
Using '--yes' will skip this prompt:
lvconvert -s --yes vg/lv vg/lvcow
---
WHATS_NEW | 1 +
test/shell/lvconvert-snapshot.sh | 4 +++-
tools/lvconvert.c | 30 +++++++++++++++++++++++++-----
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index dcaaf23..7891d76 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
diff --git a/test/shell/lvconvert-snapshot.sh b/test/shell/lvconvert-snapshot.sh
index f59bb7b..3d81573 100644
--- a/test/shell/lvconvert-snapshot.sh
+++ b/test/shell/lvconvert-snapshot.sh
@@ -25,6 +25,7 @@ lvcreate -L1 -s -n $lv3 $vg/$lv2
lvcreate -l1 -n $lv4 $vg
lvcreate -L1 -n $lv5 $vg
+lvcreate -L1 -n $lv6 $vg
not lvconvert -s $vg/$lv1 $vg/not_exist
@@ -52,6 +53,7 @@ not lvconvert -s $vg/$lv2 $vg/$lv4 2>&1 | tee err
grep "smaller" err
# This should pass
-lvconvert -s $vg/$lv2 $vg/$lv5
+lvconvert --yes -s $vg/$lv2 $vg/$lv5
+lvconvert --yes --type snapshot $vg/$lv2 $vg/$lv6
vgremove -f $vg
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 62a9d4e..264b86c 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2063,11 +2063,14 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
- if (!lp->zero || !(lv->status & LVM_WRITE))
- log_warn("WARNING: \"%s\" not zeroed", lv->name);
- else if (!wipe_lv(lv, (struct wipe_params) { .do_zero = 1 })) {
- log_error("Aborting. Failed to wipe snapshot "
- "exception store.");
+ log_warn("WARNING: Converting logical volume %s to snapshot exception store.",
+ display_lvname(lv));
+ log_warn("THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)");
+
+ if (!lp->yes &&
+ yes_no_prompt("Do you really want to convert %s? [y/n]: ",
+ display_lvname(lv)) == 'n') {
+ log_error("Conversion aborted.");
return 0;
}
@@ -2076,6 +2079,23 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return 0;
}
+ if (!lp->zero || !(lv->status & LVM_WRITE))
+ log_warn("WARNING: \"%s\" not zeroed", lv->name);
+ else {
+ lv->status |= LV_TEMPORARY;
+ if (!activate_lv_local(cmd, lv) ||
+ !wipe_lv(lv, (struct wipe_params) { .do_zero = 1 })) {
+ log_error("Aborting. Failed to wipe snapshot exception store.");
+ return 0;
+ }
+ lv->status &= ~LV_TEMPORARY;
+ /* Deactivates cleared metadata LV */
+ if (!deactivate_lv_local(lv->vg->cmd, lv)) {
+ log_error("Failed to deactivate zeroed snapshot exception store.");
+ return 0;
+ }
+ }
+
if (!archive(lv->vg))
return_0;
9 years, 9 months
master - lvconvert: fix return codes
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=64828d877edbf1...
Commit: 64828d877edbf1907557d76e44eb86d00f7a1f3a
Parent: baf825331cb37fd29007e7ed7596fb3683c8b37d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 11 12:24:32 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:49:02 2014 +0200
lvconvert: fix return codes
Error codes in some function are directly used
as command result - thus return 0 is not error code,
but success - switch to proper ECMD_FAILED.
---
WHATS_NEW | 1 +
tools/lvconvert.c | 16 +++++++++-------
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 77cc2d7..dcaaf23 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2a2a398..62a9d4e 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -894,7 +894,7 @@ int lvconvert_poll(struct cmd_context *cmd, struct logical_volume *lv,
if (dm_snprintf(lv_full_name, sizeof(lv_full_name), "%s/%s", lv->vg->name, lv->name) < 0) {
log_error(INTERNAL_ERROR "Name \"%s/%s\" is too long.", lv->vg->name, lv->name);
- return 0;
+ return ECMD_FAILED;
}
memcpy(uuid, &lv->lvid, sizeof(lv->lvid));
@@ -1995,7 +1995,7 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
if (lv_info(cmd, cow, 0, &info, 1, 0)) {
if (!lv_check_not_in_use(cmd, cow, &info))
- return_0;
+ return_ECMD_FAILED;
if ((lp->force == PROMPT) &&
lv_is_visible(cow) &&
@@ -3047,8 +3047,11 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lp->splitsnapshot)
return _lvconvert_splitsnapshot(cmd, lv, lp);
- if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv))
- return _lvconvert_thinpool_repair(cmd, lv, lp);
+ if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv)) {
+ if (!_lvconvert_thinpool_repair(cmd, lv, lp))
+ return_ECMD_FAILED;
+ return ECMD_PROCESSED;
+ }
if (arg_count(cmd, repair_ARG) &&
!(lv->status & MIRRORED) && !(lv->status & RAID)) {
@@ -3070,9 +3073,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
* to consult the default.
*/
if (arg_count(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) {
- lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL));
- if (!lp->segtype)
- return_0;
+ if (!(lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL))))
+ return_ECMD_FAILED;
}
}
if (lp->merge) {
9 years, 9 months
master - prompt: display 'n' for EOF
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=baf825331cb37f...
Commit: baf825331cb37fd29007e7ed7596fb3683c8b37d
Parent: 39cb8aa3abd4e3eea7bbbdcc24225e8475c3aff3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 7 21:03:15 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:41 2014 +0200
prompt: display 'n' for EOF
When EOF is detect - it could be either 'Ctrl+C'
or empty stdin.
For Ctrl+C there is visual ^C sign.
For EOF print 'n' so decision is clear in debug print.
---
lib/display/display.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib/display/display.c b/lib/display/display.c
index cd204a0..cfd83c9 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -883,7 +883,7 @@ void display_name_error(name_error_t name_error)
*/
char yes_no_prompt(const char *prompt, ...)
{
- int c = 0, ret = 0;
+ int c = 0, ret = 0, cb = 0;
va_list ap;
sigint_allow();
@@ -903,6 +903,7 @@ char yes_no_prompt(const char *prompt, ...)
if ((c = getchar()) == EOF) {
ret = 'n'; /* SIGINT */
+ cb = 1;
break;
}
@@ -918,6 +919,9 @@ char yes_no_prompt(const char *prompt, ...)
sigint_restore();
+ if (cb && !sigint_caught())
+ fputc(ret, stderr);
+
if (c != '\n')
fputc('\n', stderr);
9 years, 9 months
master - configure
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=39cb8aa3abd4e3...
Commit: 39cb8aa3abd4e3eea7bbbdcc24225e8475c3aff3
Parent: f9d80c9d31d7113ab8bc08baf6bba96a7449261f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 4 16:31:05 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:41 2014 +0200
configure
---
configure | 521 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 517 insertions(+), 4 deletions(-)
diff --git a/configure b/configure
index dec82de..40ab256 100755
--- a/configure
+++ b/configure
@@ -768,6 +768,10 @@ PKGCONFIGINIT_CFLAGS
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
+CACHE_RESTORE_CMD
+CACHE_REPAIR_CMD
+CACHE_DUMP_CMD
+CACHE_CHECK_CMD
THIN_RESTORE_CMD
THIN_REPAIR_CMD
THIN_DUMP_CMD
@@ -874,6 +878,10 @@ with_thin_repair
with_thin_restore
enable_thin_check_needs_check
with_cache
+with_cache_check
+with_cache_dump
+with_cache_repair
+with_cache_restore
enable_readline
enable_realtime
enable_ocf
@@ -1661,6 +1669,12 @@ Optional Packages:
--with-thin-restore=PATH
thin_restore tool: [[autodetect]]
--with-cache=TYPE cache support: internal/shared/none [[TYPE=none]]
+ --with-cache-check=PATH cache_check tool: [[autodetect]]
+ --with-cache-dump=PATH cache_dump tool: [[autodetect]]
+ --with-cache-repair=PATH
+ cache_repair tool: [[autodetect]]
+ --with-cache-restore=PATH
+ cache_restore tool: [[autodetect]]
--with-ocfdir=DIR install OCF files in DIR
[[PREFIX/lib/ocf/resource.d/lvm2]]
--with-default-pid-dir=PID_DIR
@@ -7450,7 +7464,7 @@ $as_echo "$as_me: WARNING: $THIN_CHECK_CMD: Old version \"$THIN_CHECK_VSN\" foun
THIN_CHECK_NEEDS_CHECK=no
fi
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin dumping
if test "$THIN_DUMP_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_dump", so it can be a program name with args.
@@ -7557,7 +7571,7 @@ $as_echo "$as_me: WARNING: thin_dump not found in path $PATH" >&2;}
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin repairing
if test "$THIN_REPAIR_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_repair", so it can be a program name with args.
@@ -7664,7 +7678,7 @@ $as_echo "$as_me: WARNING: thin_repair not found in path $PATH" >&2;}
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin restoring
if test "$THIN_RESTORE_CMD" = "autodetect"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}thin_restore", so it can be a program name with args.
@@ -7816,7 +7830,39 @@ $as_echo_n "checking whether to include cache... " >&6; }
if test "${with_cache+set}" = set; then :
withval=$with_cache; CACHE=$withval
else
- CACHE=none
+ CACHE="none"
+fi
+
+
+# Check whether --with-cache-check was given.
+if test "${with_cache_check+set}" = set; then :
+ withval=$with_cache_check; CACHE_CHECK_CMD=$withval
+else
+ CACHE_CHECK_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-dump was given.
+if test "${with_cache_dump+set}" = set; then :
+ withval=$with_cache_dump; CACHE_DUMP_CMD=$withval
+else
+ CACHE_DUMP_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-repair was given.
+if test "${with_cache_repair+set}" = set; then :
+ withval=$with_cache_repair; CACHE_REPAIR_CMD=$withval
+else
+ CACHE_REPAIR_CMD="autodetect"
+fi
+
+
+# Check whether --with-cache-restore was given.
+if test "${with_cache_restore+set}" = set; then :
+ withval=$with_cache_restore; CACHE_RESTORE_CMD=$withval
+else
+ CACHE_RESTORE_CMD="autodetect"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE" >&5
@@ -7830,6 +7876,466 @@ $as_echo "#define CACHE_INTERNAL 1" >>confdefs.h
*) as_fn_error $? "--with-cache parameter invalid" "$LINENO" 5 ;;
esac
+# Test if necessary cache tools are available
+# if not - use plain defaults and warn user
+case "$CACHE" in
+ internal|shared)
+ # Empty means a config way to ignore cache checking
+ if test "$CACHE_CHECK_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_check", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_CHECK_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_CHECK_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_CHECK_CMD="$CACHE_CHECK_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_CHECK_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_CHECK_CMD=$ac_cv_path_CACHE_CHECK_CMD
+if test -n "$CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_CHECK_CMD" >&5
+$as_echo "$CACHE_CHECK_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_CHECK_CMD"; then
+ ac_pt_CACHE_CHECK_CMD=$CACHE_CHECK_CMD
+ # Extract the first word of "cache_check", so it can be a program name with args.
+set dummy cache_check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_CHECK_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_CHECK_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_CHECK_CMD="$ac_pt_CACHE_CHECK_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_CHECK_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_CHECK_CMD=$ac_cv_path_ac_pt_CACHE_CHECK_CMD
+if test -n "$ac_pt_CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_CHECK_CMD" >&5
+$as_echo "$ac_pt_CACHE_CHECK_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_CHECK_CMD" = x; then
+ CACHE_CHECK_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_CHECK_CMD=$ac_pt_CACHE_CHECK_CMD
+ fi
+else
+ CACHE_CHECK_CMD="$ac_cv_path_CACHE_CHECK_CMD"
+fi
+
+ if test -z "$CACHE_CHECK_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_check not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_check not found in path $PATH" >&2;}
+ CACHE_CHECK_CMD=/usr/sbin/cache_check
+ CACHE_CONFIGURE_WARN=y
+ fi
+ fi
+ # Empty means a config way to ignore cache dumping
+ if test "$CACHE_DUMP_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_dump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_dump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_DUMP_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_DUMP_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_DUMP_CMD="$CACHE_DUMP_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_DUMP_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_DUMP_CMD=$ac_cv_path_CACHE_DUMP_CMD
+if test -n "$CACHE_DUMP_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_DUMP_CMD" >&5
+$as_echo "$CACHE_DUMP_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_DUMP_CMD"; then
+ ac_pt_CACHE_DUMP_CMD=$CACHE_DUMP_CMD
+ # Extract the first word of "cache_dump", so it can be a program name with args.
+set dummy cache_dump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_DUMP_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_DUMP_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_DUMP_CMD="$ac_pt_CACHE_DUMP_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_DUMP_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_DUMP_CMD=$ac_cv_path_ac_pt_CACHE_DUMP_CMD
+if test -n "$ac_pt_CACHE_DUMP_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_DUMP_CMD" >&5
+$as_echo "$ac_pt_CACHE_DUMP_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_DUMP_CMD" = x; then
+ CACHE_DUMP_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_DUMP_CMD=$ac_pt_CACHE_DUMP_CMD
+ fi
+else
+ CACHE_DUMP_CMD="$ac_cv_path_CACHE_DUMP_CMD"
+fi
+
+ test -z "$CACHE_DUMP_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_dump not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_dump not found in path $PATH" >&2;}
+ CACHE_DUMP_CMD=/usr/sbin/cache_dump
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache repairing
+ if test "$CACHE_REPAIR_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_repair", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_repair; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_REPAIR_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_REPAIR_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_REPAIR_CMD="$CACHE_REPAIR_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_REPAIR_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_REPAIR_CMD=$ac_cv_path_CACHE_REPAIR_CMD
+if test -n "$CACHE_REPAIR_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_REPAIR_CMD" >&5
+$as_echo "$CACHE_REPAIR_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_REPAIR_CMD"; then
+ ac_pt_CACHE_REPAIR_CMD=$CACHE_REPAIR_CMD
+ # Extract the first word of "cache_repair", so it can be a program name with args.
+set dummy cache_repair; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_REPAIR_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_REPAIR_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_REPAIR_CMD="$ac_pt_CACHE_REPAIR_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_REPAIR_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_REPAIR_CMD=$ac_cv_path_ac_pt_CACHE_REPAIR_CMD
+if test -n "$ac_pt_CACHE_REPAIR_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_REPAIR_CMD" >&5
+$as_echo "$ac_pt_CACHE_REPAIR_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_REPAIR_CMD" = x; then
+ CACHE_REPAIR_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_REPAIR_CMD=$ac_pt_CACHE_REPAIR_CMD
+ fi
+else
+ CACHE_REPAIR_CMD="$ac_cv_path_CACHE_REPAIR_CMD"
+fi
+
+ test -z "$CACHE_REPAIR_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_repair not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_repair not found in path $PATH" >&2;}
+ CACHE_REPAIR_CMD=/usr/sbin/cache_repair
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache restoring
+ if test "$CACHE_RESTORE_CMD" = "autodetect"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cache_restore", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cache_restore; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CACHE_RESTORE_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CACHE_RESTORE_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CACHE_RESTORE_CMD="$CACHE_RESTORE_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_CACHE_RESTORE_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CACHE_RESTORE_CMD=$ac_cv_path_CACHE_RESTORE_CMD
+if test -n "$CACHE_RESTORE_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CACHE_RESTORE_CMD" >&5
+$as_echo "$CACHE_RESTORE_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_CACHE_RESTORE_CMD"; then
+ ac_pt_CACHE_RESTORE_CMD=$CACHE_RESTORE_CMD
+ # Extract the first word of "cache_restore", so it can be a program name with args.
+set dummy cache_restore; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_CACHE_RESTORE_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_CACHE_RESTORE_CMD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_CACHE_RESTORE_CMD="$ac_pt_CACHE_RESTORE_CMD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_CACHE_RESTORE_CMD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_CACHE_RESTORE_CMD=$ac_cv_path_ac_pt_CACHE_RESTORE_CMD
+if test -n "$ac_pt_CACHE_RESTORE_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CACHE_RESTORE_CMD" >&5
+$as_echo "$ac_pt_CACHE_RESTORE_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_CACHE_RESTORE_CMD" = x; then
+ CACHE_RESTORE_CMD=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CACHE_RESTORE_CMD=$ac_pt_CACHE_RESTORE_CMD
+ fi
+else
+ CACHE_RESTORE_CMD="$ac_cv_path_CACHE_RESTORE_CMD"
+fi
+
+ test -z "$CACHE_RESTORE_CMD" && {
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache_restore not found in path $PATH" >&5
+$as_echo "$as_me: WARNING: cache_restore not found in path $PATH" >&2;}
+ CACHE_RESTORE_CMD=/usr/sbin/cache_restore
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ ;;
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_CHECK_CMD "$CACHE_CHECK_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_DUMP_CMD "$CACHE_DUMP_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_REPAIR_CMD "$CACHE_REPAIR_CMD"
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define CACHE_RESTORE_CMD "$CACHE_RESTORE_CMD"
+_ACEOF
+
+
+
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable readline" >&5
$as_echo_n "checking whether to enable readline... " >&6; }
@@ -12091,6 +12597,10 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
+
+
+
+
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile conf/Makefile conf/example.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile
python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
@@ -13455,5 +13965,8 @@ $as_echo "$as_me: WARNING: Support for thin provisioning is limited since some t
test -n "$THIN_CHECK_VERSION_WARN" && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&5
$as_echo "$as_me: WARNING: You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning" >&2;}
+test -n "$CACHE_CONFIGURE_WARN" && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Support for cache is limited since some cache tools are missing!" >&5
+$as_echo "$as_me: WARNING: Support for cache is limited since some cache tools are missing!" >&2;}
+
test "$ODIRECT" = yes || { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5
$as_echo "$as_me: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&2;}
9 years, 9 months
master - cache: add tool support
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f9d80c9d31d711...
Commit: f9d80c9d31d7113ab8bc08baf6bba96a7449261f
Parent: 5c3d8940136f39a017ab434651789647161350b1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jul 4 16:31:29 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jul 11 12:47:35 2014 +0200
cache: add tool support
Introducing cache tool support.
---
WHATS_NEW | 1 +
conf/example.conf.in | 30 ++++++++++++++
configure.in | 89 +++++++++++++++++++++++++++++++++++++++---
lib/config/config_settings.h | 5 ++
lib/config/defaults.h | 2 +
lib/misc/configure.h.in | 12 ++++++
6 files changed, 133 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 29a0aa3..77cc2d7 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.108 -
=================================
+ Add initial code to use cache tools (cache_check|dump|repair|restore).
Add "degraded" activation mode and make it the default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 91768fb..2930054 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -744,6 +744,36 @@ global {
# external_origin_extend
#
# thin_disabled_features = [ "discards", "block_size" ]
+
+ # Full path of the utility called to check that a cache metadata device
+ # is in a state that allows it to be used.
+ # Each time a cached LV needs to be used or after it is deactivated
+ # this utility is executed. The activation will only proceed if the utility
+ # has an exit status of 0.
+ # Set to "" to skip this check. (Not recommended.)
+ # The cache tools are available as part of the device-mapper-persistent-data
+ # package from https://github.com/jthornber/thin-provisioning-tools.
+ #
+ # cache_check_executable = "@CACHE_CHECK_CMD@"
+
+ # Array of string options passed with cache_check command. By default,
+ # option "-q" is for quiet output.
+ #
+ # cache_check_options = [ "-q" ]
+
+ # Full path of the utility called to repair a cache metadata device.
+ # Each time a cache metadata needs repair this utility is executed.
+ # See cache_check_executable how to obtain binaries.
+ #
+ # cache_repair_executable = "@CACHE_REPAIR_CMD@"
+
+ # Array of extra string options passed with cache_repair command.
+ # cache_repair_options = [ "" ]
+
+ # Full path of the utility called to dump cache metadata content.
+ # See cache_check_executable how to obtain binaries.
+ #
+ # cache_dump_executable = "@CACHE_DUMP_CMD@"
}
activation {
diff --git a/configure.in b/configure.in
index d92e03e..1b8c338 100644
--- a/configure.in
+++ b/configure.in
@@ -447,7 +447,7 @@ case "$THIN" in
THIN_CHECK_NEEDS_CHECK=no
fi
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin dumping
if test "$THIN_DUMP_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_DUMP_CMD, thin_dump)
test -z "$THIN_DUMP_CMD" && {
@@ -456,7 +456,7 @@ case "$THIN" in
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin repairing
if test "$THIN_REPAIR_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_REPAIR_CMD, thin_repair)
test -z "$THIN_REPAIR_CMD" && {
@@ -465,7 +465,7 @@ case "$THIN" in
THIN_CONFIGURE_WARN=y
}
fi
- # Empty means a config way to ignore thin checking
+ # Empty means a config way to ignore thin restoring
if test "$THIN_RESTORE_CMD" = "autodetect"; then
AC_PATH_TOOL(THIN_RESTORE_CMD, thin_restore)
test -z "$THIN_RESTORE_CMD" && {
@@ -500,9 +500,24 @@ dnl -- cache inclusion type
AC_MSG_CHECKING(whether to include cache)
AC_ARG_WITH(cache,
AC_HELP_STRING([--with-cache=TYPE],
- [cache support: internal/shared/none
- [[TYPE=none]]]),
- CACHE=$withval, CACHE=none)
+ [cache support: internal/shared/none [[TYPE=none]]]),
+ CACHE=$withval, CACHE="none")
+AC_ARG_WITH(cache-check,
+ AC_HELP_STRING([--with-cache-check=PATH],
+ [cache_check tool: [[autodetect]]]),
+ CACHE_CHECK_CMD=$withval, CACHE_CHECK_CMD="autodetect")
+AC_ARG_WITH(cache-dump,
+ AC_HELP_STRING([--with-cache-dump=PATH],
+ [cache_dump tool: [[autodetect]]]),
+ CACHE_DUMP_CMD=$withval, CACHE_DUMP_CMD="autodetect")
+AC_ARG_WITH(cache-repair,
+ AC_HELP_STRING([--with-cache-repair=PATH],
+ [cache_repair tool: [[autodetect]]]),
+ CACHE_REPAIR_CMD=$withval, CACHE_REPAIR_CMD="autodetect")
+AC_ARG_WITH(cache-restore,
+ AC_HELP_STRING([--with-cache-restore=PATH],
+ [cache_restore tool: [[autodetect]]]),
+ CACHE_RESTORE_CMD=$withval, CACHE_RESTORE_CMD="autodetect")
AC_MSG_RESULT($CACHE)
case "$CACHE" in
@@ -511,6 +526,62 @@ case "$CACHE" in
*) AC_MSG_ERROR([--with-cache parameter invalid]) ;;
esac
+# Test if necessary cache tools are available
+# if not - use plain defaults and warn user
+case "$CACHE" in
+ internal|shared)
+ # Empty means a config way to ignore cache checking
+ if test "$CACHE_CHECK_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_CHECK_CMD, cache_check)
+ if test -z "$CACHE_CHECK_CMD"; then
+ AC_MSG_WARN([cache_check not found in path $PATH])
+ CACHE_CHECK_CMD=/usr/sbin/cache_check
+ CACHE_CONFIGURE_WARN=y
+ fi
+ fi
+ # Empty means a config way to ignore cache dumping
+ if test "$CACHE_DUMP_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_DUMP_CMD, cache_dump)
+ test -z "$CACHE_DUMP_CMD" && {
+ AC_MSG_WARN(cache_dump not found in path $PATH)
+ CACHE_DUMP_CMD=/usr/sbin/cache_dump
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache repairing
+ if test "$CACHE_REPAIR_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_REPAIR_CMD, cache_repair)
+ test -z "$CACHE_REPAIR_CMD" && {
+ AC_MSG_WARN(cache_repair not found in path $PATH)
+ CACHE_REPAIR_CMD=/usr/sbin/cache_repair
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ # Empty means a config way to ignore cache restoring
+ if test "$CACHE_RESTORE_CMD" = "autodetect"; then
+ AC_PATH_TOOL(CACHE_RESTORE_CMD, cache_restore)
+ test -z "$CACHE_RESTORE_CMD" && {
+ AC_MSG_WARN(cache_restore not found in path $PATH)
+ CACHE_RESTORE_CMD=/usr/sbin/cache_restore
+ CACHE_CONFIGURE_WARN=y
+ }
+ fi
+ ;;
+esac
+
+AC_DEFINE_UNQUOTED([CACHE_CHECK_CMD], ["$CACHE_CHECK_CMD"],
+ [The path to 'cache_check', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_DUMP_CMD], ["$CACHE_DUMP_CMD"],
+ [The path to 'cache_dump', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_REPAIR_CMD], ["$CACHE_REPAIR_CMD"],
+ [The path to 'cache_repair', if available.])
+
+AC_DEFINE_UNQUOTED([CACHE_RESTORE_CMD], ["$CACHE_RESTORE_CMD"],
+ [The path to 'cache_restore', if available.])
+
+
################################################################################
dnl -- Disable readline
AC_MSG_CHECKING(whether to enable readline)
@@ -1660,6 +1731,10 @@ AC_SUBST(THIN_CHECK_CMD)
AC_SUBST(THIN_DUMP_CMD)
AC_SUBST(THIN_REPAIR_CMD)
AC_SUBST(THIN_RESTORE_CMD)
+AC_SUBST(CACHE_CHECK_CMD)
+AC_SUBST(CACHE_DUMP_CMD)
+AC_SUBST(CACHE_REPAIR_CMD)
+AC_SUBST(CACHE_RESTORE_CMD)
AC_SUBST(UDEV_PC)
AC_SUBST(UDEV_RULES)
AC_SUBST(UDEV_SYNC)
@@ -1764,4 +1839,6 @@ test -n "$THIN_CONFIGURE_WARN" && AC_MSG_WARN([Support for thin provisioning is
test -n "$THIN_CHECK_VERSION_WARN" && AC_MSG_WARN([You should also install thin_check vsn 0.3.2 (or later) to use lvm2 thin provisioning])
+test -n "$CACHE_CONFIGURE_WARN" && AC_MSG_WARN([Support for cache is limited since some cache tools are missing!])
+
test "$ODIRECT" = yes || AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 455eb4f..c6be2e3 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -182,6 +182,11 @@ cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CF
cfg(global_thin_dump_executable_CFG, "thin_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_DUMP_CMD, vsn(2, 2, 100), NULL)
cfg(global_thin_repair_executable_CFG, "thin_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_REPAIR_CMD, vsn(2, 2, 100), NULL)
cfg_array(global_thin_repair_options_CFG, "thin_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_REPAIR_OPTIONS, vsn(2, 2, 100), NULL)
+cfg(global_cache_check_executable_CFG, "cache_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_CHECK_CMD, vsn(2, 2, 108), NULL)
+cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_CHECK_OPTIONS, vsn(2, 2, 108), NULL)
+cfg(global_cache_dump_executable_CFG, "cache_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_DUMP_CMD, vsn(2, 2, 108), NULL)
+cfg(global_cache_repair_executable_CFG, "cache_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_REPAIR_CMD, vsn(2, 2, 108), NULL)
+cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_REPAIR_OPTIONS, vsn(2, 2, 108), NULL)
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL)
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 815d6a3..05187b0 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -90,6 +90,8 @@
#define DEFAULT_THIN_POOL_ZERO 1
#define DEFAULT_POOL_METADATA_SPARE 1 /* thin + cache */
+#define DEFAULT_CACHE_CHECK_OPTIONS "-q"
+#define DEFAULT_CACHE_REPAIR_OPTIONS ""
#define DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_CACHE_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
diff --git a/lib/misc/configure.h.in b/lib/misc/configure.h.in
index c618ff4..f137f14 100644
--- a/lib/misc/configure.h.in
+++ b/lib/misc/configure.h.in
@@ -3,9 +3,21 @@
/* Define to 1 to use libblkid detection of signatures when wiping. */
#undef BLKID_WIPING_SUPPORT
+/* The path to 'cache_check', if available. */
+#undef CACHE_CHECK_CMD
+
+/* The path to 'cache_dump', if available. */
+#undef CACHE_DUMP_CMD
+
/* Define to 1 to include built-in support for cache. */
#undef CACHE_INTERNAL
+/* The path to 'cache_repair', if available. */
+#undef CACHE_REPAIR_CMD
+
+/* The path to 'cache_restore', if available. */
+#undef CACHE_RESTORE_CMD
+
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
9 years, 9 months