mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Properly copy the whole pv structure for later use.
The all_pvs list, used in vg_read, should make its own private copy of pv structures, otherwise (when vg will use its own pool) it will point to released memory pool. The same applies for get_pvs() call. Patch adds pv_list copy helper and adds explicit memory pool parameter into _copy_pv. (Please note that all these helper functions cannot guarantee that vg related fields are valid - proper vg read & lock must be used if it is requested.)
This commit is contained in:
parent
1b25b6e009
commit
6fe905c705
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.46 -
|
Version 2.02.46 -
|
||||||
================================
|
================================
|
||||||
|
Use copy of PV structure when manipulating with global PV lists.
|
||||||
Always return exit error status when locking of volume group fails.
|
Always return exit error status when locking of volume group fails.
|
||||||
Fix mirror log convert validation question.
|
Fix mirror log convert validation question.
|
||||||
Avoid referencing files from DESTDIR during build process.
|
Avoid referencing files from DESTDIR during build process.
|
||||||
|
@ -198,11 +198,10 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _copy_pv(struct physical_volume *pv_to,
|
static int _copy_pv(struct dm_pool *pvmem,
|
||||||
|
struct physical_volume *pv_to,
|
||||||
struct physical_volume *pv_from)
|
struct physical_volume *pv_from)
|
||||||
{
|
{
|
||||||
struct dm_pool *pvmem = pv_from->fmt->cmd->mem;
|
|
||||||
|
|
||||||
memcpy(pv_to, pv_from, sizeof(*pv_to));
|
memcpy(pv_to, pv_from, sizeof(*pv_to));
|
||||||
|
|
||||||
if (!(pv_to->vg_name = dm_pool_strdup(pvmem, pv_from->vg_name)))
|
if (!(pv_to->vg_name = dm_pool_strdup(pvmem, pv_from->vg_name)))
|
||||||
@ -217,6 +216,25 @@ static int _copy_pv(struct physical_volume *pv_to,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct pv_list *_copy_pvl(struct dm_pool *pvmem, struct pv_list *pvl_from)
|
||||||
|
{
|
||||||
|
struct pv_list *pvl_to = NULL;
|
||||||
|
|
||||||
|
if (!(pvl_to = dm_pool_zalloc(pvmem, sizeof(*pvl_to))))
|
||||||
|
return_NULL;
|
||||||
|
|
||||||
|
if (!(pvl_to->pv = dm_pool_alloc(pvmem, sizeof(*pvl_to->pv))))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
if(!_copy_pv(pvmem, pvl_to->pv, pvl_from->pv))
|
||||||
|
goto_bad;
|
||||||
|
|
||||||
|
return pvl_to;
|
||||||
|
bad:
|
||||||
|
dm_pool_free(pvmem, pvl_to);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
|
int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
|
||||||
const char *vgid, const char *pvid,
|
const char *vgid, const char *pvid,
|
||||||
struct physical_volume *pv)
|
struct physical_volume *pv)
|
||||||
@ -237,7 +255,7 @@ int get_pv_from_vg_by_id(const struct format_type *fmt, const char *vg_name,
|
|||||||
|
|
||||||
dm_list_iterate_items(pvl, &vg->pvs) {
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
|
if (id_equal(&pvl->pv->id, (const struct id *) pvid)) {
|
||||||
if (!_copy_pv(pv, pvl->pv)) {
|
if (!_copy_pv(fmt->cmd->mem, pv, pvl->pv)) {
|
||||||
log_error("internal PV duplication failed");
|
log_error("internal PV duplication failed");
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
@ -1669,7 +1687,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd,
|
|||||||
return vg;
|
return vg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _update_pv_list(struct dm_list *all_pvs, struct volume_group *vg)
|
static int _update_pv_list(struct dm_pool *pvmem, struct dm_list *all_pvs, struct volume_group *vg)
|
||||||
{
|
{
|
||||||
struct pv_list *pvl, *pvl2;
|
struct pv_list *pvl, *pvl2;
|
||||||
|
|
||||||
@ -1678,13 +1696,15 @@ static int _update_pv_list(struct dm_list *all_pvs, struct volume_group *vg)
|
|||||||
if (pvl->pv->dev == pvl2->pv->dev)
|
if (pvl->pv->dev == pvl2->pv->dev)
|
||||||
goto next_pv;
|
goto next_pv;
|
||||||
}
|
}
|
||||||
/* PV is not on list so add it. Note that we don't copy it. */
|
|
||||||
if (!(pvl2 = dm_pool_zalloc(vg->cmd->mem, sizeof(*pvl2)))) {
|
/*
|
||||||
|
* PV is not on list so add it.
|
||||||
|
*/
|
||||||
|
if (!(pvl2 = _copy_pvl(pvmem, pvl))) {
|
||||||
log_error("pv_list allocation for '%s' failed",
|
log_error("pv_list allocation for '%s' failed",
|
||||||
pv_dev_name(pvl->pv));
|
pv_dev_name(pvl->pv));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pvl2->pv = pvl->pv;
|
|
||||||
dm_list_add(all_pvs, &pvl2->list);
|
dm_list_add(all_pvs, &pvl2->list);
|
||||||
next_pv:
|
next_pv:
|
||||||
;
|
;
|
||||||
@ -1899,7 +1919,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
|||||||
}
|
}
|
||||||
if (!correct_vg) {
|
if (!correct_vg) {
|
||||||
correct_vg = vg;
|
correct_vg = vg;
|
||||||
if (!_update_pv_list(&all_pvs, correct_vg))
|
if (!_update_pv_list(cmd->mem, &all_pvs, correct_vg))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1913,7 +1933,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
|||||||
/* FIXME Also ensure contents same - checksums same? */
|
/* FIXME Also ensure contents same - checksums same? */
|
||||||
if (correct_vg->seqno != vg->seqno) {
|
if (correct_vg->seqno != vg->seqno) {
|
||||||
inconsistent = 1;
|
inconsistent = 1;
|
||||||
if (!_update_pv_list(&all_pvs, vg))
|
if (!_update_pv_list(cmd->mem, &all_pvs, vg))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
if (vg->seqno > correct_vg->seqno)
|
if (vg->seqno > correct_vg->seqno)
|
||||||
correct_vg = vg;
|
correct_vg = vg;
|
||||||
@ -2203,7 +2223,7 @@ static int _get_pvs(struct cmd_context *cmd, struct dm_list **pvslist)
|
|||||||
struct str_list *strl;
|
struct str_list *strl;
|
||||||
struct dm_list * uninitialized_var(results);
|
struct dm_list * uninitialized_var(results);
|
||||||
const char *vgname, *vgid;
|
const char *vgname, *vgid;
|
||||||
struct dm_list *pvh, *tmp;
|
struct pv_list *pvl, *pvl_copy;
|
||||||
struct dm_list *vgids;
|
struct dm_list *vgids;
|
||||||
struct volume_group *vg;
|
struct volume_group *vg;
|
||||||
int consistent = 0;
|
int consistent = 0;
|
||||||
@ -2249,8 +2269,13 @@ static int _get_pvs(struct cmd_context *cmd, struct dm_list **pvslist)
|
|||||||
|
|
||||||
/* Move PVs onto results list */
|
/* Move PVs onto results list */
|
||||||
if (pvslist)
|
if (pvslist)
|
||||||
dm_list_iterate_safe(pvh, tmp, &vg->pvs)
|
dm_list_iterate_items(pvl, &vg->pvs) {
|
||||||
dm_list_add(results, pvh);
|
if (!(pvl_copy = _copy_pvl(cmd->mem, pvl))) {
|
||||||
|
log_error("PV list allocation failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dm_list_add(results, &pvl_copy->list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
init_pvmove(old_pvmove);
|
init_pvmove(old_pvmove);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user