[lvm-devel] master - dev_manager: enhance dev_manager_info to acquire LV segment status if requested, add lv_info_with_seg_status fn
Peter Rajnoha
prajnoha at fedoraproject.org
Tue Nov 11 12:12:37 UTC 2014
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a2c1024f6ac7e22ac5c010a267d0c1df331ee416
Commit: a2c1024f6ac7e22ac5c010a267d0c1df331ee416
Parent: 7f90ad84c1f9bbc51a833b7ebb6459842405de52
Author: Peter Rajnoha <prajnoha at redhat.com>
AuthorDate: Tue Nov 4 15:00:32 2014 +0100
Committer: Peter Rajnoha <prajnoha at redhat.com>
CommitterDate: Tue Nov 11 13:04:02 2014 +0100
dev_manager: enhance dev_manager_info to acquire LV segment status if requested, add lv_info_with_seg_status fn
---
lib/activate/activate.c | 42 ++++++++++---
lib/activate/activate.h | 5 ++
lib/activate/dev_manager.c | 140 ++++++++++++++++++++++++++++++++++++-------
lib/activate/dev_manager.h | 4 +-
tools/reporter.c | 2 +
5 files changed, 160 insertions(+), 33 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 93f9b9c..2843e61 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -617,17 +617,12 @@ int target_present(struct cmd_context *cmd, const char *target_name,
return target_version(target_name, &maj, &min, &patchlevel);
}
-/*
- * Returns 1 if info structure populated, else 0 on failure.
- * When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
- */
-int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
- struct lvinfo *info, int with_open_count, int with_read_ahead)
+static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
+ int use_layer, struct lvinfo *info, struct lv_seg_status *seg_status,
+ int with_open_count, int with_read_ahead)
{
struct dm_info dminfo;
- if (!activation())
- return 0;
/*
* If open_count info is requested and we have to be sure our own udev
* transactions are finished
@@ -648,7 +643,8 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
if (!dev_manager_info(cmd->mem, lv,
(use_layer) ? lv_layer(lv) : NULL,
with_open_count, with_read_ahead,
- &dminfo, (info) ? &info->read_ahead : NULL))
+ &dminfo, (info) ? &info->read_ahead : NULL,
+ seg_status))
return_0;
if (!info)
@@ -666,6 +662,19 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
return 1;
}
+/*
+ * Returns 1 if info structure populated, else 0 on failure.
+ * When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
+ */
+int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
+ struct lvinfo *info, int with_open_count, int with_read_ahead)
+{
+ if (!activation())
+ return 0;
+
+ return _lv_info(cmd, lv, use_layer, info, NULL, with_open_count, with_read_ahead);
+}
+
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead)
{
@@ -681,6 +690,21 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
return r;
}
+int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
+ const struct lv_segment *lv_seg, int use_layer,
+ struct lv_with_info_and_seg_status *lvdm,
+ int with_open_count, int with_read_ahead)
+{
+ if (!activation())
+ return 0;
+
+ if (!_lv_info(cmd, lv, use_layer, lvdm->info, lvdm->seg_status,
+ with_open_count, with_read_ahead))
+ return 0;
+
+ return 1;
+}
+
#define OPEN_COUNT_CHECK_RETRIES 25
#define OPEN_COUNT_CHECK_USLEEP_DELAY 200000
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index ab5e69d..86c53f5 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -118,6 +118,11 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
+int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
+ const struct lv_segment *lv_seg, int use_layer,
+ struct lv_with_info_and_seg_status *lvdm,
+ int with_open_count, int with_read_ahead);
+
int lv_check_not_in_use(const struct logical_volume *lv);
/*
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 2651ec8..5a07fad 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -106,32 +106,122 @@ static struct dm_task *_setup_task(const char *name, const char *uuid,
return NULL;
}
-static int _info_run(const char *name, const char *dlid, struct dm_info *info,
- uint32_t *read_ahead, int mknodes, int with_open_count,
- int with_read_ahead, uint32_t major, uint32_t minor)
+static int _get_segment_status_from_target_params(const char *target_name,
+ const char *params,
+ struct lv_seg_status *seg_status)
+{
+ struct segment_type *segtype;
+
+ /* FIXME: linear is also represented as striped with stripe count 1.
+ We're not reporting linear or striped status anyway, so
+ just skip the error here till this is properly resolved.*/
+ if (!strcmp(target_name, "linear") || !strcmp(target_name, "striped"))
+ return 1;
+
+ segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, target_name);
+
+ if (segtype != seg_status->seg->segtype) {
+ log_error(INTERNAL_ERROR "_get_segment_status_from_target_params: "
+ "segment type %s found does not match expected segment type %s",
+ segtype->name, seg_status->seg->segtype->name);
+ return 0;
+ }
+
+ if (!strcmp(segtype->name, "cache")) {
+ if (!dm_get_status_cache(seg_status->mem, params,
+ (struct dm_status_cache **) &seg_status->status))
+ return_0;
+ seg_status->type = SEG_STATUS_CACHE;
+ } else if (!strcmp(segtype->name, "raid")) {
+ if (!dm_get_status_raid(seg_status->mem, params,
+ (struct dm_status_raid **) &seg_status->status))
+ return_0;
+ seg_status->type = SEG_STATUS_RAID;
+ } else if (!strcmp(segtype->name, "thin")) {
+ if (!dm_get_status_thin(seg_status->mem, params,
+ (struct dm_status_thin **) &seg_status->status))
+ return_0;
+ seg_status->type = SEG_STATUS_THIN;
+ } else if (!strcmp(segtype->name, "thin-pool")) {
+ if (!dm_get_status_thin_pool(seg_status->mem, params,
+ (struct dm_status_thin_pool **) &seg_status->status))
+ return_0;
+ seg_status->type = SEG_STATUS_THIN_POOL;
+ } else if (!strcmp(segtype->name, "snapshot")) {
+ if (!dm_get_status_snapshot(seg_status->mem, params,
+ (struct dm_status_snapshot **) &seg_status->status))
+ return_0;
+ seg_status->type = SEG_STATUS_SNAPSHOT;
+ }
+
+ return 1;
+}
+
+typedef enum {
+ INFO, /* DM_DEVICE_INFO ioctl */
+ STATUS, /* DM_DEVICE_STATUS ioctl */
+ MKNODES
+} info_type_t;
+
+static int _info_run(info_type_t type, const char *name, const char *dlid,
+ struct dm_info *dminfo, uint32_t *read_ahead,
+ struct lv_seg_status *seg_status,
+ int with_open_count, int with_read_ahead,
+ uint32_t major, uint32_t minor)
{
int r = 0;
struct dm_task *dmt;
int dmtask;
+ void *target = NULL;
+ uint64_t target_start, target_length;
+ char *target_name, *target_params, *params_to_process = NULL;
+ uint32_t extent_size;
+
+ switch (type) {
+ case INFO:
+ dmtask = DM_DEVICE_INFO;
+ break;
+ case STATUS:
+ dmtask = DM_DEVICE_STATUS;
+ break;
+ case MKNODES:
+ dmtask = DM_DEVICE_MKNODES;
+ break;
+ }
- dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
-
- if (!(dmt = _setup_task(mknodes ? name : NULL, dlid, 0, dmtask, major, minor,
- with_open_count)))
+ if (!(dmt = _setup_task(type != MKNODES ? name : NULL, dlid, 0, dmtask,
+ major, minor, with_open_count)))
return_0;
if (!dm_task_run(dmt))
goto_out;
- if (!dm_task_get_info(dmt, info))
+ if (!dm_task_get_info(dmt, dminfo))
goto_out;
- if (with_read_ahead && info->exists) {
+ if (with_read_ahead && dminfo->exists) {
if (!dm_task_get_read_ahead(dmt, read_ahead))
goto_out;
} else if (read_ahead)
*read_ahead = DM_READ_AHEAD_NONE;
+ if (type == STATUS) {
+ extent_size = seg_status->seg->lv->vg->extent_size;
+ do {
+ target = dm_get_next_target(dmt, target, &target_start,
+ &target_length, &target_name, &target_params);
+ if ((seg_status->seg->le * extent_size == target_start) &&
+ (seg_status->seg->len * extent_size == target_length)) {
+ params_to_process = target_params;
+ break;
+ }
+ } while (target);
+
+ if (params_to_process &&
+ !_get_segment_status_from_target_params(target_name, params_to_process, seg_status))
+ goto_out;
+ }
+
r = 1;
out:
@@ -476,7 +566,8 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
}
static int _info(const char *dlid, int with_open_count, int with_read_ahead,
- struct dm_info *info, uint32_t *read_ahead)
+ struct dm_info *dminfo, uint32_t *read_ahead,
+ struct lv_seg_status *seg_status)
{
int r = 0;
char old_style_dlid[sizeof(UUID_PREFIX) + 2 * ID_LEN];
@@ -484,8 +575,8 @@ static int _info(const char *dlid, int with_open_count, int with_read_ahead,
unsigned i = 0;
/* Check for dlid */
- if ((r = _info_run(NULL, dlid, info, read_ahead, 0, with_open_count,
- with_read_ahead, 0, 0)) && info->exists)
+ if ((r = _info_run(seg_status ? STATUS : INFO, NULL, dlid, dminfo, read_ahead,
+ seg_status, with_open_count, with_read_ahead, 0, 0)) && dminfo->exists)
return 1;
/* Check for original version of dlid before the suffixes got added in 2.02.106 */
@@ -496,16 +587,17 @@ static int _info(const char *dlid, int with_open_count, int with_read_ahead,
(void) strncpy(old_style_dlid, dlid, sizeof(old_style_dlid));
old_style_dlid[sizeof(old_style_dlid) - 1] = '\0';
- if ((r = _info_run(NULL, old_style_dlid, info, read_ahead, 0, with_open_count,
- with_read_ahead, 0, 0)) && info->exists)
+ if ((r = _info_run(seg_status ? STATUS : INFO, NULL, old_style_dlid, dminfo,
+ read_ahead, seg_status, with_open_count,
+ with_read_ahead, 0, 0)) && dminfo->exists)
return 1;
}
}
/* Check for dlid before UUID_PREFIX was added */
- if ((r = _info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info,
- read_ahead, 0, with_open_count,
- with_read_ahead, 0, 0)) && info->exists)
+ if ((r = _info_run(seg_status ? STATUS : INFO, NULL, dlid + sizeof(UUID_PREFIX) - 1,
+ dminfo, read_ahead, seg_status, with_open_count,
+ with_read_ahead, 0, 0)) && dminfo->exists)
return 1;
return r;
@@ -513,13 +605,14 @@ static int _info(const char *dlid, int with_open_count, int with_read_ahead,
static int _info_by_dev(uint32_t major, uint32_t minor, struct dm_info *info)
{
- return _info_run(NULL, NULL, info, NULL, 0, 0, 0, major, minor);
+ return _info_run(INFO, NULL, NULL, info, NULL, 0, 0, 0, major, minor);
}
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
- struct dm_info *info, uint32_t *read_ahead)
+ struct dm_info *dminfo, uint32_t *read_ahead,
+ struct lv_seg_status *seg_status)
{
char *dlid, *name;
int r;
@@ -536,7 +629,8 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
}
log_debug_activation("Getting device info for %s [%s]", name, dlid);
- r = _info(dlid, with_open_count, with_read_ahead, info, read_ahead);
+ r = _info(dlid, with_open_count, with_read_ahead,
+ dminfo, read_ahead, seg_status);
out:
dm_pool_free(mem, name);
@@ -1447,7 +1541,7 @@ int dev_manager_mknodes(const struct logical_volume *lv)
if (!(name = dm_build_dm_name(lv->vg->cmd->mem, lv->vg->name, lv->name, NULL)))
return_0;
- if ((r = _info_run(name, NULL, &dminfo, NULL, 1, 0, 0, 0, 0))) {
+ if ((r = _info_run(MKNODES, name, NULL, &dminfo, NULL, NULL, 0, 0, 0, 0))) {
if (dminfo.exists) {
if (lv_is_visible(lv))
r = _dev_manager_lv_mknodes(lv);
@@ -1589,7 +1683,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
log_debug_activation("Getting device info for %s [%s]", name, dlid);
- if (!_info(dlid, 1, 0, &info, NULL)) {
+ if (!_info(dlid, 1, 0, &info, NULL, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
@@ -2078,7 +2172,7 @@ static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
return_NULL;
log_debug_activation("Getting device info for %s [%s]", name, dlid);
- if (!_info(dlid, 1, 0, &info, NULL)) {
+ if (!_info(dlid, 1, 0, &info, NULL, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index f4f989c..bfc6c02 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -25,6 +25,7 @@ struct cmd_context;
struct dev_manager;
struct dm_info;
struct device;
+struct lv_seg_status;
int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts *laopts);
@@ -47,7 +48,8 @@ void dev_manager_exit(void);
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
- struct dm_info *info, uint32_t *read_ahead);
+ struct dm_info *dminfo, uint32_t *read_ahead,
+ struct lv_seg_status *seg_status);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
dm_percent_t *percent);
diff --git a/tools/reporter.c b/tools/reporter.c
index d8c19eb..8fe5698 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -59,6 +59,8 @@ static void _get_lv_info_for_report(struct cmd_context *cmd,
static void _get_lv_info_with_segment_status_for_report(struct cmd_context *cmd,
struct lv_with_info_and_seg_status *lvdm)
{
+ if (!lv_info_with_seg_status(cmd, lvdm->seg_status->seg->lv, lvdm->seg_status->seg, 0, lvdm, 1, 1))
+ lvdm->info->exists = 0;
}
static int _lvs_with_info_single(struct cmd_context *cmd, struct logical_volume *lv,
More information about the lvm-devel
mailing list