mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
o Code to calculate the metadata layout.
This commit is contained in:
parent
aa6421921c
commit
f6349180e8
2
configure
vendored
2
configure
vendored
@ -556,7 +556,7 @@ ac_config_sub=$ac_aux_dir/config.sub
|
||||
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
|
||||
|
||||
|
||||
for ac_prog in gawk mawk nawk awk
|
||||
for ac_prog in mawk gawk nawk awk
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
|
@ -17,6 +17,7 @@ SOURCES=\
|
||||
format1/disk-rep.c \
|
||||
format1/format1.c \
|
||||
format1/import-export.c \
|
||||
format1/layout.c \
|
||||
log/log.c \
|
||||
mm/dbg_malloc.c \
|
||||
mm/pool.c
|
||||
|
@ -148,6 +148,28 @@ struct disk_list {
|
||||
struct pe_disk *extents;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Layout constants.
|
||||
*/
|
||||
#define METADATA_ALIGN 4096UL
|
||||
#define PE_ALIGN 65536UL
|
||||
|
||||
#define METADATA_BASE 0UL
|
||||
#define PV_SIZE 1024UL
|
||||
#define VG_SIZE 4096UL
|
||||
|
||||
|
||||
/*
|
||||
* Functions to calculate layout info.
|
||||
*/
|
||||
int calculate_layout(struct disk_list *dl);
|
||||
|
||||
|
||||
/*
|
||||
* Low level io routines which read/write
|
||||
* disk_lists.
|
||||
*/
|
||||
struct disk_list *read_pv(struct device *dev, struct pool *mem,
|
||||
const char *vg_name);
|
||||
|
||||
@ -158,7 +180,7 @@ int write_pvs(struct list_head *pvs);
|
||||
|
||||
|
||||
/*
|
||||
* Functions to translate to betweendisk and in
|
||||
* Functions to translate to between disk and in
|
||||
* core structures.
|
||||
*/
|
||||
int import_pv(struct pool *mem, struct device *dev,
|
||||
|
@ -103,25 +103,6 @@ static struct volume_group *_vg_read(struct io_space *is, const char *vg_name)
|
||||
return vg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int _calculate_disk_sizes(struct disk_list *dl)
|
||||
{
|
||||
pvd->pv_on_disk.base = ??;
|
||||
pvd->pv_on_disk.size = ??;
|
||||
|
||||
pvd->vg_on_disk.base = ??;
|
||||
pvd->vg_on_disk.size = ??;
|
||||
|
||||
pvd->pv_uuidlist_on_disk.base = ??;
|
||||
pvd->pv_uuidlist_on_disk.size = ??;
|
||||
|
||||
pvd->lv_on_disk.base = ??;
|
||||
pvd->lv_on_disk.size = ??;
|
||||
|
||||
pvd->pe_on_disk.base = ??;
|
||||
pvd->pe_on_disk.size = ??;
|
||||
}
|
||||
#endif
|
||||
static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
|
||||
struct physical_volume *pv,
|
||||
const char *prefix)
|
||||
@ -142,7 +123,8 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
|
||||
if (!export_pv(&dl->pv, pv) ||
|
||||
!export_vg(&dl->vg, vg) ||
|
||||
!export_uuids(dl, vg) ||
|
||||
!export_lvs(dl, vg, pv, prefix)) {
|
||||
!export_lvs(dl, vg, pv, prefix) ||
|
||||
!calculate_layout(dl)) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
@ -323,6 +305,13 @@ static struct list_head *_get_vgs(struct io_space *is)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _pv_setup(struct io_space *is, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
log_err("format1:pv_setup not implemented.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _pv_write(struct io_space *is, struct physical_volume *pv)
|
||||
{
|
||||
log_err("format1:pv_write not implemented.");
|
||||
@ -344,6 +333,7 @@ struct io_space *create_lvm1_format(const char *prefix, struct pool *mem,
|
||||
ios->get_vgs = _get_vgs;
|
||||
ios->get_pvs = _get_pvs;
|
||||
ios->pv_read = _pv_read;
|
||||
ios->pv_setup = _pv_setup;
|
||||
ios->pv_write = _pv_write;
|
||||
ios->vg_read = _vg_read;
|
||||
ios->vg_write = _vg_write;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
static int _check_vg_name(const char *name)
|
||||
{
|
||||
return strlen(name) < NAME_LEN;
|
||||
|
81
lib/format1/layout.c
Normal file
81
lib/format1/layout.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the GPL.
|
||||
*/
|
||||
|
||||
#include "disk-rep.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
/*
|
||||
* Only works with powers of 2.
|
||||
*/
|
||||
static inline ulong _round_up(ulong n, ulong size)
|
||||
{
|
||||
size--;
|
||||
return (n + size) & ~size;
|
||||
}
|
||||
|
||||
static inline ulong _div_up(ulong n, ulong size)
|
||||
{
|
||||
return _round_up(n, size) / size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each chunk of metadata should be aligned to
|
||||
* METADATA_ALIGN.
|
||||
*/
|
||||
static uint32_t _next_base(struct data_area *area)
|
||||
{
|
||||
return _round_up(area->base + area->size, METADATA_ALIGN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Quick calculation based on pe_start.
|
||||
*/
|
||||
static int _adjust_pe_on_disk(struct pv_disk *pvd)
|
||||
{
|
||||
uint32_t pe_start = pvd->pe_start * SECTOR_SIZE;
|
||||
|
||||
if (pe_start < pvd->pe_on_disk.base + pvd->pe_on_disk.size)
|
||||
return 0;
|
||||
|
||||
pvd->pe_on_disk.size = pe_start - pvd->pe_on_disk.base;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This assumes pe_count and pe_start have already
|
||||
* been calculated correctly.
|
||||
*/
|
||||
int calculate_layout(struct disk_list *dl)
|
||||
{
|
||||
struct pv_disk *pvd = &dl->pv;
|
||||
|
||||
pvd->pv_on_disk.base = METADATA_BASE;
|
||||
pvd->pv_on_disk.size = PV_SIZE;
|
||||
|
||||
pvd->vg_on_disk.base = _next_base(&pvd->pv_on_disk);
|
||||
pvd->vg_on_disk.size = VG_SIZE;
|
||||
|
||||
pvd->pv_uuidlist_on_disk.base = _next_base(&pvd->vg_on_disk);
|
||||
pvd->pv_uuidlist_on_disk.size = (MAX_PV + 1) * NAME_LEN;
|
||||
|
||||
pvd->lv_on_disk.base = _next_base(&pvd->pv_uuidlist_on_disk);
|
||||
pvd->lv_on_disk.size = (MAX_LV + 1) * sizeof(struct lv_disk);
|
||||
|
||||
pvd->pe_on_disk.base = _next_base(&pvd->lv_on_disk);
|
||||
pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk);
|
||||
|
||||
if (!_adjust_pe_on_disk(pvd)) {
|
||||
log_err("insufficient space for metadata and PE's.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -119,55 +119,84 @@ struct lv_list {
|
||||
struct logical_volume lv;
|
||||
};
|
||||
|
||||
/* ownership of returned objects passes */
|
||||
/*
|
||||
* Ownership of objects passes to caller.
|
||||
*/
|
||||
struct io_space {
|
||||
/* Returns list of names of all vgs - vg
|
||||
component only, not full path*/
|
||||
/*
|
||||
* Returns a name_list of vg's.
|
||||
*/
|
||||
struct list_head *(*get_vgs)(struct io_space *is);
|
||||
|
||||
/* Returns list of fully-populated pv structures */
|
||||
/*
|
||||
* Returns pv_list of fully-populated pv structures.
|
||||
*/
|
||||
struct list_head *(*get_pvs)(struct io_space *is);
|
||||
|
||||
/* Return PV with given name (may be full or relative path) */
|
||||
/*
|
||||
* Return PV with given path.
|
||||
*/
|
||||
struct physical_volume *(*pv_read)(struct io_space *is,
|
||||
const char *pv_name);
|
||||
|
||||
/* Write a PV structure to disk. */
|
||||
/* Fails if the PV is in a VG ie
|
||||
pv->vg_name must be null */
|
||||
/*
|
||||
* fill out a pv ready for importing into
|
||||
* a vg.
|
||||
*/
|
||||
int (*pv_setup)(struct io_space *is, struct physical_volume *pv,
|
||||
struct volume_group *vg);
|
||||
|
||||
/*
|
||||
* Write a PV structure to disk. Fails if
|
||||
* the PV is in a VG ie pv->vg_name must
|
||||
* be null.
|
||||
*/
|
||||
int (*pv_write)(struct io_space *is, struct physical_volume *pv);
|
||||
|
||||
/* if vg_name doesn't contain any slash, this function adds prefix */
|
||||
/*
|
||||
* If vg_name doesn't contain any slash,
|
||||
* this function adds prefix.
|
||||
*/
|
||||
struct volume_group *(*vg_read)(struct io_space *is,
|
||||
const char *vg_name);
|
||||
|
||||
/* Write out complete VG metadata. */
|
||||
/* Ensure *internal* consistency before writing anything.
|
||||
* eg. PEs can't refer to PVs not part of the VG
|
||||
* Order write sequence to aid recovery if process is aborted
|
||||
* (eg flush entire set of changes to each disk in turn)
|
||||
* It is the responsibility of the caller to ensure external
|
||||
* consistency, eg by calling pv_write() if removing PVs from a VG
|
||||
* or calling vg_write() a second time if splitting a VG into two.
|
||||
* vg_write() must not read or write from any PVs not included
|
||||
* in the volume_group structure it is handed.
|
||||
/*
|
||||
* Write out complete VG metadata. Ensure
|
||||
* *internal* consistency before writing
|
||||
* anything. eg. PEs can't refer to PVs
|
||||
* not part of the VG. Order write sequence
|
||||
* to aid recovery if process is aborted
|
||||
* (eg flush entire set of changes to each
|
||||
* disk in turn) It is the responsibility
|
||||
* of the caller to ensure external
|
||||
* consistency, eg by calling pv_write()
|
||||
* if removing PVs from a VG or calling
|
||||
* vg_write() a second time if splitting a
|
||||
* VG into two. vg_write() must not read
|
||||
* or write from any PVs not included in
|
||||
* the volume_group structure it is
|
||||
* handed.
|
||||
*/
|
||||
int (*vg_write)(struct io_space *is, struct volume_group *vg);
|
||||
|
||||
/*
|
||||
* Destructor for this object.
|
||||
*/
|
||||
void (*destroy)(struct io_space *is);
|
||||
|
||||
/* Current volume group prefix. */
|
||||
/* Default to "/dev/" */
|
||||
/*
|
||||
* Current volume group prefix.
|
||||
*/
|
||||
char *prefix;
|
||||
struct pool *mem;
|
||||
struct dev_filter *filter;
|
||||
void *private;
|
||||
};
|
||||
|
||||
|
||||
/* FIXME: Move to other files */
|
||||
struct io_space *create_text_format(struct dev_filter *filter,
|
||||
const char *text_file);
|
||||
struct io_space *create_lvm_v1_format(struct dev_filter *filter);
|
||||
|
||||
int id_eq(struct id *op1, struct id *op2);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user