summaryrefslogtreecommitdiff
path: root/lib/activate
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2020-09-27 01:11:47 +0200
committerZdenek Kabelac <zkabelac@redhat.com>2020-09-29 10:43:56 +0200
commit4de6f58085c533c79ce2e0db6cdeb6ed06fe05f8 (patch)
treefd3880637513515a6b14af693715a257f6b64fdc /lib/activate
parent92c0e8c17f506b551c1b7c0a448d60279e7fdae6 (diff)
downloadlvm2-4de6f58085c533c79ce2e0db6cdeb6ed06fe05f8.tar.gz
thin: use lv_status_thin and lv_status_thin_pool
Introduce structures lv_status_thin_pool and lv_status_thin (pair to lv_status_cache, lv_status_vdo) Convert lv_thin_percent() -> lv_thin_status() and lv_thin_pool_percent() + lv_thin_pool_transaction_id() -> lv_thin_pool_status(). This way a function user can see not only percentages, but also other important status info about thin-pool. TODO: This patch tries to not change too many other things, but pool_below_threshold() now uses new thin-pool info to return failure if thin-pool cannot be actually modified. This should be handle separately in a better way.
Diffstat (limited to 'lib/activate')
-rw-r--r--lib/activate/activate.c83
-rw-r--r--lib/activate/activate.h10
-rw-r--r--lib/activate/dev_manager.c118
-rw-r--r--lib/activate/dev_manager.h16
4 files changed, 109 insertions, 118 deletions
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 2e8f0e467..27f44e820 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -284,18 +284,13 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
{
return 0;
}
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent)
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **thin_pool_status)
{
return 0;
}
-int lv_thin_percent(const struct logical_volume *lv, int mapped,
- dm_percent_t *percent)
-{
- return 0;
-}
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id)
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **thin_status)
{
return 0;
}
@@ -1248,86 +1243,52 @@ int lv_cache_status(const struct logical_volume *cache_lv,
return 1;
}
-/*
- * Returns data or metadata percent usage, depends on metadata 0/1.
- * Returns 1 if percent set, else 0 on failure.
- */
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent)
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **thin_pool_status)
{
- int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
return 0;
- log_debug_activation("Checking thin %sdata percent for LV %s.",
- (metadata) ? "meta" : "", display_lvname(lv));
+ log_debug_activation("Checking thin pool status for LV %s.",
+ display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
- if (!(r = dev_manager_thin_pool_percent(dm, lv, metadata, percent)))
- stack;
+ if (!dev_manager_thin_pool_status(dm, lv, flush, thin_pool_status)) {
+ dev_manager_destroy(dm);
+ return_0;
+ }
- dev_manager_destroy(dm);
+ /* User has to call dm_pool_destroy(thin_pool_status->mem)! */
- return r;
+ return 1;
}
-/*
- * Returns 1 if percent set, else 0 on failure.
- */
-int lv_thin_percent(const struct logical_volume *lv,
- int mapped, dm_percent_t *percent)
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **thin_status)
{
- int r;
struct dev_manager *dm;
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
return 0;
- log_debug_activation("Checking thin percent for LV %s.",
+ log_debug_activation("Checking thin status for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
- if (!(r = dev_manager_thin_percent(dm, lv, mapped, percent)))
- stack;
-
- dev_manager_destroy(dm);
-
- return r;
-}
-
-/*
- * Returns 1 if transaction_id set, else 0 on failure.
- */
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id)
-{
- int r;
- struct dev_manager *dm;
- struct dm_status_thin_pool *status;
-
- if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
- return 0;
-
- log_debug_activation("Checking thin-pool transaction id for LV %s.",
- display_lvname(lv));
-
- if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
+ if (!dev_manager_thin_status(dm, lv, flush, thin_status)) {
+ dev_manager_destroy(dm);
return_0;
+ }
- if (!(r = dev_manager_thin_pool_status(dm, lv, &status, 0)))
- stack;
- else
- *transaction_id = status->transaction_id;
-
- dev_manager_destroy(dm);
+ /* User has to call dm_pool_destroy(thin_status->mem)! */
- return r;
+ return 1;
}
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index e3c1bb35e..3f4d128be 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -191,13 +191,11 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg);
int lv_writecache_message(const struct logical_volume *lv, const char *msg);
int lv_cache_status(const struct logical_volume *cache_lv,
struct lv_status_cache **status);
-int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
- dm_percent_t *percent);
-int lv_thin_percent(const struct logical_volume *lv, int mapped,
- dm_percent_t *percent);
-int lv_thin_pool_transaction_id(const struct logical_volume *lv,
- uint64_t *transaction_id);
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id);
+int lv_thin_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status);
+int lv_thin_pool_status(const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status);
int lv_vdo_pool_status(const struct logical_volume *lv, int flush,
struct lv_status_vdo **status);
int lv_vdo_pool_percent(const struct logical_volume *lv, dm_percent_t *percent);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index a626b000a..85cfda246 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1564,9 +1564,6 @@ int dev_manager_cache_status(struct dev_manager *dm,
if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
- return_0;
-
if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, 0, 0)))
return_0;
@@ -1589,8 +1586,11 @@ int dev_manager_cache_status(struct dev_manager *dm,
if (!dm_get_status_cache(dm->mem, params, &c))
goto_out;
- (*status)->cache = c;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_cache))))
+ goto_out;
+
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
+ (*status)->cache = c;
if (c->fail || c->error) {
(*status)->data_usage =
(*status)->metadata_usage =
@@ -1612,10 +1612,10 @@ out:
}
int dev_manager_thin_pool_status(struct dev_manager *dm,
- const struct logical_volume *lv,
- struct dm_status_thin_pool **status,
- int flush)
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status)
{
+ struct dm_status_thin_pool *dm_status;
const char *dlid;
struct dm_task *dmt;
struct dm_info info;
@@ -1636,11 +1636,31 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
- /* FIXME Check for thin and check there's exactly one target */
+ if (!type || strcmp(type, TARGET_NAME_THIN_POOL)) {
+ log_error("Expected %s segment type but got %s instead.",
+ TARGET_NAME_THIN_POOL, type ? type : "NULL");
+ goto out;
+ }
- if (!dm_get_status_thin_pool(dm->mem, params, status))
+ if (!dm_get_status_thin_pool(dm->mem, params, &dm_status))
goto_out;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin_pool))))
+ goto_out;
+
+ (*status)->mem = dm->mem;
+ (*status)->thin_pool = dm_status;
+
+ if (dm_status->fail || dm_status->error) {
+ (*status)->data_usage =
+ (*status)->metadata_usage = DM_PERCENT_INVALID;
+ } else {
+ (*status)->data_usage = dm_make_percent(dm_status->used_data_blocks,
+ dm_status->total_data_blocks);
+ (*status)->metadata_usage = dm_make_percent(dm_status->used_metadata_blocks,
+ dm_status->total_metadata_blocks);
+ }
+
r = 1;
out:
dm_task_destroy(dmt);
@@ -1648,52 +1668,68 @@ out:
return r;
}
-int dev_manager_thin_pool_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int metadata, dm_percent_t *percent)
+int dev_manager_thin_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status)
{
- char *name;
+ struct dm_status_thin *dm_status;
const char *dlid;
- const char *layer = lv_layer(lv);
+ struct dm_task *dmt;
+ struct dm_info info;
+ uint64_t start, length;
+ char *type = NULL;
+ char *params = NULL;
+ uint64_t csize;
+ int r = 0;
- /* Build a name for the top layer */
- if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
+ if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
return_0;
- if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
+ if (!(dmt = _setup_task_run(DM_DEVICE_STATUS, &info, NULL, dlid, 0, 0, 0, 0, flush, 0)))
return_0;
- log_debug_activation("Getting device status percentage for %s.", name);
-
- if (!(_percent(dm, name, dlid, TARGET_NAME_THIN_POOL, 0,
- (metadata) ? lv : NULL, percent, NULL, 1)))
- return_0;
+ if (!info.exists)
+ goto_out;
- return 1;
-}
+ dm_get_next_target(dmt, NULL, &start, &length, &type, &params);
-int dev_manager_thin_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int mapped, dm_percent_t *percent)
-{
- char *name;
- const char *dlid;
- const char *layer = lv_layer(lv);
+ if (!type || strcmp(type, TARGET_NAME_THIN)) {
+ log_error("Expected %s segment type but got %s instead.",
+ TARGET_NAME_THIN, type ? type : "NULL");
+ goto out;
+ }
- /* Build a name for the top layer */
- if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
- return_0;
+ if (!dm_get_status_thin(dm->mem, params, &dm_status))
+ goto_out;
- if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
- return_0;
+ if (!(*status = dm_pool_zalloc(dm->mem, sizeof(struct lv_status_thin))))
+ goto_out;
- log_debug_activation("Getting device status percentage for %s", name);
+ (*status)->mem = dm->mem;
+ (*status)->thin = dm_status;
+
+ if (dm_status->fail)
+ (*status)->usage = DM_PERCENT_INVALID;
+ else {
+ /* Pool allocates whole chunk so round-up to nearest one */
+ csize = first_seg(first_seg(lv)->pool_lv)->chunk_size;
+ csize = ((lv->size + csize - 1) / csize) * csize;
+ if (dm_status->mapped_sectors > csize) {
+ log_warn("WARNING: LV %s maps %s while the size is only %s.",
+ display_lvname(lv),
+ display_size(dm->cmd, dm_status->mapped_sectors),
+ display_size(dm->cmd, csize));
+ /* Don't show nonsense numbers like i.e. 1000% full */
+ dm_status->mapped_sectors = csize;
+ }
+ (*status)->usage = dm_make_percent(dm_status->mapped_sectors, csize);
+ }
- if (!(_percent(dm, name, dlid, TARGET_NAME_THIN, 0,
- (mapped) ? NULL : lv, percent, NULL, 1)))
- return_0;
+ r = 1;
+out:
+ dm_task_destroy(dmt);
- return 1;
+ return r;
}
/*
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index 5bff47799..557418201 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -69,19 +69,15 @@ int dev_manager_writecache_message(struct dev_manager *dm,
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_cache **status);
-int dev_manager_thin_pool_status(struct dev_manager *dm,
- const struct logical_volume *lv,
- struct dm_status_thin_pool **status,
- int flush);
-int dev_manager_thin_pool_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int metadata, dm_percent_t *percent);
-int dev_manager_thin_percent(struct dev_manager *dm,
- const struct logical_volume *lv,
- int mapped, dm_percent_t *percent);
+int dev_manager_thin_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin **status);
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id);
+int dev_manager_thin_pool_status(struct dev_manager *dm,
+ const struct logical_volume *lv, int flush,
+ struct lv_status_thin_pool **status);
int dev_manager_vdo_pool_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct lv_status_vdo **vdo_status,