diff options
author | Alasdair G Kergon <agk@redhat.com> | 2014-01-14 03:17:27 +0000 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2014-01-14 03:17:27 +0000 |
commit | 5a450eab6a9fef7793066864ff58857d827b903f (patch) | |
tree | 5108cf84f40bd7f72d95cb920a8e0224bcb40a0a | |
parent | 4c2b4c37e72b74553125664364efcda0e0758bf7 (diff) | |
download | lvm2-5a450eab6a9fef7793066864ff58857d827b903f.tar.gz |
pvs: fix segfaults with orphans
Several fields used to display 0 if undefined. Recent changes
to the way the fields are reported threw away some tests for
valid pointers, leading to segfaults with 'pvs -o all'.
Reinstate the original behaviour.
-rw-r--r-- | lib/cache/lvmcache.c | 3 | ||||
-rw-r--r-- | lib/metadata/pv.c | 3 | ||||
-rw-r--r-- | lib/report/report.c | 8 | ||||
-rw-r--r-- | tools/reporter.c | 16 |
4 files changed, 17 insertions, 13 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 6719e9938..ec8699b8d 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -1958,6 +1958,9 @@ int lvmcache_uncertain_ownership(struct lvmcache_info *info) { uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info) { + if (!info) + return UINT64_C(0); + return find_min_mda_size(&info->mdas); } diff --git a/lib/metadata/pv.c b/lib/metadata/pv.c index 349048ec1..6f5fca4ad 100644 --- a/lib/metadata/pv.c +++ b/lib/metadata/pv.c @@ -245,7 +245,8 @@ uint64_t lvmcache_info_mda_free(struct lvmcache_info *info) { uint64_t freespace = UINT64_MAX; - lvmcache_foreach_mda(info, _pv_mda_free, &freespace); + if (info) + lvmcache_foreach_mda(info, _pv_mda_free, &freespace); if (freespace == UINT64_MAX) freespace = UINT64_C(0); diff --git a/lib/report/report.c b/lib/report/report.c index 3626769a9..bd4b725a0 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -693,13 +693,11 @@ static int _devsize_disp(struct dm_report *rh, struct dm_pool *mem, struct dm_report_field *field, const void *data, void *private) { + const struct device *dev = *(const struct device * const *) data; uint64_t size; - if (!data) - return _field_set_value(field, "", NULL); - - if (!dev_get_size(*(const struct device **) data, &size)) - return_0; + if (!dev || !dev->dev || !dev_get_size(dev, &size)) + size = _zero64; return _size64_disp(rh, mem, field, &size, private); } diff --git a/tools/reporter.c b/tools/reporter.c index a36fcb3e2..602f17303 100644 --- a/tools/reporter.c +++ b/tools/reporter.c @@ -141,8 +141,8 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg, struct volume_group *old_vg = vg; char uuid[64] __attribute__((aligned(8))); struct label *label; - struct label _dummy_label = { .dev = 0 }; - struct device _dummy_device = { .dev = 0 }; + struct label dummy_label = { .dev = 0 }; + struct device dummy_device = { .dev = 0 }; if (is_pv(pv) && !is_orphan(pv) && !vg) { vg_name = pv_vg_name(pv); @@ -183,14 +183,16 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg, /* FIXME workaround for pv_label going through cache; remove once struct * physical_volume gains a proper "label" pointer */ if (!(label = pv_label(pv))) { - _dummy_label.labeller = pv->fmt->labeller; + if (pv->fmt) + dummy_label.labeller = pv->fmt->labeller; + if (pv->dev) - _dummy_label.dev = pv->dev; + dummy_label.dev = pv->dev; else { - _dummy_label.dev = &_dummy_device; - memcpy(_dummy_device.pvid, &pv->id, ID_LEN); + dummy_label.dev = &dummy_device; + memcpy(dummy_device.pvid, &pv->id, ID_LEN); } - label = &_dummy_label; + label = &dummy_label; } if (!report_object(handle, vg, NULL, pv, NULL, NULL, label)) { |