diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2015-01-20 13:14:16 +0100 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2015-01-20 14:58:41 +0100 |
commit | b3a348c03c67b490ad1a8517168454dc6d5563da (patch) | |
tree | b5f3d24ae92e7870d3ee3f783f0ac6e7462b6227 | |
parent | e34b004422f0d51263e0d34f4064556cfc9148f6 (diff) | |
download | lvm2-b3a348c03c67b490ad1a8517168454dc6d5563da.tar.gz |
report: use same info also for lv_attr
Recently the single 'status' code has been used for number of cache
features.
Extend the API a little bit to allow usage also for lv_attr_dup.
As the function itself is used in lvm2api - add a new function:
lv_attr_dup_with_info_and_seg_status() that is able to use
grabbed info & status information.
report_init() is now using directly passed lvdm struct pointer
which holds the infomation whether lv_info() was correctly obtained or
there was some error when trying to read it.
Move 'healt' attribute to status.
TODO convert raid function to use the already known status.
-rw-r--r-- | lib/activate/activate.h | 8 | ||||
-rw-r--r-- | lib/activate/dev_manager.c | 21 | ||||
-rw-r--r-- | lib/metadata/lv.c | 50 | ||||
-rw-r--r-- | lib/metadata/lv.h | 3 | ||||
-rw-r--r-- | lib/report/columns.h | 4 | ||||
-rw-r--r-- | lib/report/report.c | 35 |
6 files changed, 67 insertions, 54 deletions
diff --git a/lib/activate/activate.h b/lib/activate/activate.h index 7cb8271bf..306ebd817 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -44,7 +44,13 @@ struct lv_seg_status { struct dm_pool *mem; /* input */ const struct lv_segment *seg; /* input */ lv_seg_status_type_t type; /* output */ - const void *status; /* struct dm_status_* */ /* output */ + union { + struct dm_status_cache *cache; + struct dm_status_raid *raid; + struct dm_status_snapshot *snapshot; + struct dm_status_thin *thin; + struct dm_status_thin_pool *thin_pool; + }; }; struct lv_with_info_and_seg_status { diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index f310a67a7..015af5bd0 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -121,6 +121,7 @@ static int _get_segment_status_from_target_params(const char *target_name, { struct segment_type *segtype; + seg_status->type = SEG_STATUS_UNKNOWN; /* * TODO: Add support for other segment types too! * The segment to report status for must be properly @@ -142,30 +143,28 @@ static int _get_segment_status_from_target_params(const char *target_name, } if (!strcmp(segtype->name, "cache")) { - if (!dm_get_status_cache(seg_status->mem, params, - (struct dm_status_cache **) &seg_status->status)) - return_0; + if (!dm_get_status_cache(seg_status->mem, params, &(seg_status->cache))) + 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)) + if (!dm_get_status_raid(seg_status->mem, params, &seg_status->raid)) 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)) + if (!dm_get_status_thin(seg_status->mem, params, &seg_status->thin)) 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)) + if (!dm_get_status_thin_pool(seg_status->mem, params, &seg_status->thin_pool)) 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)) + if (!dm_get_status_snapshot(seg_status->mem, params, &seg_status->snapshot)) return_0; seg_status->type = SEG_STATUS_SNAPSHOT; + } else { + log_error(INTERNAL_ERROR "Unsupported segment type %s.", segtype->name); + return 0; } return 1; diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c index 868253505..cb6577dbf 100644 --- a/lib/metadata/lv.c +++ b/lib/metadata/lv.c @@ -644,12 +644,11 @@ int lv_raid_healthy(const struct logical_volume *lv) return 1; } -char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) +char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm) { dm_percent_t snap_percent; - struct lvinfo info; + const struct logical_volume *lv = lvdm->lv; struct lv_segment *seg; - struct lv_seg_status seg_status; char *repstr; if (!(repstr = dm_pool_zalloc(mem, 11))) { @@ -722,30 +721,30 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) repstr[3] = (lv->status & FIXED_MINOR) ? 'm' : '-'; - if (!activation() || !lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) { + if (!activation() || !lvdm->info_ok) { repstr[4] = 'X'; /* Unknown */ repstr[5] = 'X'; /* Unknown */ - } else if (info.exists) { - if (info.suspended) + } else if (lvdm->info.exists) { + if (lvdm->info.suspended) repstr[4] = 's'; /* Suspended */ - else if (info.live_table) + else if (lvdm->info.live_table) repstr[4] = 'a'; /* Active */ - else if (info.inactive_table) + else if (lvdm->info.inactive_table) repstr[4] = 'i'; /* Inactive with table */ else repstr[4] = 'd'; /* Inactive without table */ /* Snapshot dropped? */ - if (info.live_table && lv_is_cow(lv)) { + if (lvdm->info.live_table && lv_is_cow(lv)) { if (!lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID) { - if (info.suspended) + if (lvdm->info.suspended) repstr[4] = 'S'; /* Susp Inv snapshot */ else repstr[4] = 'I'; /* Invalid snapshot */ } else if (snap_percent == LVM_PERCENT_MERGE_FAILED) { - if (info.suspended) + if (lvdm->info.suspended) repstr[4] = 'M'; /* Susp snapshot merge failed */ else repstr[4] = 'm'; /* snapshot merge failed */ @@ -756,10 +755,10 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) * 'R' indicates read-only activation of a device that * does not have metadata flagging it as read-only. */ - if (repstr[1] != 'r' && info.read_only) + if (repstr[1] != 'r' && lvdm->info.read_only) repstr[1] = 'R'; - repstr[5] = (info.open_count) ? 'o' : '-'; + repstr[5] = (lvdm->info.open_count) ? 'o' : '-'; } else { repstr[4] = '-'; repstr[5] = '-'; @@ -803,15 +802,15 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) repstr[8] = 'm'; /* RAID has 'm'ismatches */ } else if (lv->status & LV_WRITEMOSTLY) repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */ - } else if (lv_is_thin_pool(lv)) { - seg_status.mem = lv->vg->cmd->mem; - if (!lv_status(lv->vg->cmd, first_seg(lv), &seg_status)) + } else if (lv_is_thin_pool(lv) && + (lvdm->seg_status.type != SEG_STATUS_NONE)) { + if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN) repstr[8] = 'X'; /* Unknown */ - else if (((struct dm_status_thin_pool *)seg_status.status)->fail) + else if (lvdm->seg_status.thin_pool->fail) repstr[8] = 'F'; - else if (((struct dm_status_thin_pool *)seg_status.status)->out_of_data_space) + else if (lvdm->seg_status.thin_pool->out_of_data_space) repstr[8] = 'D'; - else if (((struct dm_status_thin_pool *)seg_status.status)->read_only) + else if (lvdm->seg_status.thin_pool->read_only) repstr[8] = 'M'; } @@ -824,6 +823,19 @@ out: return repstr; } +/* backward compatible internal API for lvm2api, TODO improve it */ +char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv) +{ + struct lv_with_info_and_seg_status status = { + .seg_status.type = SEG_STATUS_NONE + }; + + if (!lv_info_with_seg_status(lv->vg->cmd, lv, first_seg(lv), 1, &status, 1, 1)) + return_NULL; + + return lv_attr_dup_with_info_and_seg_status(mem, &status); +} + int lv_set_creation(struct logical_volume *lv, const char *hostname, uint64_t timestamp) { diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h index 6c6df737f..cb5885df5 100644 --- a/lib/metadata/lv.h +++ b/lib/metadata/lv.h @@ -54,8 +54,11 @@ struct logical_volume { const char *hostname; }; +struct lv_with_info_and_seg_status; + uint64_t lv_size(const struct logical_volume *lv); uint64_t lv_metadata_size(const struct logical_volume *lv); +char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm); char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lv_uuid_dup(const struct logical_volume *lv); char *lv_tags_dup(const struct logical_volume *lv); diff --git a/lib/report/columns.h b/lib/report/columns.h index 9f64ac8bc..fbbbe9dce 100644 --- a/lib/report/columns.h +++ b/lib/report/columns.h @@ -38,7 +38,7 @@ FIELD(LVS, lv, STR, "LV", lvid, 4, lvfullname, lv_full_name, "Full name of LV in FIELD(LVS, lv, STR, "Path", lvid, 4, lvpath, lv_path, "Full pathname for LV. Blank for internal LVs.", 0) FIELD(LVS, lv, STR, "DMPath", lvid, 6, lvdmpath, lv_dm_path, "Internal device-mapper pathname for LV (in /dev/mapper directory).", 0) FIELD(LVS, lv, STR, "Parent", lvid, 6, lvparent, lv_parent, "For LVs that are components of another LV, the parent LV.", 0) -FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, lv_attr, "Various attributes - see man page.", 0) +FIELD(LVSSTATUS, lv, STR, "Attr", lvid, 4, lvstatus, lv_attr, "Various attributes - see man page.", 0) FIELD(LVS, lv, STR_LIST, "Layout", lvid, 10, lvlayout, lv_layout, "LV layout.", 0) FIELD(LVS, lv, STR_LIST, "Role", lvid, 10, lvrole, lv_role, "LV role.", 0) FIELD(LVS, lv, BIN, "InitImgSync", lvid, 10, lvinitialimagesync, lv_initial_image_sync, "Set if mirror/RAID images underwent initial resynchronization.", 0) @@ -50,7 +50,6 @@ FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_loc FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Set if LV has fixed minor number assigned.", 0) FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Set if snapshot merge failed.", 0) FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Set if snapshot LV is invalid.", 0) -FIELD(LVS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0) FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0) FIELD(LVS, lv, BIN, "WhenFull", lvid, 15, lverrorwhenfull, lv_error_when_full, "For thin pools, behavior when full.", 0) FIELD(LVS, lv, STR, "Active", lvid, 6, lvactive, lv_active, "Active state of the LV.", 0) @@ -103,6 +102,7 @@ FIELD(LVSSTATUS, lv, NUM, "CacheReadHits", lvid, 16, cache_read_hits, cache_read FIELD(LVSSTATUS, lv, NUM, "CacheReadMisses", lvid, 16, cache_read_misses, cache_read_misses, "Cache read misses.", 0) FIELD(LVSSTATUS, lv, NUM, "CacheWriteHits", lvid, 16, cache_write_hits, cache_write_hits, "Cache write hits.", 0) FIELD(LVSSTATUS, lv, NUM, "CacheWriteMisses", lvid, 16, cache_write_misses, cache_write_misses, "Cache write misses.", 0) +FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0) FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0) FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0) diff --git a/lib/report/report.c b/lib/report/report.c index 1b1ccca2f..433819066 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -415,10 +415,10 @@ static int _lvstatus_disp(struct dm_report *rh __attribute__((unused)), struct d struct dm_report_field *field, const void *data, void *private __attribute__((unused))) { - const struct logical_volume *lv = (const struct logical_volume *) data; + const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data; char *repstr; - if (!(repstr = lv_attr_dup(mem, lv))) + if (!(repstr = lv_attr_dup_with_info_and_seg_status(mem, lvdm))) return_0; return _field_set_value(field, repstr, NULL); @@ -1770,8 +1770,8 @@ static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem, struct dm_report_field *field, const void *data, void *private) { - const struct logical_volume *lv = (const struct logical_volume *) data; - struct lv_seg_status seg_status; + const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data; + const struct logical_volume *lv = lvdm->lv; const char *health = ""; uint64_t n; @@ -1787,15 +1787,15 @@ static int _lvhealthstatus_disp(struct dm_report *rh, struct dm_pool *mem, health = "mismatches exist"; } else if (lv->status & LV_WRITEMOSTLY) health = "writemostly"; - } else if (lv_is_thin_pool(lv)) { - seg_status.mem = lv->vg->cmd->mem; - if (!lv_status(lv->vg->cmd, first_seg(lv), &seg_status)) - health = "unknown"; - else if (((struct dm_status_thin_pool *)seg_status.status)->fail) + } else if (lv_is_thin_pool(lv) && (lvdm->seg_status.type != SEG_STATUS_NONE)) { + if (lvdm->seg_status.type != SEG_STATUS_THIN_POOL) + return _field_set_value(field, GET_FIRST_RESERVED_NAME(health_undef), + GET_FIELD_RESERVED_VALUE(health_undef)); + else if (lvdm->seg_status.thin_pool->fail) health = "failed"; - else if (((struct dm_status_thin_pool *)seg_status.status)->out_of_data_space) + else if (lvdm->seg_status.thin_pool->out_of_data_space) health = "out_of_data"; - else if (((struct dm_status_thin_pool *)seg_status.status)->read_only) + else if (lvdm->seg_status.thin_pool->read_only) health = "metadata_read_only"; } @@ -1824,7 +1824,7 @@ static int _cache_ ## cache_status_field_name ## _disp (struct dm_report *rh, \ const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data; \ if (lvdm->seg_status.type != SEG_STATUS_CACHE) \ return _field_set_value(field, "", &GET_TYPE_RESERVED_VALUE(num_undef_64)); \ - return dm_report_field_uint64(rh, field, (void *) ((char *) lvdm->seg_status.status + offsetof(struct dm_status_cache, cache_status_field_name))); \ + return dm_report_field_uint64(rh, field, &lvdm->seg_status.cache->cache_status_field_name); \ } GENERATE_CACHE_STATUS_DISP_FN(total_blocks) @@ -1997,27 +1997,20 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys, int report_object(void *handle, const struct volume_group *vg, const struct logical_volume *lv, const struct physical_volume *pv, const struct lv_segment *seg, const struct pv_segment *pvseg, - const struct lvinfo *lvinfo, const struct lv_seg_status *lv_seg_status, + const struct lv_with_info_and_seg_status *lvdm, const struct label *label) { struct device dummy_device = { .dev = 0 }; struct label dummy_label = { .dev = &dummy_device }; - struct lv_with_info_and_seg_status lvdm = { .lv = lv }; struct lvm_report_object obj = { .vg = (struct volume_group *) vg, - .lvdm = &lvdm, + .lvdm = (struct lv_with_info_and_seg_status *) lvdm, .pv = (struct physical_volume *) pv, .seg = (struct lv_segment *) seg, .pvseg = (struct pv_segment *) pvseg, .label = (struct label *) (label ? : (pv ? pv_label(pv) : NULL)) }; - if (lvinfo) - lvdm.info = *lvinfo; - - if (lv_seg_status) - lvdm.seg_status = *lv_seg_status; - /* FIXME workaround for pv_label going through cache; remove once struct * physical_volume gains a proper "label" pointer */ if (!obj.label) { |