#include "lvm1-label.h"
#include "format1.h"
#include "segtype.h"
+#include "pv_alloc.h"
/* VG consistency checks */
-static int _check_vgs(struct dm_list *pvs)
+static int _check_vgs(struct dm_list *pvs, struct volume_group *vg)
{
struct dm_list *pvh, *t;
struct disk_list *dl = NULL;
if (pv_count != first->vgd.pv_cur) {
log_error("%d PV(s) found for VG %s: expected %d",
pv_count, first->pvd.vg_name, first->vgd.pv_cur);
+ vg->status |= PARTIAL_VG;
}
return 1;
}
+static int _fix_partial_vg(struct volume_group *vg, struct dm_list *pvs)
+{
+ uint32_t extent_count = 0;
+ struct disk_list *dl;
+ struct dm_list *pvh;
+ struct pv_list *pvl;
+
+ dm_list_iterate(pvh, pvs) {
+ dl = dm_list_item(pvh, struct disk_list);
+ extent_count += dl->pvd.pe_total;
+ }
+
+ /* FIXME: move this to one place to pv_manip */
+ if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl))) ||
+ !(pvl->pv = dm_pool_zalloc(vg->vgmem, sizeof(*pvl->pv))))
+ return_0;
+
+ if (!id_create(&pvl->pv->id))
+ goto_out;
+ if (!(pvl->pv->vg_name = dm_pool_strdup(vg->vgmem, vg->name)))
+ goto_out;
+ memcpy(&pvl->pv->vgid, &vg->id, sizeof(vg->id));
+ pvl->pv->status |= MISSING_PV;
+ dm_list_init(&pvl->pv->tags);
+ dm_list_init(&pvl->pv->segments);
+
+ pvl->pv->pe_size = vg->extent_size;
+ pvl->pv->pe_count = vg->extent_count - extent_count;
+ if (!alloc_pv_segment_whole_pv(vg->vgmem, pvl->pv))
+ goto_out;
+
+ add_pvl_to_vgs(vg, pvl);
+ log_debug("%s: partial VG, allocated missing PV using %d extents.",
+ vg->name, pvl->pv->pe_count);
+
+ return 1;
+out:
+ dm_pool_free(vg->vgmem, pvl);
+ return 0;
+}
+
static struct volume_group *_build_vg(struct format_instance *fid,
struct dm_list *pvs,
struct dm_pool *mem)
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_pvs);
- if (!_check_vgs(pvs))
+ if (!_check_vgs(pvs, vg))
goto_bad;
dl = dm_list_item(pvs->n, struct disk_list);
if (!import_snapshots(mem, vg, pvs))
goto_bad;
+ /* Fix extents counts by adding missing PV if partial VG */
+ if ((vg->status & PARTIAL_VG) && !_fix_partial_vg(vg, pvs))
+ goto_bad;
+
return vg;
bad: