Add interface to support adding and removing metadata areas on demand (v2)
cover Add interface to support adding and removing metadata areas on demand (v2)
This patchset provides a possibility to add new metadata areas on demand as well as removing them. Now, we can add a new metadata area independently of the PV initialisation so if there's a place we can even add metadata area additionally. The same applies for metadata removal functionality. This is only internal interface for now, but we should be able to provide external hooks in lvm2 commands if desired.
The patchset also tries to cleanup existing pv_setup/pv_write code. It also uses the new interface to allow resizing a PV with more copies of metadata areas on disk which was not allowed before because of missing metadata handling part in the interface.
To support all these changes, a definition of format_instance for PVs is now supported. This structure holds all the information we need.
This patchset should be applicable to 4dff097f6617ef746cd75250f74425825082a8ce. The tests seems to be passing, just one is still failing - it's lvm2 format
handling: t-pv-create-usage.sh: "PV segment pe_count mismatch: 33 != 32".
Peter Rajnoha (17):
Add pvid parameter to create_instance function.
Add supporting functions for metadata areas stored in format
instance.
Add struct format_instance *fid field to struct physical_volume. Add format_instance support for pv_read.
Add attach_existing_mdas parameter to create_instance fn. Remove useless mdas parameter from PV read functions.
Add pv_add_metadata_area fn to support adding metadata areas on
demand.
Add pv_remove_metadata_area fn to support removing metadata areas on
demand.
Add pv_initialise fn to format_handler interface.
Add pe_start_locked parameter to pv_create fn.
Refactor pv_setup to not include the PV initialisation code. Remove unused _mda_setup code.
Cleanup pv_write code to use recent changes in metadata handling
interface.
Use new metadata handling interface to provide better support for PV
resize.
Change vg_convert code to actually work with recent changes in
metadata handling interface.
Fix pvchange -u to work with recent changes in metadata handling
interface.
Fix pvchange --metadataignore to work with recent changes in metadata
handling interface.
lib/cache/lvmcache.c | 4 +- lib/format1/format1.c | 38 +- lib/format_pool/format_pool.c | 28 +- lib/format_text/archive.c | 2 +- lib/format_text/archiver.c | 15 +- lib/format_text/format-text.c | 1027 ++++++++++++++++++++++---------------- lib/format_text/format-text.h | 8 + lib/metadata/metadata-exported.h | 23 +- lib/metadata/metadata.c | 357 +++++++++++--- lib/metadata/metadata.h | 71 ++- lib/metadata/pv.c | 20 +- lib/metadata/pv.h | 2 + lib/metadata/pv_manip.c | 70 ++- tools/pvchange.c | 5 +- tools/pvremove.c | 10 +- tools/pvresize.c | 57 +-- tools/toollib.c | 14 +- tools/vgconvert.c | 93 +--- tools/vgreduce.c | 2 +- 19 files changed, 1120 insertions(+), 726 deletions(-)
Signature · 1 line
1.7.3.4
PATCH 1/17 Add pvid parameter to create_instance function.
This is a preparation for the next patches...
The format instance holds the information about current metadata areas and it is a snapshot of what we have in the cache at the moment of the instance creation. Through the command exection, we use this instance to modify, set and access modified metadata areas (like we use it to support the --metadataignore and we store the metadata areas that are in use and the ones that are ignored).
But to support modifying metadata areas fully (with add/remove metadata area support), we need to be able to create format instances for PVs as well. Hence, add the pvid parameter for the create_instance function.
The rules we will follow:
- the format instance is VG-based or PV-based, but *never both* at the same time,
- when a PV (structure) is alone, not part of any VG, we will have a PV based format_instance attached to the PV structure,
- when a PV is part of the VG, any existing PV-based format_instance is destroyed and the PV strucutre will reference VG based format instance instead.
- whatever we need change for mdas, we'll use the format_instance, we don't touch the cache directly! This will be synchronized with the format instance after pv_write automatically.
--- lib/cache/lvmcache.c | 2 +- lib/format1/format1.c | 1 + lib/format_pool/format_pool.c | 1 + lib/format_text/archive.c | 2 +- lib/format_text/archiver.c | 8 ++++---- lib/format_text/format-text.c | 20 +++++++++++--------- lib/metadata/metadata.c | 10 +++++----- lib/metadata/metadata.h | 5 +++-- 8 files changed, 27 insertions(+), 22 deletions(-)
lib/cache/lvmcache.c +1 -1
@@ -653,7 +653,7 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)return NULL ;if (!(fid = vginfo->fmt->ops->create_instance (vginfo->fmt, - vginfo->vgname, +NULL , vginfo->vgname, vgid,NULL ))) return_NULL;
lib/format1/format1.c +1 -0
@@ -522,6 +522,7 @@ static struct metadata_area_ops _metadata_format1_ops = { };static struct format_instance *_format1_create_instance (const struct format_type *fmt, +const char *pvid __attribute__((unused)),const char *vgname __attribute__((unused)),const char *vgid __attribute__((unused)),void *private __attribute__((unused)))
lib/format_pool/format_pool.c +1 -0
@@ -249,6 +249,7 @@ static struct metadata_area_ops _metadata_format_pool_ops = {/* *INDENT-ON* */ static struct format_instance *_pool_create_instance (const struct format_type *fmt, +const char *pvid __attribute__((unused)),const char *vgname __attribute__((unused)),const char *vgid __attribute__((unused)),void *private __attribute__((unused)))
lib/format_text/archive.c +1 -1
@@ -309,7 +309,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)if (!(context =create_text_context (cmd, af->path,NULL )) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create text instance object." );return ; }
lib/format_text/archiver.c +4 -4
@@ -278,7 +278,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,if (!(context =create_text_context (cmd, file, cmd->cmd_line)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create text format object." );return NULL ; }
@@ -306,8 +306,8 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)*/ /* Attempt to write out using currently active format */ -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt, vg->name, -NULL ,NULL ))) { +if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg->name,NULL ,NULL ))) {log_error ("Failed to allocate format instance" );return 0 ; }
@@ -398,7 +398,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)if (!(context =create_text_context (cmd, file, desc)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create backup object." );return 0 ; }
lib/format_text/format-text.c +11 -9
@@ -37,10 +37,11 @@#include <dirent.h> #include <ctype.h> -static struct format_instance *_text_create_text_instance (const struct format_type - *fmt,const char *vgname, -const char *vgid, -void *context); +static struct format_instance *_text_create_text_instance (const struct format_type *fmt, +const char *pvid, +const char *vgname, +const char *vgid, +void *context);struct text_fid_context {char *raw_metadata_buf;
@@ -1085,7 +1086,7 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)/* FIXME stat file to see if it's changed */ fid =_text_create_text_instance (fmt,NULL ,NULL , -NULL ); +NULL ,NULL );if ((vg =_vg_read_file_name (fid, scanned_vgname, path))) {/* FIXME Store creation host in vg */
@@ -1912,10 +1913,11 @@ static int _text_pv_setup(const struct format_type *fmt, }/* NULL vgname means use only the supplied context e.g. an archive file */ -static struct format_instance *_text_create_text_instance (const struct format_type - *fmt,const char *vgname, -const char *vgid, -void *context) +static struct format_instance *_text_create_text_instance (const struct format_type *fmt, +const char *pvid, +const char *vgname, +const char *vgid, +void *context) {struct format_instance *fid;struct text_fid_context *fidtc;
lib/metadata/metadata.c +5 -5
@@ -974,8 +974,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)/* initialize removed_pvs list */ dm_list_init (&vg->removed_pvs); -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt, vg_name, -NULL ,NULL ))) { +if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg_name,NULL ,NULL ))) {log_error ("Failed to create format instance" ); goto bad; }
@@ -2629,7 +2629,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, }/* create format instance with appropriate metadata area */ -if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt, +if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , orphan_vgname,NULL ,NULL ))) {log_error ("Failed to create format instance" );
@@ -2808,7 +2808,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt, vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) {log_error ("Failed to create format instance" );return NULL ; }
@@ -2962,7 +2962,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt, vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) {log_error ("Failed to create format instance" );return NULL ; }
lib/metadata/metadata.h +3 -2
@@ -279,8 +279,9 @@ struct format_handler {/* * Create format instance with a particular metadata area */ -struct format_instance *(*create_instance) (const struct format_type * - fmt,const char *vgname, +struct format_instance *(*create_instance) (const struct format_type *fmt, +const char *pvid, +const char *vgname,const char *vgid,void *context);
Signature · 1 line
1.7.3.4
PATCH 1/17 Add pvid parameter to create_instance function.
Quoted 19 lines · Peter Rajnoha
The format instance holds the information about current metadata areas and it is a snapshot of what we have in the cache at the moment of the instance creation. Through the command exection, we use this instance to modify, set and access modified metadata areas (like we use it to support the --metadataignore and we store the metadata areas that are in use and the ones that are ignored).
But to support modifying metadata areas fully (with add/remove metadata area support), we need to be able to create format instances for PVs as well. Hence, add the pvid parameter for the
create_instancefunction.The rules we will follow:
- the format instance is VG-based or PV-based, but *never both* at the same time,
- when a PV (structure) is alone, not part of any VG, we will have a PV based
format_instanceattached to the PV structure,
Quoted 7 lines
- when a PV is part of the VG, any existing PV-based
format_instanceis destroyed and the PV strucutre will reference VG based format instance instead.- whatever we need change for mdas, we'll use the
format_instance, we don't touch the cache directly! This will be synchronized with the format instance afterpv_writeautomatically.
Sounds sane. Implementation looks OK too.
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 196 lines
--- lib/cache/lvmcache.c | 2 +- lib/format1/format1.c | 1 + lib/format_pool/format_pool.c | 1 + lib/format_text/archive.c | 2 +- lib/format_text/archiver.c | 8 ++++---- lib/format_text/format-text.c | 20 +++++++++++--------- lib/metadata/metadata.c | 10 +++++----- lib/metadata/metadata.h | 5 +++-- 8 files changed, 27 insertions(+), 22 deletions(-)lib/cache/lvmcache.c +1
-1@@ -653,7 +653,7 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)return NULL ;if (!(fid = vginfo->fmt->ops->create_instance (vginfo->fmt, - vginfo->vgname, +NULL , vginfo->vgname, vgid,NULL ))) return_NULL;lib/format1/format1.c +1
-0@@ -522,6 +522,7 @@ static struct metadata_area_ops _metadata_format1_ops = { };static struct format_instance *_format1_create_instance (const struct format_type *fmt, +const char *pvid __attribute__((unused)),const char *vgname __attribute__((unused)),const char *vgid __attribute__((unused)),void *private __attribute__((unused)))lib/format_pool/format_pool.c +1
-0@@ -249,6 +249,7 @@ static struct metadata_area_ops _metadata_format_pool_ops = {/* *INDENT-ON* */ static struct format_instance *_pool_create_instance (const struct format_type *fmt, +const char *pvid __attribute__((unused)),const char *vgname __attribute__((unused)),const char *vgid __attribute__((unused)),void *private __attribute__((unused)))lib/format_text/archive.c +1
-1@@ -309,7 +309,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)if (!(context =create_text_context (cmd, af->path,NULL )) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create text instance object." );return ; }lib/format_text/archiver.c +4
-4@@ -278,7 +278,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,if (!(context =create_text_context (cmd, file, cmd->cmd_line)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create text format object." );return NULL ; }@@ -306,8 +306,8 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)*/ /* Attempt to write out using currently active format */ -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt, vg->name, -NULL ,NULL ))) { +if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg->name,NULL ,NULL ))) {log_error ("Failed to allocate format instance" );return 0 ; }@@ -398,7 +398,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)if (!(context =create_text_context (cmd, file, desc)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL , context))) { +NULL ,NULL , context))) {log_error ("Couldn't create backup object." );return 0 ; }lib/format_text/format-text.c +11
-9@@ -37,10 +37,11 @@#include <dirent.h> #include <ctype.h> -static struct format_instance *_text_create_text_instance (const struct format_type - *fmt,const char *vgname, -const char *vgid, -void *context); +static struct format_instance *_text_create_text_instance (const struct format_type *fmt, +const char *pvid, +const char *vgname, +const char *vgid, +void *context);struct text_fid_context {char *raw_metadata_buf;@@ -1085,7 +1086,7 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)/* FIXME stat file to see if it's changed */ fid =_text_create_text_instance (fmt,NULL ,NULL , -NULL ); +NULL ,NULL );if ((vg =_vg_read_file_name (fid, scanned_vgname, path))) {/* FIXME Store creation host in vg */ @@ -1912,10 +1913,11 @@ static int _text_pv_setup(const struct format_type *fmt, }/* NULL vgname means use only the supplied context e.g. an archive file */ -static struct format_instance *_text_create_text_instance (const struct format_type - *fmt,const char *vgname, -const char *vgid, -void *context) +static struct format_instance *_text_create_text_instance (const struct format_type *fmt, +const char *pvid, +const char *vgname, +const char *vgid, +void *context) {struct format_instance *fid;struct text_fid_context *fidtc;lib/metadata/metadata.c +5
-5@@ -974,8 +974,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)/* initialize removed_pvs list */ dm_list_init (&vg->removed_pvs); -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt, vg_name, -NULL ,NULL ))) { +if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg_name,NULL ,NULL ))) {log_error ("Failed to create format instance" ); goto bad; }@@ -2629,7 +2629,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, }/* create format instance with appropriate metadata area */ -if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt, +if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , orphan_vgname,NULL ,NULL ))) {log_error ("Failed to create format instance" );@@ -2808,7 +2808,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt, vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) {log_error ("Failed to create format instance" );return NULL ; }@@ -2962,7 +2962,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt, vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) {log_error ("Failed to create format instance" );return NULL ; }lib/metadata/metadata.h +3
-2@@ -279,8 +279,9 @@ struct format_handler {/* * Create format instance with a particular metadata area */ -struct format_instance *(*create_instance) (const struct format_type * - fmt,const char *vgname, +struct format_instance *(*create_instance) (const struct format_type *fmt, +const char *pvid, +const char *vgname,const char *vgid,void *context);
PATCH 2/17 Add supporting functions for metadata areas stored in format instance.
In reply to Peter RajnohaThis patch divides current create_instance functionality into PV-based and VG-based. We add a simple flag "pv_only" in struct format_instance that will help us to identify the type of the format_instance when used later on (since we will always have PV/VG separation, I think it would be useless to define an interface for this where we would attach supporting functions on the fly like we do for mda->ops as an example. In this case, a simple flag is fine to switch the functionality).
Another change is the metadata_areas_index we have in the struct format_instance. To access a certain metadata area, we need to know two keys - PV id and metadta area index within that PV. So a few new functions have been modified/added to support this:
- fid_add_mda (modified)
- fid_add_mdas (modified)
- fid_remove_mda (new)
- fid_get_mda_indexed (new)
Actually, the form of the key that will be used is up to the caller, but he needs to remember the key somehow to get the mda back :)
The key is simply made up of the base key (a string) and a subkey (an unsigned integer). The actual key used internally is then a string:
<basekey>_<subkey>
Now, the metadata_areas_index is format specific. This is because each format can have different number and types of metadata areas it can support and so we'd like to be able to use the most suitable index for the specific format. Also, we can use a different indexing scheme for PV and VG based format_instance.
For PV based format instance in current lvm2 format, we have only 2 metadata areas at maximum. So we use only a simple array. No need to use any buldozer-type indexing here :)
For VG based format instance, we can group many many mdas together from numerous PVs. So we'll use a hash here (like we use for the cache). (but maybe we can add even better indexing in the future!)
If key is not defined, we just store the mda without indexing. We'll have it in the metadata_areas_in_use/ignored list directly.
...but we can change these later if needed, of course. The implementation is internal, the interface stays the same)
Also, I kept the format instance's metadata_areas_in_use/ignored for now, but eventually, I'd like this to be accessed through the index in the future. But that is another step to take later...
--- lib/format1/format1.c | 1 + lib/format_text/format-text.c | 137 ++++++++++++++++++++++++++++---------- lib/format_text/format-text.h | 1 + lib/metadata/metadata-exported.h | 3 + lib/metadata/metadata.c | 103 +++++++++++++++++++++++++++- lib/metadata/metadata.h | 10 ++- 6 files changed, 213 insertions(+), 42 deletions(-)
lib/format1/format1.c +1 -0
@@ -534,6 +534,7 @@ static struct format_instance *_format1_create_instance(const struct format_type return_NULL; fid->fmt = fmt; + fid->metadata_areas_index =NULL ;dm_list_init (&fid->metadata_areas_in_use);dm_list_init (&fid->metadata_areas_ignored);
lib/format_text/format-text.c +101 -36
206 lines not on this page · raw message
lib/format_text/format-text.h +1 -0
@@ -22,6 +22,7 @@#define FMT_TEXT_NAME "lvm2"#define FMT_TEXT_ALIAS "text"#define FMT_TEXT_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_TEXT_NAME) +#define FMT_TEXT_MAX_MDAS_PER_PV 2/* * Archives a vg config. 'retain_days' is the minimum number of
lib/metadata/metadata-exported.h +3 -0
@@ -173,6 +173,8 @@ struct pv_segment {struct format_instance {const struct format_type *fmt; +int pv_only; +/* * Each mda in a vg is on exactly one of the below lists. * MDAs on the 'in_use' list will be read from / written to
@@ -181,6 +183,7 @@ struct format_instance {*/ struct dm_list metadata_areas_in_use;struct dm_list metadata_areas_ignored; +void *metadata_areas_index;void *private; };
lib/metadata/metadata.c +99 -4
128 lines not on this page · raw message
lib/metadata/metadata.h +8 -2
@@ -191,8 +191,14 @@ struct metadata_area *mda_copy(struct dm_pool *mem,unsigned mda_is_ignored (struct metadata_area *mda);void mda_set_ignored (struct metadata_area *mda,unsigned ignored);unsigned mda_locns_match (struct metadata_area *mda1,struct metadata_area *mda2); -void fid_add_mda (struct format_instance *fid,struct metadata_area *mda); -int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas); +int fid_add_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey); +int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas, +const char *key,size_t key_len); +int fid_remove_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey); +struct metadata_area *fid_get_mda_indexed (struct format_instance *fid, +const char *key,size_t key_len,const unsigned subkey);int mdas_empty_or_ignored (struct dm_list *mdas);#define seg_pvseg (seg, s) (seg)->areas[(s)].u.pv.pvseg
Signature · 1 line
1.7.3.4
PATCH 2/17 Add supporting functions for metadata areas stored in format instance.
Quoted 42 lines · Peter Rajnoha
This patch divides current
create_instancefunctionality into PV-based and VG-based. We add a simple flag "pv_only" in structformat_instancethat will help us to identify the type of theformat_instancewhen used later on (since we will always have PV/VG separation, I think it would be useless to define an interface for this where we would attach supporting functions on the fly like we do formda->opsas an example. In this case, a simple flag is fine to switch the functionality).Another change is the
metadata_areas_indexwe have in the structformat_instance. To access a certain metadata area, we need to know two keys - PV id and metadta area index within that PV. So a few new functions have been modified/added to support this:
-fid_add_mda(modified)
-fid_add_mdas(modified)
-fid_remove_mda(new)
-fid_get_mda_indexed(new)Actually, the form of the key that will be used is up to the caller, but he needs to remember the key somehow to get the mda back :)
The key is simply made up of the base key (a string) and a subkey (an unsigned integer). The actual key used internally is then a string:
<basekey>_<subkey>
Now, the
metadata_areas_indexis format specific. This is because each format can have different number and types of metadata areas it can support and so we'd like to be able to use the most suitable index for the specific format. Also, we can use a different indexing scheme for PV and VG basedformat_instance.For PV based format instance in current lvm2 format, we have only 2 metadata areas at maximum. So we use only a simple array. No need to use any buldozer-type indexing here :)
For VG based format instance, we can group many many mdas together from numerous PVs. So we'll use a hash here (like we use for the cache). (but maybe we can add even better indexing in the future!)
If key is not defined, we just store the mda without indexing. We'll have it in the metadata_areas_in_use/ignored list directly.
Quoted 8 lines
...but we can change these later if needed, of course. The implementation is internal, the interface stays the same)
Also, I kept the format instance's metadata_areas_in_use/ignored for now, but eventually, I'd like this to be accessed through the index in the future. But that is another step to take later...
Signed-off-by Peter Rajnoha <[email protected]>
Comments below. I think this patch could be improved. On the other hand, none of the issues are a serious showstopper, but I would definitely like to see at least the pv_only thing addressed before proceeding. (See below.)
Yours,
Petr
Quoted 63 lines
--- lib/format1/format1.c | 1 + lib/format_text/format-text.c | 137 ++++++++++++++++++++++++++++---------- lib/format_text/format-text.h | 1 + lib/metadata/metadata-exported.h | 3 + lib/metadata/metadata.c | 103 +++++++++++++++++++++++++++- lib/metadata/metadata.h | 10 ++- 6 files changed, 213 insertions(+), 42 deletions(-)lib/format1/format1.c +1
-0@@ -534,6 +534,7 @@ static struct format_instance *_format1_create_instance(const struct format_type return_NULL; fid->fmt = fmt; + fid->metadata_areas_index =NULL ;dm_list_init (&fid->metadata_areas_in_use);dm_list_init (&fid->metadata_areas_ignored);lib/format_text/format-text.c +21
-6@@ -48,6 +48,10 @@ struct text_fid_context {uint32_t raw_metadata_buf_size; }; +struct text_fid_pv_context { +int64_t label_sector; +}; +struct dir_list {struct dm_list list;char dir[0 ];@@ -1912,14 +1916,38 @@ static int _text_pv_setup(const struct format_type *fmt, return 1; } -/* NULL vgname means use only the supplied context e.g. an archive file */ -static struct format_instance *_text_create_text_instance (const struct format_type *fmt, -const char *pvid, -const char *vgname, -const char *vgid, -void *context) +static int _create_pv_text_instance(struct format_instance *fid, const char *pvid) +{ + struct text_fid_pv_context *fid_pv_tc; + struct lvmcache_info *info; + + fid->pv_only = 1; + + if (!(fid_pv_tc = (struct text_fid_pv_context *) + dm_pool_zalloc(fid->fmt->cmd->mem, sizeof(*fid_pv_tc)))) { + log_error("Couldn't allocate text_fid_pv_context."); + return 0; + } + fid_pv_tc->label_sector = -1; + fid->private = (void *) fid_pv_tc; + + if (!(fid->metadata_areas_index = dm_pool_zalloc(fid->fmt->cmd->mem, + FMT_TEXT_MAX_MDAS_PER_PV *
lib/format_text/format-text.c static int _text_pv_setup(const struct format_type *fmt, · line 1945
Quoted 10 lines
lib/format_text/format-text.c +10
-0+ sizeof(struct metadata_area *)))) { +log_error ("Couldn't allocate format instance metadata index." ); +return 0 ; + } + +if ((info =info_from_pvid (pvid,0 ))) +fid_add_mdas (fid, &info->mdas, pvid,ID_LEN ); + +return 1 ; +}
OK
Quoted 149 lines
lib/format_text/format-text.c +61
-30+ +static int _create_vg_text_instance (struct format_instance *fid, +const char *vgname,const char *vgid, +void *context) { -struct format_instance *fid;struct text_fid_context *fidtc;struct metadata_area *mda;struct mda_context *mdac;@@ -1930,85 +1958,122 @@ static struct format_instance *_text_create_text_instance(const struct format_tystruct lvmcache_vginfo *vginfo;struct lvmcache_info *info; -if (!(fid =dm_pool_alloc (fmt->cmd->mem,sizeof (*fid)))) { -log_error ("Couldn't allocate format instance object." ); -return NULL ; - } + fid->pv_only =0 ;if (!(fidtc = (struct text_fid_context *) -dm_pool_zalloc (fmt->cmd->mem,sizeof (*fidtc)))) { +dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*fidtc)))) {log_error ("Couldn't allocate text_fid_context." ); -return NULL ; +return 0 ; } fidtc->raw_metadata_buf =NULL ; fid->private = (void *) fidtc; - fid->fmt = fmt; -dm_list_init (&fid->metadata_areas_in_use); -dm_list_init (&fid->metadata_areas_ignored); -if (!vgname) { -if (!(mda =dm_pool_zalloc (fmt->cmd->mem,sizeof (*mda)))) - return_NULL; +if (!(mda =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mda)))) + return_0; mda->ops = &_metadata_text_file_backup_ops; mda->metadata_locn = context; mda->status =0 ; -fid_add_mda (fid, mda); +fid_add_mda (fid, mda,NULL ,0 ,0 ); }else { - dir_list = &((struct mda_lists *) fmt->private)->dirs; +if (!(fid->metadata_areas_index =dm_hash_create (128 ))) { +log_error ("Couldn't create metadata index for format " +"instance of VG %s." , vgname); +return 0 ; + } + + dir_list = &((struct mda_lists *) fid->fmt->private)->dirs; dm_list_iterate_items(dl, dir_list) {if (dm_snprintf (path,PATH_MAX ,"%s/%s" , dl->dir, vgname) <0 ) {log_error ("Name too long %s/%s" , dl->dir, vgname); -return NULL ; +return 0 ; } - context =create_text_context (fmt->cmd, path,NULL ); -if (!(mda =dm_pool_zalloc (fmt->cmd->mem,sizeof (*mda)))) - return_NULL; + context =create_text_context (fid->fmt->cmd, path,NULL ); +if (!(mda =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mda)))) + return_0; mda->ops = &_metadata_text_file_ops; mda->metadata_locn = context; mda->status =0 ; -fid_add_mda (fid, mda); +fid_add_mda (fid, mda,NULL ,0 ,0 ); } - raw_list = &((struct mda_lists *) fmt->private)->raws; + raw_list = &((struct mda_lists *) fid->fmt->private)->raws; dm_list_iterate_items(rl, raw_list) {/* FIXME Cache this; rescan below if some missing */ if (!_raw_holds_vgname (fid, &rl->dev_area, vgname))continue ; -if (!(mda =dm_pool_zalloc (fmt->cmd->mem,sizeof (*mda)))) - return_NULL; +if (!(mda =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mda)))) + return_0; -if (!(mdac =dm_pool_zalloc (fmt->cmd->mem,sizeof (*mdac)))) - return_NULL; +if (!(mdac =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mdac)))) + return_0; mda->metadata_locn = mdac;/* FIXME Allow multiple dev_areas inside area */ memcpy (&mdac->area, &rl->dev_area,sizeof (mdac->area)); mda->ops = &_metadata_text_raw_ops; mda->status =0 ;/* FIXME MISTAKE? mda->metadata_locn = context; */ -fid_add_mda (fid, mda); +fid_add_mda (fid, mda,NULL ,0 ,0 ); }/* Scan PVs in VG for any further MDAs */ -lvmcache_label_scan (fmt->cmd,0 ); +lvmcache_label_scan (fid->fmt->cmd,0 );if (!(vginfo =vginfo_from_vgname (vgname, vgid))) goto_out; dm_list_iterate_items(info, &vginfo->infos) { -if (!fid_add_mdas (fid, &info->mdas)) - return_NULL; +if (!fid_add_mdas (fid, &info->mdas, info->dev->pvid, +ID_LEN )) + return_0; }/* FIXME Check raw metadata area count - rescan if required */ } out: -return fid; +return 1 ; +} + +/* NULL vgname means use only the supplied context e.g. an archive file */ +static struct format_instance *_text_create_text_instance (const struct format_type *fmt, +const char *pvid, +const char *vgname, +const char *vgid, +void *context) +{ +struct format_instance *fid; +int r; + +if (pvid && (vgname || vgid)) { +log_error (INTERNAL_ERROR "Format instance must be PV " +"or VG specific, not both." ); +return NULL ; + } + +if (!(fid =dm_pool_alloc (fmt->cmd->mem,sizeof (*fid)))) { +log_error ("Couldn't allocate format instance object." ); +return NULL ; + } + + fid->fmt = fmt; + fid->metadata_areas_index =NULL ; +dm_list_init (&fid->metadata_areas_in_use); +dm_list_init (&fid->metadata_areas_ignored); +
lib/format_text/format-text.c static struct format_instance *_text_create_text_instance(const struct format_ty · line 2077
Quoted 10 lines
lib/format_text/format-text.c +9
-0+ r = pvid ?_create_pv_text_instance (fid, pvid) : +_create_vg_text_instance (fid, vgname, vgid, context); + +if (r) +return fid; +else { +dm_pool_free (fmt->cmd->mem, fid); +return NULL ; + } }
OK, _text_create_text_instance is split into 3. The changes are relatively straightforward.
Quoted 19 lines
lib/format_text/format-text.c +0
-0void *create_text_context(struct cmd_context *cmd, const char *path,lib/format_text/format-text.h +1
-0@@ -22,6 +22,7 @@#define FMT_TEXT_NAME "lvm2"#define FMT_TEXT_ALIAS "text"#define FMT_TEXT_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_TEXT_NAME) +#define FMT_TEXT_MAX_MDAS_PER_PV 2/* * Archives a vg config. 'retain_days' is the minimum number of lib/metadata/metadata-exported.h +0
-0
lib/metadata/metadata-exported.h struct pv_segment { · line 176
Quoted 4 lines
lib/metadata/metadata-exported.h +1
-0@@ -173,6 +173,8 @@ struct pv_segment {struct format_instance {const struct format_type *fmt; +int pv_only;
Could this be changed to an enumerated "type" field, instead of pv_only? If I understand correctly, types are mutually exclusive anyway, and pv_only is rather confusing and non-obvious when reading the code.
lib/metadata/metadata-exported.h struct format_instance { · line 186
Quoted 9 lines
lib/metadata/metadata-exported.h +2
-0+/* * Each mda in a vg is on exactly one of the below lists. * MDAs on the 'in_use' list will be read from / written to @@ -181,6 +183,7 @@ struct format_instance {*/ struct dm_list metadata_areas_in_use;struct dm_list metadata_areas_ignored; +void *metadata_areas_index;
I don't currently expect that we would need as much genericity as void * offers (and that we could use a little extra safety). Would an union be better here, with an explicit list of types that can go in?
Quoted 23 lines
lib/metadata/metadata-exported.h +0
-0void *private; };lib/metadata/metadata.c +3
-2@@ -2881,7 +2881,8 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,break ; }if (dm_list_size (&info->mdas)) { -if (!fid_add_mdas (fid, &info->mdas)) +if (!fid_add_mdas (fid, &info->mdas, + info->dev->pvid,ID_LEN )) return_NULL;log_debug ("Empty mda found for VG %s." , vgname);@@ -3912,22 +3913,116 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)return FAILED_EXIST ; } -void fid_add_mda (struct format_instance *fid,struct metadata_area *mda) +static int _convert_key_to_string(const char *key, size_t key_len,
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3926
Quoted 10 lines
lib/metadata/metadata.c +9
-0+ unsigned subkey, char *buf, size_t buf_len) { +memcpy (buf ,key ,key_len ); + buf += key_len; + buf_len -= key_len; +if ((dm_snprintf (buf, buf_len,"_%u" , subkey) ==-1 )) + return_0; + +return 1 ; +}
Would it be better to require that key is NULL-terminated? It would simplify a lot of code, by not needing to pass the length as an extra parameter everywhere. I know that currently we keep the PV/VG/... IDs in unterminated strings, but I am quite sure this is not a good idea. I wouldn't expect it to be a *lot* of work to change things to keep a NULL termination in there as well. Maybe in a followup patch?
Quoted 11 lines
lib/metadata/metadata.c +9
-0+int fid_add_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey) +{ +char extended_key[PATH_MAX ]; +dm_list_add (mda_is_ignored (mda) ? &fid->metadata_areas_ignored : &fid->metadata_areas_in_use, &mda->list); + +/* +* Return if the mda is not supposed to be +* indexed or the index itself is not initialised */
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3948
Quoted 10 lines
lib/metadata/metadata.c +10
-0+if (!key || !fid->metadata_areas_index) +return 1 ; + +if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_0; + +/* Add metadata area to index. */ +if (fid->pv_only) + ((struct metadata_area **)fid->metadata_areas_index)[subkey] = mda;
In this branch, all the extended_key logic above is useless. It could be made more obvious that only the else branch needs extended_key, by restructuring the code. Also, is key, subkey and extended_key the right naming scheme? Maybe full_key instead of extended? And maybe sub_key, for consistency?
Quoted 32 lines
lib/metadata/metadata.c +20
-2+else +dm_hash_insert (fid->metadata_areas_index, extended_key, mda); + +return 1 ; } -int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas) +int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas, +const char *key,size_t key_len) {struct metadata_area *mda, *mda_new; +unsigned mda_index =0 ; dm_list_iterate_items(mda, mdas) { mda_new =mda_copy (fid->fmt->cmd->mem, mda);if (!mda_new) return_0; -fid_add_mda (fid, mda_new); + +fid_add_mda (fid, mda_new, key, key_len, mda_index); + mda_index++; } + +return 1 ; +} + +struct metadata_area *fid_get_mda_indexed (struct format_instance *fid, +const char *key,size_t key_len, +const unsigned subkey) +{ +char extended_key[PATH_MAX ]; +struct metadata_area *mda =NULL ;
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3988
Quoted 10 lines
lib/metadata/metadata.c +10
-0+ +if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_NULL; + +if (fid->pv_only) + mda = ((struct metadata_area **)fid->metadata_areas_index)[subkey]; +else + mda = (struct metadata_area *)dm_hash_lookup (fid->metadata_areas_index, + extended_key);
Same about extended_key as above (both path coverage and naming).
Quoted 23 lines
lib/metadata/metadata.c +23
-0+return mda; +} + +int fid_remove_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey) +{ +struct metadata_area *mda_indexed =NULL ; +char extended_key[PATH_MAX ]; + +/* At least one of mda or key must be specified. */ +if (!mda && !key) +return 1 ; + +if (key) { +/* +* If both mda and key specified, check given mda +* with what we find using the index and return +* immediately if these two do not match. +*/ +if (!(mda_indexed =fid_get_mda_indexed (fid, key, key_len, subkey)) || + (mda && mda != mda_indexed)) +return 1 ; +
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 4021
Quoted 10 lines
lib/metadata/metadata.c +10
-0+if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_0; + + mda = mda_indexed; + +if (fid->pv_only) + ((struct metadata_area **)fid->metadata_areas_index)[subkey] =NULL ; +else +dm_hash_remove (fid->metadata_areas_index, extended_key);
Redundant code paths again.
Quoted 28 lines
lib/metadata/metadata.c +4
-0+ } + +dm_list_del (&mda->list); +return 1 ; }lib/metadata/metadata.h +8
-2@@ -191,8 +191,14 @@ struct metadata_area *mda_copy(struct dm_pool *mem,unsigned mda_is_ignored (struct metadata_area *mda);void mda_set_ignored (struct metadata_area *mda,unsigned ignored);unsigned mda_locns_match (struct metadata_area *mda1,struct metadata_area *mda2); -void fid_add_mda (struct format_instance *fid,struct metadata_area *mda); -int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas); +int fid_add_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey); +int fid_add_mdas (struct format_instance *fid,struct dm_list *mdas, +const char *key,size_t key_len); +int fid_remove_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey); +struct metadata_area *fid_get_mda_indexed (struct format_instance *fid, +const char *key,size_t key_len,const unsigned subkey);int mdas_empty_or_ignored (struct dm_list *mdas);#define seg_pvseg (seg, s) (seg)->areas[(s)].u.pv.pvseg
PATCH 2/17 Add supporting functions for metadata areas stored in format instance.
Quoted 8 lines · Petr Rockai
lib/metadata/metadata-exported.h struct pv_segment { · line 176
Quoted 3 lines
struct
format_instance{lib/metadata/metadata-exported.h +1
-0const struct format_type *fmt; +int pv_only;Could this be changed to an enumerated "type" field, instead of
pv_only? If I understand correctly, types are mutually exclusive anyway, andpv_onlyis rather confusing and non-obvious when reading the code.
Yes, these are mutually exclusive and it'll always be only a switch between PV and VG, or I hope so... Using a enumerated type field - OK, no problem, whatever that makes the switch...
Quoted 5 lines
Quoted 5 lines
lib/metadata/metadata-exported.h +1
-0+/* * Each mda in a vg is on exactly one of the below lists. * MDAs on the 'in_use' list will be read from / written to @@ -181,6 +183,7 @@ struct format_instance {
Quoted 9 lines
lib/metadata/metadata-exported.h struct format_instance { · line 186
Quoted 4 lines
lib/metadata/metadata-exported.h +1
-0*/ struct dm_list metadata_areas_in_use;struct dm_list metadata_areas_ignored; +void *metadata_areas_index;I don't currently expect that we would need as much genericity as void * offers (and that we could use a little extra safety). Would an union be better here, with an explicit list of types that can go in?
Well, my incentive here was to keep this for any future changes so the format-specific code can decide and use any type of index we can imagine. We have this "metadata.c" layer and then the "format-specific" layer underneath that. So adding any new format with a brand new indexing scheme that is fine-tuned and suitable for that one new format would require breaking the abstraction layer (so defining a new type of index used in new format in the "metadata.c" layer above). So my incentive was to make the index transparent for the "metadata.c" layer.
(I know, we have these "fid_{add,remove,get}_mda" functions that work directly with the index in "metadata.c" now, but that may eventually evolve into format-specific "fid" functions later. But since we have only one format that actually make real use of the format instance, I kept it in that metadata.c layer for now...)
But if we expect to use the same index scheme all the time for all possible formats, not changing it too much, then sure, we can use a union there... But I'd like to avoid too much editing in the future :)
Quoted 6 lines
Quoted 6 lines
lib/metadata/metadata.c +5
-0+static int _convert_key_to_string (const char *key,size_t key_len, +unsigned subkey,char *buf,size_t buf_len) { +memcpy (buf, key, key_len); + buf += key_len; + buf_len -= key_len;
Quoted 8 lines
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3926
Quoted 5 lines
lib/metadata/metadata.c +5
-0+if ((dm_snprintf (buf, buf_len,"_%u" , subkey) ==-1 )) + return_0; + +return 1 ; +}Would it be better to require that key is NULL-terminated? It would simplify a lot of code, by not needing to pass the length as an extra
...if we can make sure that PV id is always terminated with 0, then OK. But otherwise we would need to call this "convert_to_string" function everywhere around the code (actually that was in my original working version of this patchset, then I decided to put it in one place instead).
Quoted 4 lines
parameter everywhere. I know that currently we keep the PV/VG/... IDs in unterminated strings, but I am quite sure this is not a good idea. I wouldn't expect it to be a *lot* of work to change things to keep a NULL termination in there as well. Maybe in a followup patch?
..thing with PV id is that we store that as a "struct id" which internally is an array of integeres... Hmm, so you want to put another array item with 0 at the end?
BTW, we also do this "convert_to_string" in the cache code... So yes, maybe it would be fine to clean this up somehow...
Quoted 20 lines
Quoted 20 lines
lib/metadata/metadata.c +17
-0+int fid_add_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey) +{ +char extended_key[PATH_MAX ]; +dm_list_add (mda_is_ignored (mda) ? &fid->metadata_areas_ignored : &fid->metadata_areas_in_use, &mda->list); + +/* +* Return if the mda is not supposed to be +* indexed or the index itself is not initialised */ +if (!key || !fid->metadata_areas_index) +return 1 ; + +if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_0; + +/* Add metadata area to index. */
Quoted 9 lines
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3948
Quoted 2 lines
lib/metadata/metadata.c +2
-0+if (fid->pv_only) + ((struct metadata_area **)fid->metadata_areas_index)[subkey] = mda;In this branch, all the
extended_keylogic above is useless. It could be made more obvious that only the else branch needsextended_key, by restructuring the code. Also, is key, subkey andextended_keythe right naming scheme? Maybefull_keyinstead of extended? And maybesub_key, for consistency?
OK...
Quoted 10 lines
Quoted 10 lines
lib/metadata/metadata.c +10
-0+struct metadata_area *fid_get_mda_indexed (struct format_instance *fid, +const char *key,size_t key_len, +const unsigned subkey) +{ +char extended_key[PATH_MAX ]; +struct metadata_area *mda =NULL ; + +if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_NULL;
Quoted 9 lines
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 3988
Quoted 6 lines
lib/metadata/metadata.c +6
-0+ +if (fid->pv_only) + mda = ((struct metadata_area **)fid->metadata_areas_index)[subkey]; +else + mda = (struct metadata_area *)dm_hash_lookup (fid->metadata_areas_index, + extended_key);Same about
extended_keyas above (both path coverage and naming).
OK...
Quoted 24 lines
Quoted 24 lines
lib/metadata/metadata.c +24
-0+int fid_remove_mda (struct format_instance *fid,struct metadata_area *mda, +const char *key,size_t key_len,const unsigned subkey) +{ +struct metadata_area *mda_indexed =NULL ; +char extended_key[PATH_MAX ]; + +/* At least one of mda or key must be specified. */ +if (!mda && !key) +return 1 ; + +if (key) { +/* +* If both mda and key specified, check given mda +* with what we find using the index and return +* immediately if these two do not match. +*/ +if (!(mda_indexed =fid_get_mda_indexed (fid, key, key_len, subkey)) || + (mda && mda != mda_indexed)) +return 1 ; + +if (!_convert_key_to_string (key, key_len, subkey, + extended_key,PATH_MAX )) + return_0; +
Quoted 9 lines
lib/metadata/metadata.c uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname) · line 4021
Quoted 6 lines
lib/metadata/metadata.c +6
-0+ mda = mda_indexed; + +if (fid->pv_only) + ((struct metadata_area **)fid->metadata_areas_index)[subkey] =NULL ; +else +dm_hash_remove (fid->metadata_areas_index, extended_key);Redundant code paths again.
OK... :)
Peter
PATCH 2/17 Add supporting functions for metadata areas stored in format instance.
Quoted 22 lines · Peter Rajnoha
Quoted 6 lines
lib/metadata/metadata-exported.h struct format_instance { · line 186
Quoted 1 line
lib/metadata/metadata-exported.h +1
-0+void *metadata_areas_index;I don't currently expect that we would need as much genericity as void * offers (and that we could use a little extra safety). Would an union be better here, with an explicit list of types that can go in?
Well, my incentive here was to keep this for any future changes so the format-specific code can decide and use any type of index we can imagine. We have this "
metadata.c" layer and then the "format-specific" layer underneath that. So adding any new format with a brand new indexing scheme that is fine-tuned and suitable for that one new format would require breaking the abstraction layer (so defining a new type of index used in new format in the "metadata.c" layer above). So my incentive was to make the index transparent for the "metadata.c" layer.(I know, we have these "fid_{add,remove,get}_mda" functions that work directly with the index in "
metadata.c" now, but that may eventually evolve into format-specific "fid" functions later. But since we have only one format that actually make real use of the format instance, I kept it in thatmetadata.clayer for now...)
Quoted 3 lines
But if we expect to use the same index scheme all the time for all possible formats, not changing it too much, then sure, we can use a union there... But I'd like to avoid too much editing in the future :)
Well, I think you are deluding yourself about that. Plenty of other such things is hard-coded all over the place and I am fairly sure adding an union member is going to be the least of your worries at that point.
I wouldn't say anything if this came for free, but you are obviously trading code safety and maintainability (which are fairly concrete) for easier extendability (which is fairly hypothetical). I would opt for the first, if faced with this kind of a tradeoff. YAGNI (You Aren't Gonna Need It), anyway.
Yours,
Petr
PS: If you want to make the format instance actually opaque, you should move it out of metadata.{h,c} completely, into format_text, and only have an opaque pointer (void * typedef) in VG/PV.
PATCH 2/17 Add supporting functions for metadata areas stored in format instance.
In reply to Peter RajnohaQuoted 11 lines · Peter Rajnoha
Quoted 4 lines
parameter everywhere. I know that currently we keep the PV/VG/... IDs in unterminated strings, but I am quite sure this is not a good idea. I wouldn't expect it to be a *lot* of work to change things to keep a NULL termination in there as well. Maybe in a followup patch?
..thing with PV id is that we store that as a "struct id" which internally is an array of integeres... Hmm, so you want to put another array item with 0 at the end?
BTW, we also do this "
convert_to_string" in the cache code... So yes, maybe it would be fine to clean this up somehow...
Well, I don't see a problem with making the array ID_LEN + 1 instead of ID_LEN and storing a 0 element at the end. It's always used as a character array anyway, and we can save significant amount of boilerplate by having that 0 in there.
Yours,
Petr
PATCH 3/17 Add struct format_instance *fid field to struct physical_volume.
In reply to Peter RajnohaSo PV has also a format instance from now on.
Also, for starters, let's create a new PV-based format_instance in pv_create code.
--- lib/metadata/metadata.c | 7 +++++++ lib/metadata/pv.h | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)
lib/metadata/metadata.c +7 -0
@@ -1547,6 +1547,7 @@ static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *devif (!pv) return_NULL; + pv->fid =NULL ; pv->pe_size =0 ; pv->pe_start =0 ; pv->pe_count =0 ;
@@ -1638,6 +1639,12 @@ struct physical_volume *pv_create(const struct cmd_context *cmd, goto bad; } +if (!(pv->fid = fmt->ops->create_instance (fmt, (const char *) &pv->id, +NULL ,NULL ,NULL ))) { +log_error ("Couldn't create format instance for PV %s." ,pv_dev_name (pv)); + goto bad; + } + pv->fmt = fmt; pv->vg_name = fmt->orphan_vg_name;
lib/metadata/pv.h +1 -0
@@ -24,6 +24,7 @@ struct physical_volume {struct id id;struct device *dev;const struct format_type *fmt; +struct format_instance *fid;/* * vg_name and vgid are used before the parent VG struct exists.
Signature · 1 line
1.7.3.4
PATCH 3/17 Add struct format_instance *fid field to struct physical_volume.
Quoted 3 lines · Peter Rajnoha
So PV has also a format instance from now on.
Also, for starters, let's create a new PV-basedformat_instanceinpv_createcode.
This one is quite straightforward.
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 42 lines
--- lib/metadata/metadata.c | 7 +++++++ lib/metadata/pv.h | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)lib/metadata/metadata.c +7
-0@@ -1547,6 +1547,7 @@ static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *devif (!pv) return_NULL; + pv->fid =NULL ; pv->pe_size =0 ; pv->pe_start =0 ; pv->pe_count =0 ;@@ -1638,6 +1639,12 @@ struct physical_volume *pv_create(const struct cmd_context *cmd, goto bad; } +if (!(pv->fid = fmt->ops->create_instance (fmt, (const char *) &pv->id, +NULL ,NULL ,NULL ))) { +log_error ("Couldn't create format instance for PV %s." ,pv_dev_name (pv)); + goto bad; + } + pv->fmt = fmt; pv->vg_name = fmt->orphan_vg_name;lib/metadata/pv.h +1
-0@@ -24,6 +24,7 @@ struct physical_volume {struct id id;struct device *dev;const struct format_type *fmt; +struct format_instance *fid;/* * vg_name and vgid are used before the parent VG struct exists.
PATCH 4/17 Add format_instance support for pv_read.
In reply to Peter RajnohaWe don't need to store metadata areas in a separate "mdas" parameter since it is in the pv->fid now. If the fid is not defined yet and is NULL, pv_read code will create a new one (if there's no VG fid yet where the metadata areas read off of a PV should be attached to).
--- lib/metadata/metadata.c | 26 +++++++++++++++++++++----- 1 files changed, 21 insertions(+), 5 deletions(-)
lib/metadata/metadata.c +21 -5
@@ -37,6 +37,7 @@static struct physical_volume *_pv_read (struct cmd_context *cmd,struct dm_pool *pvmem,const char *pv_name, +struct format_instance *fid,struct dm_list *mdas,uint64_t *label_sector,int warnings,int scan_label_only);
@@ -166,6 +167,7 @@ void add_pvl_to_vgs(struct volume_group *vg, struct pv_list *pvl)dm_list_add (&vg->pvs, &pvl->list); vg->pv_count++; pvl->pv->vg = vg; + pvl->pv->fid = vg->fid; }void del_pvl_from_vgs (struct volume_group *vg,struct pv_list *pvl)
@@ -1813,7 +1815,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,struct physical_volume *pv;dm_list_init (&mdas); -if (!(pv =_pv_read (cmd, cmd->mem, pv_name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }
@@ -1822,7 +1824,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,/* If a PV has no MDAs - need to search all VGs for it */ if (!scan_vgs_for_pvs (cmd,1 )) return_NULL; -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }
@@ -2644,7 +2646,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, } dm_list_iterate_items(info, &vginfo->infos) { -if (!(pv =_pv_read (cmd, mem,dev_name (info->dev),NULL ,NULL , warnings,0 ))) { +if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), vg->fid, +NULL ,NULL , warnings,0 ))) {continue ; }if (!(pvl =dm_pool_zalloc (mem,sizeof (*pvl)))) {
@@ -3357,13 +3360,14 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name, struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only) { - return _pv_read(cmd, cmd->mem, pv_name, mdas, label_sector, warnings, scan_label_only); + return _pv_read(cmd, cmd->mem, pv_name, NULL, mdas, label_sector, warnings, scan_label_only); }/* FIXME Use label functions instead of PV functions */ static struct physical_volume *_pv_read (struct cmd_context *cmd,struct dm_pool *pvmem,const char *pv_name, +struct format_instance *fid,struct dm_list *mdas,uint64_t *label_sector,int warnings,int scan_label_only)
@@ -3407,6 +3411,18 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,if (!alloc_pv_segment_whole_pv (pvmem, pv)) goto_bad; +if (fid) +fid_add_mdas (fid, &info->mdas, (const char *) &pv->id,ID_LEN ); +else { +if (!(pv->fid = pv->fmt->ops->create_instance (pv->fmt, + (const char *) &pv->id, +NULL ,NULL ,NULL ))) { +log_error ("_pv_read: Couldn't create format instance " +"for PV %s" , pv_name); + goto bad; + } + } +return pv; bad:_free_pv (pvmem, pv);
@@ -4213,5 +4229,5 @@ struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name)struct dm_list mdas;dm_list_init (&mdas); -return _pv_read (cmd, cmd->mem, pv_name, &mdas,NULL ,1 ,0 ); +return _pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ); }
Signature · 1 line
1.7.3.4
PATCH 4/17 Add format_instance support for pv_read.
Quoted 4 lines · Peter Rajnoha
We don't need to store metadata areas in a separate "mdas" parameter since it is in the
pv->fidnow. If the fid is not defined yet and is NULL,pv_readcode will create a new one (if there's no VG fid yet where the metadata areas read off of a PV should be attached to).
This is somewhat hairy... With this patch, it's starting to seem that PV will sometimes point to a VG FID and other times to PV FID. Is there a good reason for that? Is the PV FID only used with orphan PVs?
I think this is something that really needs to be documented. If nothing else, the format_instance type value (as suggested in an earlier comment) should read ORPHAN_PV_FID and VG_FID. It also does raise the question, why we don't always use VG_FID even for orphans, given how we have an orphans VG? Would simply using the orphans VG FID be more consistent overall?
Please also see below.
Quoted 74 lines
--- lib/metadata/metadata.c | 26 +++++++++++++++++++++----- 1 files changed, 21 insertions(+), 5 deletions(-)lib/metadata/metadata.c +10
-4@@ -37,6 +37,7 @@static struct physical_volume *_pv_read (struct cmd_context *cmd,struct dm_pool *pvmem,const char *pv_name, +struct format_instance *fid,struct dm_list *mdas,uint64_t *label_sector,int warnings,int scan_label_only);@@ -166,6 +167,7 @@ void add_pvl_to_vgs(struct volume_group *vg, struct pv_list *pvl)dm_list_add (&vg->pvs, &pvl->list); vg->pv_count++; pvl->pv->vg = vg; + pvl->pv->fid = vg->fid; }void del_pvl_from_vgs (struct volume_group *vg,struct pv_list *pvl)@@ -1813,7 +1815,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,struct physical_volume *pv;dm_list_init (&mdas); -if (!(pv =_pv_read (cmd, cmd->mem, pv_name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }@@ -1822,7 +1824,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,/* If a PV has no MDAs - need to search all VGs for it */ if (!scan_vgs_for_pvs (cmd,1 )) return_NULL; -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }@@ -2644,7 +2646,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, } dm_list_iterate_items(info, &vginfo->infos) { -if (!(pv =_pv_read (cmd, mem,dev_name (info->dev),NULL ,NULL , warnings,0 ))) { +if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), vg->fid, +NULL ,NULL , warnings,0 ))) {continue ; }if (!(pvl =dm_pool_zalloc (mem,sizeof (*pvl)))) {@@ -3357,13 +3360,14 @@ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name, struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only) { - return _pv_read(cmd, cmd->mem, pv_name, mdas, label_sector, warnings, scan_label_only); + return _pv_read(cmd, cmd->mem, pv_name, NULL, mdas, label_sector, warnings, scan_label_only); }/* FIXME Use label functions instead of PV functions */ static struct physical_volume *_pv_read (struct cmd_context *cmd,struct dm_pool *pvmem,const char *pv_name, +struct format_instance *fid,struct dm_list *mdas,uint64_t *label_sector,int warnings,int scan_label_only)@@ -3407,6 +3411,18 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,if (!alloc_pv_segment_whole_pv (pvmem, pv)) goto_bad; +if (fid) +fid_add_mdas (fid, &info->mdas, (const char *) &pv->id,ID_LEN );
lib/metadata/metadata.c static struct physical_volume *_pv_read(struct cmd_context *cmd, · line 3425
Quoted 10 lines
lib/metadata/metadata.c +10
-0+else { +if (!(pv->fid = pv->fmt->ops->create_instance (pv->fmt, + (const char *) &pv->id, +NULL ,NULL ,NULL ))) { +log_error ("_pv_read: Couldn't create format instance " +"for PV %s" , pv_name); + goto bad; + } + } +
The code above is certainly confusing. A comment is needed, explaining what is going on. Please explain that non-NULL "fid" means that this PV belongs to a VG, and the fid variable points to that VG's fid.
Also, why mdas are added to the VG fid, but the (orphan) PV fid is left empty? Should the code read
if (!fid) {
if (!(fid = pv->fid = ...
}fid_add_mdas(fid, ...)
?
If, as I suspect, it's because create_instance adds the MDA's itself, please add a comment to that effect. (Also, is it necessary that create_instance does this? I am not sure it is entirely intuitive...)
lib/metadata/metadata.c struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name) · line 4233
Quoted 10 lines
lib/metadata/metadata.c +1
-1return pv; bad:_free_pv (pvmem, pv);@@ -4213,5 +4229,5 @@ struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name)struct dm_list mdas;dm_list_init (&mdas); -return _pv_read (cmd, cmd->mem, pv_name, &mdas,NULL ,1 ,0 ); +return _pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ); }
Yours,
Petr
PATCH 4/17 Add format_instance support for pv_read.
Quoted 11 lines · Petr Rockai
Quoted 4 lines · Peter Rajnoha
We don't need to store metadata areas in a separate "mdas" parameter since it is in the
pv->fidnow. If the fid is not defined yet and is NULL,pv_readcode will create a new one (if there's no VG fid yet where the metadata areas read off of a PV should be attached to).This is somewhat hairy... With this patch, it's starting to seem that PV will sometimes point to a VG FID and other times to PV FID. Is there a good reason for that? Is the PV FID only used with orphan PVs?
Well, we have plain PVs that are not part of any real VG yet, the orphan. BUT we don't want to group them into an orphan VG (that would require collecting all mdas from all orphan VGs). In this case, we have a pure PV fid defined (this fid will include *only* the mdas on that PV).
Then we have plain PVs that are not part of any real VG yet, but are grouped together into a virtual "orphan" VG. From fid's point of view, this is a VG like any other, so the pv->fid references the VG-based pv->vg->fid.
Then we have PVs that are part of a real VG. These also have the pv->fid referencing the pv->vg->fid.
This way, we can use the pv->fid transparently - we don't actually care whether it is PV-based or VG-based fid, we only need to access the mdas. Whether these mdas are store together in a pool with mdas from other PVs (when in a VG) or they are just standalone mdas from that one PV, we don't care. It makes writing the code easier. We don't need to check that anymore...
Quoted 1 line
I think this is something that really needs to be documented. If nothing
..OK, I'll try to add some comments.
Quoted 2 lines
else, the
format_instancetype value (as suggested in an earlier comment) should readORPHAN_PV_FIDandVG_FID. It also does raise the
Actually, ORPHAN_VG_FID, VG_FID and PV_FID. But since ORPHAN_VG_FID == VG_FID from fid's point of view, we have the separation PV_FID and VG_FID only (which is exactly what the format_instance->pv_only flag is about)
Quoted 1 line
question, why we don't always use
VG_FIDeven for orphans, given how we
E.g. creating a new PV, modifying just one PV etc. - there's no need to group and store all the other mdas that are in that "virtual" orphan VG. If we want to group that for some complex situations, OK. But it's useless for simple modification done only on one PVs (iow, creating orphan VG fid means collecting all mdas from all PVs not in a VG yet. And that could be uselessly time-consuming for simple PV-only operations since we would throw all that information away anyway).
Quoted 3 lines
have an orphans VG? Would simply using the orphans VG FID be more consistent overall?
Please, let's not group into orphan VG where it's not really needed...
Quoted 8 lines
Quoted 8 lines
lib/metadata/metadata.c +8
-0+if (fid) +fid_add_mdas (fid, &info->mdas, (const char *) &pv->id,ID_LEN ); +else { +if (!(pv->fid = pv->fmt->ops->create_instance (pv->fmt, + (const char *) &pv->id, +NULL ,NULL ,NULL ))) { +log_error ("_pv_read: Couldn't create format instance " +"for PV %s" , pv_name);
Quoted 9 lines
lib/metadata/metadata.c static struct physical_volume *_pv_read(struct cmd_context *cmd, · line 3425
Quoted 4 lines
lib/metadata/metadata.c +4
-0+ goto bad; + } + } +The code above is certainly confusing. A comment is needed, explaining what is going on. Please explain that non-NULL "fid" means that this PV belongs to a VG, and the fid variable points to that VG's fid.
It's because this _pv_read could be part of a vg_read (e.g. _vg_read_orphans). So creating a standalone PV fid that would be destroyed immediately and replaced by orphan VG fid would be useless, so it's better to pass the existing fid in. So if it's defined already, we just merge PVs mdas into the fid and if not, we create the new PV-based fid.
Quoted 9 lines
Also, why mdas are added to the VG fid, but the (orphan) PV fid is left empty? Should the code read
if (!fid) { if (!(fid = pv->fid = ... }
fid_add_mdas(fid, ...)
The fid_add_mdas is part of the create_instance fn, so you would call that code twice... (but this is related to the next patch also and I've seen the comment briefly, so I'll reply there :) )
Quoted 6 lines
?
If, as I suspect, it's because
create_instanceadds the MDA's itself, please add a comment to that effect. (Also, is it necessary thatcreate_instancedoes this? I am not sure it is entirely intuitive...)
...
Peter
PATCH 4/17 Add format_instance support for pv_read.
Quoted 1 line · Peter Rajnoha
It's because this
_pv_readcould be part of avg_read(e.g._vg_read_orphans).
..for the other "vg_read", we call the other fn, the _read_pv (_pv_read - read_pv nice :) ). That one already handles the fid through the "fid" parameter and then we call add_pvl_to_vgs which does the job of referencing the pv->fid to pv->vg->fid (the format instance is already done before that where we create the VG-based fid). So everything is tied together nicely...
Peter
PATCH 5/17 Add attach_existing_mdas parameter to create_instance fn.
In reply to Peter RajnohaIf attach_existing_mdas parameter is set, we'll attach any existing metadata areas found in the cache to the format_instance. Otherwise, we will only initialise the format_instance and keep the metadata areas list empty (so we can fill that later if that's needed).
--- lib/cache/lvmcache.c | 2 +- lib/format1/format1.c | 3 ++- lib/format_pool/format_pool.c | 3 ++- lib/format_text/archive.c | 2 +- lib/format_text/archiver.c | 10 ++++++---- lib/format_text/format-text.c | 34 ++++++++++++++++++++-------------- lib/metadata/metadata.c | 27 ++++++++++++++++++++------- lib/metadata/metadata.h | 4 +++- 8 files changed, 55 insertions(+), 30 deletions(-)
lib/cache/lvmcache.c +1 -1
@@ -654,7 +654,7 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)if (!(fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , vginfo->vgname, - vgid,NULL ))) + vgid,NULL ,1 ))) return_NULL;/* Build config tree from vgmetadata, if not yet cached */
lib/format1/format1.c +2 -1
@@ -525,7 +525,8 @@ static struct format_instance *_format1_create_instance(const struct format_type const char *pvid __attribute__((unused)), const char *vgname __attribute__((unused)), const char *vgid __attribute__((unused)), - void *private __attribute__((unused))) + void *private __attribute__((unused)), + int attach_existing_mdas __attribute((unused))) {struct format_instance *fid;struct metadata_area *mda;
lib/format_pool/format_pool.c +2 -1
@@ -252,7 +252,8 @@ static struct format_instance *_pool_create_instance(const struct format_type *f const char *pvid __attribute__((unused)), const char *vgname __attribute__((unused)), const char *vgid __attribute__((unused)), - void *private __attribute__((unused))) + void *private __attribute__((unused)), + int attach_existing_mdas __attribute__((unused))) {struct format_instance *fid;struct metadata_area *mda;
lib/format_text/archive.c +1 -1
@@ -309,7 +309,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)if (!(context =create_text_context (cmd, af->path,NULL )) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create text instance object." );return ; }
lib/format_text/archiver.c +6 -4
@@ -278,7 +278,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,if (!(context =create_text_context (cmd, file, cmd->cmd_line)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create text format object." );return NULL ; }
@@ -299,6 +299,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)struct pv_list *pvl;struct physical_volume *pv;struct lvmcache_info *info; +struct format_instance *fid;/* * FIXME: Check that the PVs referenced in the backup are
@@ -306,11 +307,12 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)*/ /* Attempt to write out using currently active format */ -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , - vg->name,NULL ,NULL ))) { +if (!(fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg->name,NULL ,NULL ,1 ))) {log_error ("Failed to allocate format instance" );return 0 ; } +change_vg_format_instance (vg, fid);/* * Setting vg->old_name to a blank value will explicitly
@@ -398,7 +400,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)if (!(context =create_text_context (cmd, file, desc)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create backup object." );return 0 ; }
lib/format_text/format-text.c +20 -14
@@ -41,7 +41,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tyconst char *pvid, const char *vgname, const char *vgid, - void *context); + void *context, + int attach_existing_mdas);struct text_fid_context {char *raw_metadata_buf;
@@ -1090,7 +1091,7 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)/* FIXME stat file to see if it's changed */ fid =_text_create_text_instance (fmt,NULL ,NULL , -NULL ,NULL ); +NULL ,NULL ,1 );if ((vg =_vg_read_file_name (fid, scanned_vgname, path))) {/* FIXME Store creation host in vg */
@@ -1916,7 +1917,8 @@ static int _text_pv_setup(const struct format_type *fmt,return 1 ; } -static int _create_pv_text_instance (struct format_instance *fid,const char *pvid) +static int _create_pv_text_instance (struct format_instance *fid,const char *pvid, +int attach_existing_mdas) {struct text_fid_pv_context *fid_pv_tc;struct lvmcache_info *info;
@@ -1938,7 +1940,7 @@ static int _create_pv_text_instance(struct format_instance *fid, const char *pvireturn 0 ; } -if ((info =info_from_pvid (pvid,0 ))) +if (attach_existing_mdas && (info =info_from_pvid (pvid,0 )))fid_add_mdas (fid, &info->mdas, pvid,ID_LEN );return 1 ;
@@ -1946,7 +1948,7 @@ static int _create_pv_text_instance(struct format_instance *fid, const char *pvistatic int _create_vg_text_instance (struct format_instance *fid,const char *vgname,const char *vgid, -void *context) +void *context,int attach_existing_mdas) {struct text_fid_context *fidtc;struct metadata_area *mda;
@@ -1969,6 +1971,15 @@ static int _create_vg_text_instance(struct format_instance *fid, fidtc->raw_metadata_buf =NULL ; fid->private = (void *) fidtc; +if (!(fid->metadata_areas_index =dm_hash_create (128 ))) { +log_error ("Couldn't create metadata index for format " +"instance of VG %s." , vgname); +return 0 ; + } + +if (!attach_existing_mdas) + goto out; +if (!vgname) {if (!(mda =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mda)))) return_0;
@@ -1977,12 +1988,6 @@ static int _create_vg_text_instance(struct format_instance *fid, mda->status =0 ;fid_add_mda (fid, mda,NULL ,0 ,0 ); }else { -if (!(fid->metadata_areas_index =dm_hash_create (128 ))) { -log_error ("Couldn't create metadata index for format " -"instance of VG %s." , vgname); -return 0 ; - } - dir_list = &((struct mda_lists *) fid->fmt->private)->dirs; dm_list_iterate_items(dl, dir_list) {
@@ -2044,7 +2049,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tyconst char *pvid, const char *vgname, const char *vgid, - void *context) + void *context, + int attach_existing_mdas) { struct format_instance *fid;int r;
@@ -2065,8 +2071,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tydm_list_init (&fid->metadata_areas_in_use);dm_list_init (&fid->metadata_areas_ignored); - r = pvid ?_create_pv_text_instance (fid, pvid) : -_create_vg_text_instance (fid, vgname, vgid, context); + r = pvid ?_create_pv_text_instance (fid, pvid, attach_existing_mdas) : +_create_vg_text_instance (fid, vgname, vgid, context, attach_existing_mdas);if (r)return fid;
lib/metadata/metadata.c +20 -7
@@ -977,7 +977,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)dm_list_init (&vg->removed_pvs);if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , - vg_name,NULL ,NULL ))) { + vg_name,NULL ,NULL ,1 ))) {log_error ("Failed to create format instance" ); goto bad; }
@@ -1642,7 +1642,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd, }if (!(pv->fid = fmt->ops->create_instance (fmt, (const char *) &pv->id, -NULL ,NULL ,NULL ))) { +NULL ,NULL ,NULL ,0 ))) {log_error ("Couldn't create format instance for PV %s." ,pv_dev_name (pv)); goto bad; }
@@ -2637,10 +2637,13 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, goto bad; } -/* create format instance with appropriate metadata area */ +/* +* Create an empty format instance. Metadata areas +* will be attached using consequent PV read calls. +*/ if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , orphan_vgname,NULL , -NULL ))) { +NULL ,0 ))) {log_error ("Failed to create format instance" ); goto bad; }
@@ -2818,7 +2821,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ,1 ))) {log_error ("Failed to create format instance" );return NULL ; }
@@ -2973,7 +2976,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ,1 ))) {log_error ("Failed to create format instance" );return NULL ; }
@@ -3416,7 +3419,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,else {if (!(pv->fid = pv->fmt->ops->create_instance (pv->fmt, (const char *) &pv->id, -NULL ,NULL ,NULL ))) { +NULL ,NULL ,NULL ,1 ))) {log_error ("_pv_read: Couldn't create format instance " "for PV %s" , pv_name); goto bad;
@@ -3936,6 +3939,16 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)return FAILED_EXIST ; } +void change_vg_format_instance (struct volume_group *vg, +struct format_instance *fid) +{ +struct pv_list *pvl; + + vg->fid = fid; +dm_list_iterate_items (pvl, &vg->pvs) + pvl->pv->fid = fid; +} +static int _convert_key_to_string (const char *key,size_t key_len,unsigned subkey,char *buf,size_t buf_len) {
lib/metadata/metadata.h +3 -1
@@ -191,6 +191,7 @@ struct metadata_area *mda_copy(struct dm_pool *mem,unsigned mda_is_ignored (struct metadata_area *mda);void mda_set_ignored (struct metadata_area *mda,unsigned ignored);unsigned mda_locns_match (struct metadata_area *mda1,struct metadata_area *mda2); +void change_vg_format_instance (struct volume_group *vg,struct format_instance *fid);int fid_add_mda (struct format_instance *fid,struct metadata_area *mda,const char *key,size_t key_len,const unsigned subkey); int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas,
@@ -289,7 +290,8 @@ struct format_handler {const char *pvid, const char *vgname, const char *vgid, - void *context); + void *context, + int attach_existing_mdas);/* * Destructor for format instance
Signature · 1 line
1.7.3.4
PATCH 5/17 Add attach_existing_mdas parameter to create_instance fn.
Quoted 4 lines · Peter Rajnoha
If
attach_existing_mdasparameter is set, we'll attach any existing metadata areas found in the cache to theformat_instance. Otherwise, we will only initialise theformat_instanceand keep the metadata areas list empty (so we can fill that later if that's needed).
As hinted in previous comment, I think it would be better to never attach existing MDAs in create_instance and simply have a single call to do that when it is needed. create_instance parameter list is already a mess...
Yours,
Petr
Quoted 317 lines
Signed-off-by Peter Rajnoha <[email protected]>--- lib/cache/lvmcache.c | 2 +- lib/format1/format1.c | 3 ++- lib/format_pool/format_pool.c | 3 ++- lib/format_text/archive.c | 2 +- lib/format_text/archiver.c | 10 ++++++---- lib/format_text/format-text.c | 34 ++++++++++++++++++++-------------- lib/metadata/metadata.c | 27 ++++++++++++++++++++------- lib/metadata/metadata.h | 4 +++- 8 files changed, 55 insertions(+), 30 deletions(-)lib/cache/lvmcache.c +1
-1@@ -654,7 +654,7 @@ struct volume_group *lvmcache_get_vg(const char *vgid, unsigned precommitted)if (!(fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , vginfo->vgname, - vgid,NULL ))) + vgid,NULL ,1 ))) return_NULL;/* Build config tree from vgmetadata, if not yet cached */ lib/format1/format1.c +2
-1@@ -525,7 +525,8 @@ static struct format_instance *_format1_create_instance(const struct format_type const char *pvid __attribute__((unused)), const char *vgname __attribute__((unused)), const char *vgid __attribute__((unused)), - void *private __attribute__((unused))) + void *private __attribute__((unused)), + int attach_existing_mdas __attribute((unused))) {struct format_instance *fid;struct metadata_area *mda;lib/format_pool/format_pool.c +2
-1@@ -252,7 +252,8 @@ static struct format_instance *_pool_create_instance(const struct format_type *f const char *pvid __attribute__((unused)), const char *vgname __attribute__((unused)), const char *vgid __attribute__((unused)), - void *private __attribute__((unused))) + void *private __attribute__((unused)), + int attach_existing_mdas __attribute__((unused))) {struct format_instance *fid;struct metadata_area *mda;lib/format_text/archive.c +1
-1@@ -309,7 +309,7 @@ static void _display_archive(struct cmd_context *cmd, struct archive_file *af)if (!(context =create_text_context (cmd, af->path,NULL )) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create text instance object." );return ; }lib/format_text/archiver.c +6
-4@@ -278,7 +278,7 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,if (!(context =create_text_context (cmd, file, cmd->cmd_line)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create text format object." );return NULL ; }@@ -299,6 +299,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)struct pv_list *pvl;struct physical_volume *pv;struct lvmcache_info *info; +struct format_instance *fid;/* * FIXME: Check that the PVs referenced in the backup are @@ -306,11 +307,12 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)*/ /* Attempt to write out using currently active format */ -if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , - vg->name,NULL ,NULL ))) { +if (!(fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , + vg->name,NULL ,NULL ,1 ))) {log_error ("Failed to allocate format instance" );return 0 ; } +change_vg_format_instance (vg, fid);/* * Setting vg->old_name to a blank value will explicitly @@ -398,7 +400,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)if (!(context =create_text_context (cmd, file, desc)) || !(tf = cmd->fmt_backup->ops->create_instance (cmd->fmt_backup,NULL , -NULL ,NULL , context))) { +NULL ,NULL , context,1 ))) {log_error ("Couldn't create backup object." );return 0 ; }lib/format_text/format-text.c +20
-14@@ -41,7 +41,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tyconst char *pvid, const char *vgname, const char *vgid, - void *context); + void *context, + int attach_existing_mdas);struct text_fid_context {char *raw_metadata_buf;@@ -1090,7 +1091,7 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)/* FIXME stat file to see if it's changed */ fid =_text_create_text_instance (fmt,NULL ,NULL , -NULL ,NULL ); +NULL ,NULL ,1 );if ((vg =_vg_read_file_name (fid, scanned_vgname, path))) {/* FIXME Store creation host in vg */ @@ -1916,7 +1917,8 @@ static int _text_pv_setup(const struct format_type *fmt,return 1 ; } -static int _create_pv_text_instance (struct format_instance *fid,const char *pvid) +static int _create_pv_text_instance (struct format_instance *fid,const char *pvid, +int attach_existing_mdas) {struct text_fid_pv_context *fid_pv_tc;struct lvmcache_info *info;@@ -1938,7 +1940,7 @@ static int _create_pv_text_instance(struct format_instance *fid, const char *pvireturn 0 ; } -if ((info =info_from_pvid (pvid,0 ))) +if (attach_existing_mdas && (info =info_from_pvid (pvid,0 )))fid_add_mdas (fid, &info->mdas, pvid,ID_LEN );return 1 ;@@ -1946,7 +1948,7 @@ static int _create_pv_text_instance(struct format_instance *fid, const char *pvistatic int _create_vg_text_instance (struct format_instance *fid,const char *vgname,const char *vgid, -void *context) +void *context,int attach_existing_mdas) {struct text_fid_context *fidtc;struct metadata_area *mda;@@ -1969,6 +1971,15 @@ static int _create_vg_text_instance(struct format_instance *fid, fidtc->raw_metadata_buf =NULL ; fid->private = (void *) fidtc; +if (!(fid->metadata_areas_index =dm_hash_create (128 ))) { +log_error ("Couldn't create metadata index for format " +"instance of VG %s." , vgname); +return 0 ; + } + +if (!attach_existing_mdas) + goto out; +if (!vgname) {if (!(mda =dm_pool_zalloc (fid->fmt->cmd->mem,sizeof (*mda)))) return_0;@@ -1977,12 +1988,6 @@ static int _create_vg_text_instance(struct format_instance *fid, mda->status =0 ;fid_add_mda (fid, mda,NULL ,0 ,0 ); }else { -if (!(fid->metadata_areas_index =dm_hash_create (128 ))) { -log_error ("Couldn't create metadata index for format " -"instance of VG %s." , vgname); -return 0 ; - } - dir_list = &((struct mda_lists *) fid->fmt->private)->dirs; dm_list_iterate_items(dl, dir_list) {@@ -2044,7 +2049,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tyconst char *pvid, const char *vgname, const char *vgid, - void *context) + void *context, + int attach_existing_mdas) { struct format_instance *fid;int r;@@ -2065,8 +2071,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tydm_list_init (&fid->metadata_areas_in_use);dm_list_init (&fid->metadata_areas_ignored); - r = pvid ?_create_pv_text_instance (fid, pvid) : -_create_vg_text_instance (fid, vgname, vgid, context); + r = pvid ?_create_pv_text_instance (fid, pvid, attach_existing_mdas) : +_create_vg_text_instance (fid, vgname, vgid, context, attach_existing_mdas);if (r)return fid;lib/metadata/metadata.c +20
-7@@ -977,7 +977,7 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)dm_list_init (&vg->removed_pvs);if (!(vg->fid = cmd->fmt->ops->create_instance (cmd->fmt,NULL , - vg_name,NULL ,NULL ))) { + vg_name,NULL ,NULL ,1 ))) {log_error ("Failed to create format instance" ); goto bad; }@@ -1642,7 +1642,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd, }if (!(pv->fid = fmt->ops->create_instance (fmt, (const char *) &pv->id, -NULL ,NULL ,NULL ))) { +NULL ,NULL ,NULL ,0 ))) {log_error ("Couldn't create format instance for PV %s." ,pv_dev_name (pv)); goto bad; }@@ -2637,10 +2637,13 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, goto bad; } -/* create format instance with appropriate metadata area */ +/* +* Create an empty format instance. Metadata areas +* will be attached using consequent PV read calls. +*/ if (!(vg->fid = vginfo->fmt->ops->create_instance (vginfo->fmt,NULL , orphan_vgname,NULL , -NULL ))) { +NULL ,0 ))) {log_error ("Failed to create format instance" ); goto bad; }@@ -2818,7 +2821,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ,1 ))) {log_error ("Failed to create format instance" );return NULL ; }@@ -2973,7 +2976,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd, use_precommitted =0 ;/* create format instance with appropriate metadata area */ -if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ))) { +if (!(fid = fmt->ops->create_instance (fmt,NULL , vgname, vgid,NULL ,1 ))) {log_error ("Failed to create format instance" );return NULL ; }@@ -3416,7 +3419,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,else {if (!(pv->fid = pv->fmt->ops->create_instance (pv->fmt, (const char *) &pv->id, -NULL ,NULL ,NULL ))) { +NULL ,NULL ,NULL ,1 ))) {log_error ("_pv_read: Couldn't create format instance " "for PV %s" , pv_name); goto bad;@@ -3936,6 +3939,16 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)return FAILED_EXIST ; } +void change_vg_format_instance (struct volume_group *vg, +struct format_instance *fid) +{ +struct pv_list *pvl; + + vg->fid = fid; +dm_list_iterate_items (pvl, &vg->pvs) + pvl->pv->fid = fid; +} +static int _convert_key_to_string (const char *key,size_t key_len,unsigned subkey,char *buf,size_t buf_len) {lib/metadata/metadata.h +3
-1@@ -191,6 +191,7 @@ struct metadata_area *mda_copy(struct dm_pool *mem,unsigned mda_is_ignored (struct metadata_area *mda);void mda_set_ignored (struct metadata_area *mda,unsigned ignored);unsigned mda_locns_match (struct metadata_area *mda1,struct metadata_area *mda2); +void change_vg_format_instance (struct volume_group *vg,struct format_instance *fid);int fid_add_mda (struct format_instance *fid,struct metadata_area *mda,const char *key,size_t key_len,const unsigned subkey); int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas,@@ -289,7 +290,8 @@ struct format_handler {const char *pvid, const char *vgname, const char *vgid, - void *context); + void *context, + int attach_existing_mdas);/* * Destructor for format instance
PATCH 5/17 Add attach_existing_mdas parameter to create_instance fn.
Quoted 12 lines · Petr Rockai
Quoted 4 lines · Peter Rajnoha
If
attach_existing_mdasparameter is set, we'll attach any existing metadata areas found in the cache to theformat_instance. Otherwise, we will only initialise theformat_instanceand keep the metadata areas list empty (so we can fill that later if that's needed).As hinted in previous comment, I think it would be better to never attach existing MDAs in
create_instanceand simply have a single call to do that when it is needed.create_instanceparameter list is already a mess...
...
Quoted 8 lines
lib/format_text/format-text.c static struct format_instance *_text_create_text_instance(const struct format_ty · line 46
Quoted 8 lines
lib/format_text/format-text.c +2
-1@@ -41,7 +41,8 @@ static struct format_instance *_text_create_text_instance(const struct format_tyconst char *pvid, const char *vgname, const char *vgid, - void *context); + void *context, + int attach_existing_mdas);
Yes, I was thinking whether we should separate these somehow first - at least pv_create_instance/vg_create_instance... Hmm. But that's a detail. As for the other parameters - vgname/vgid is necessary and context - well I'm afraid we need that too to handle those special cases with (current) format - the location of the mda in filesystem (metadata backup...).
The "attach_existing_mdas" vs. calling separate function to fill the format instance with mdas - hmm, I'll think about that and see how it fits in...
Peter
PATCH 6/17 Remove useless mdas parameter from PV read functions.
In reply to Peter Rajnoha...metadata areas are now stored within pv->fid.
--- lib/format1/format1.c | 3 +-- lib/format_pool/format_pool.c | 1 - lib/format_text/format-text.c | 15 +-------------- lib/metadata/metadata-exported.h | 4 ++-- lib/metadata/metadata.c | 37 +++++++++++++------------------------ lib/metadata/metadata.h | 3 +-- tools/pvremove.c | 10 ++++------ tools/pvresize.c | 8 +++----- tools/toollib.c | 14 ++++++-------- 9 files changed, 31 insertions(+), 64 deletions(-)
lib/format1/format1.c +1 -2
@@ -331,8 +331,7 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v }static int _format1_pv_read (const struct format_type *fmt,const char *pv_name, -struct physical_volume *pv,struct dm_list *mdas __attribute__((unused)), -int scan_label_only __attribute__((unused))) +struct physical_volume *pv,int scan_label_only __attribute__((unused))) {struct dm_pool *mem =dm_pool_create ("lvm1 pv_read" ,1024 );struct disk_list *dl;
lib/format_pool/format_pool.c +0 -1
@@ -206,7 +206,6 @@ static int _pool_pv_setup(const struct format_type *fmt __attribute__((unused)),static int _pool_pv_read (const struct format_type *fmt,const char *pv_name,struct physical_volume *pv, -struct dm_list *mdas __attribute__((unused)),int scan_label_only __attribute__((unused))) {struct dm_pool *mem =dm_pool_create ("pool pv_read" ,1024 );
lib/format_text/format-text.c +1 -14
@@ -1669,10 +1669,8 @@ static uint64_t _metadata_locn_offset_raw(void *metadata_locn) }static int _text_pv_read (const struct format_type *fmt,const char *pv_name, -struct physical_volume *pv,struct dm_list *mdas, -int scan_label_only) +struct physical_volume *pv,int scan_label_only) { -struct metadata_area *mda, *mda_new;struct label *label;struct device *dev;struct lvmcache_info *info;
@@ -1687,17 +1685,6 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,if (!_populate_pv_fields (info, pv, scan_label_only))return 0 ; -if (!mdas) -return 1 ; - -/* Add copy of mdas to supplied list */ - dm_list_iterate_items(mda, &info->mdas) { - mda_new =mda_copy (fmt->cmd->mem, mda); -if (!mda_new) -return 0 ; -dm_list_add (mdas, &mda_new->list); - } -return 1 ; }
lib/metadata/metadata-exported.h +2 -2
@@ -340,8 +340,8 @@ int vg_revert(struct volume_group *vg);struct volume_group *vg_read_internal (struct cmd_context *cmd,const char *vg_name,const char *vgid,int warnings,int *consistent);struct physical_volume *pv_read (struct cmd_context *cmd,const char *pv_name, -struct dm_list *mdas,uint64_t *label_sector, -int warnings,int scan_label_only); +uint64_t *label_sector,int warnings, +int scan_label_only);struct dm_list *get_pvs (struct cmd_context *cmd);/*
lib/metadata/metadata.c +13 -24
@@ -38,7 +38,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only);
@@ -1330,14 +1329,11 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name, {struct physical_volume *pv;struct device *dev; -struct dm_list mdas; - -dm_list_init (&mdas);/* FIXME Check partition type is LVM unless --force is given */ /* Is there a pv here already? */ - pv =pv_read (cmd, name, &mdas,NULL ,0 ,0 ); + pv =pv_read (cmd, name,NULL ,0 ,0 );/* * If a PV has no MDAs it may appear to be an orphan until the
@@ -1345,10 +1341,10 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,* this means checking every VG by scanning every PV on the * system. */ -if (pv &&is_orphan (pv) &&mdas_empty_or_ignored (&mdas)) { +if (pv &&is_orphan (pv) && !dm_list_size (&pv->fid->metadata_areas_in_use)) {if (!scan_vgs_for_pvs (cmd,0 )) return_0; - pv =pv_read (cmd, name,NULL ,NULL ,0 ,0 ); + pv =pv_read (cmd, name,NULL ,0 ,0 ); }/* Allow partial & exported VGs to be destroyed. */
@@ -1811,20 +1807,18 @@ struct physical_volume *find_pv_by_name(struct cmd_context *cmd,static struct physical_volume *_find_pv_by_name (struct cmd_context *cmd,const char *pv_name) { -struct dm_list mdas;struct physical_volume *pv; -dm_list_init (&mdas); -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; } -if (is_orphan_vg (pv->vg_name) &&mdas_empty_or_ignored (&mdas)) { +if (is_orphan_vg (pv->vg_name) && !dm_list_size (&pv->fid->metadata_areas_in_use)) {/* If a PV has no MDAs - need to search all VGs for it */ if (!scan_vgs_for_pvs (cmd,1 )) return_NULL; -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }
@@ -2649,8 +2643,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, } dm_list_iterate_items(info, &vginfo->infos) { -if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), vg->fid, -NULL ,NULL , warnings,0 ))) { +if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), + vg->fid,NULL , warnings,0 ))) {continue ; }if (!(pvl =dm_pool_zalloc (mem,sizeof (*pvl)))) {
@@ -3360,10 +3354,10 @@ const char *find_vgname_from_pvname(struct cmd_context *cmd,* FIXME - liblvm todo - make into function that returns handle */ struct physical_volume *pv_read (struct cmd_context *cmd,const char *pv_name, -struct dm_list *mdas,uint64_t *label_sector, -int warnings,int scan_label_only) +uint64_t *label_sector,int warnings, +int scan_label_only) { -return _pv_read (cmd, cmd->mem, pv_name,NULL , mdas, label_sector, warnings, scan_label_only); +return _pv_read (cmd, cmd->mem, pv_name,NULL , label_sector, warnings, scan_label_only); }/* FIXME Use label functions instead of PV functions */
@@ -3371,7 +3365,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only) {
@@ -3401,8 +3394,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, }/* FIXME Move more common code up here */ -if (!(info->fmt->ops->pv_read (info->fmt, pv_name, pv, mdas, - scan_label_only))) { +if (!(info->fmt->ops->pv_read (info->fmt, pv_name, pv, scan_label_only))) {log_error ("Failed to read existing physical volume '%s'" , pv_name); goto bad;
@@ -4239,8 +4231,5 @@ char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags)*/ struct physical_volume *pv_by_path (struct cmd_context *cmd,const char *pv_name) { -struct dm_list mdas; - -dm_list_init (&mdas); -return _pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ); +return _pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ); }
lib/metadata/metadata.h +1 -2
@@ -241,8 +241,7 @@ struct format_handler {* Return PV with given path. */ int (*pv_read) (const struct format_type * fmt,const char *pv_name, -struct physical_volume * pv,struct dm_list *mdas, -int scan_label_only); +struct physical_volume * pv,int scan_label_only);/* * Tweak an already filled out a pv ready for importing into a
tools/pvremove.c +4 -6
@@ -25,15 +25,12 @@ const char _really_wipe[] =static int pvremove_check (struct cmd_context *cmd,const char *name) {struct physical_volume *pv; -struct dm_list mdas; - -dm_list_init (&mdas);/* FIXME Check partition type is LVM unless --force is given */ /* Is there a pv here already? */ /* If not, this is an error unless you used -f. */ -if (!(pv =pv_read (cmd, name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, name,NULL ,1 ,0 ))) {if (arg_count (cmd, force_ARG))return 1 ;log_error ("Physical Volume %s not found" , name);
@@ -47,13 +44,14 @@ static int pvremove_check(struct cmd_context *cmd, const char *name)* means checking every VG by scanning every * PV on the system. */ -if (is_orphan (pv) && !dm_list_size (&mdas)) { +if (is_orphan (pv) && !dm_list_size (&pv->fid->metadata_areas_in_use) && + !dm_list_size (&pv->fid->metadata_areas_ignored)) {if (!scan_vgs_for_pvs (cmd,0 )) {log_error ("Rescan for PVs without metadata areas " "failed." );return 0 ; } -if (!(pv =pv_read (cmd, name,NULL ,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, name,NULL ,1 ,0 ))) {log_error ("Failed to read physical volume %s" , name);return 0 ; }
tools/pvresize.c +3 -5
@@ -32,28 +32,26 @@ static int _pv_resize_single(struct cmd_context *cmd,uint64_t size =0 ;uint32_t new_pe_count =0 ;int r =0 ; -struct dm_list mdas;const char *pv_name =pv_dev_name (pv);const char *vg_name =pv_vg_name (pv);struct lvmcache_info *info;int mda_count =0 ;struct volume_group *old_vg = vg; -dm_list_init (&mdas); -if (is_orphan_vg (vg_name)) {if (!lock_vol (cmd, vg_name,LCK_VG_WRITE )) {log_error ("Can't get lock for orphans" );return 0 ; } -if (!(pv =pv_read (cmd, pv_name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, pv_name,NULL ,1 ,0 ))) {unlock_vg (cmd, vg_name);log_error ("Unable to read PV \"%s\"" , pv_name);return 0 ; } - mda_count =dm_list_size (&mdas); + mda_count =dm_list_size (&pv->fid->metadata_areas_in_use) + +dm_list_size (&pv->fid->metadata_areas_ignored); }else { vg =vg_read_for_update (cmd, vg_name,NULL ,0 );
tools/toollib.c +6 -8
@@ -640,7 +640,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle, }while ((dev =dev_iter_get (iter))) { -if (!(pv =pv_read (cmd,dev_name (dev),NULL ,NULL ,0 ,0 ))) { +if (!(pv =pv_read (cmd,dev_name (dev),NULL ,0 ,0 ))) {memset (&pv_dummy,0 ,sizeof (pv_dummy));dm_list_init (&pv_dummy.tags);dm_list_init (&pv_dummy.segments);
@@ -682,7 +682,6 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,struct str_list *sll;char *at_sign, *tagname;int scanned =0 ; -struct dm_list mdas;dm_list_init (&tags);
@@ -724,10 +723,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, } pv = pvl->pv; }else { - -dm_list_init (&mdas); -if (!(pv =pv_read (cmd, argv[opt], &mdas, -NULL ,1 , scan_label_only))) { +if (!(pv =pv_read (cmd, argv[opt],NULL , +1 , scan_label_only))) {log_error ("Failed to read physical " "volume \"%s\"" , argv[opt]); ret_max =ECMD_FAILED ;
@@ -742,7 +739,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,* PV on the system. */ if (!scanned &&is_orphan (pv) && - !dm_list_size (&mdas)) { + !dm_list_size (&pv->fid->metadata_areas_in_use) && + !dm_list_size (&pv->fid->metadata_areas_ignored)) {if (!scan_label_only && !scan_vgs_for_pvs (cmd,1 )) { stack;
@@ -751,7 +749,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, } scanned =1 ;if (!(pv =pv_read (cmd, argv[opt], -NULL ,NULL ,1 , +NULL ,1 , scan_label_only))) {log_error ("Failed to read " "physical volume "
Signature · 1 line
1.7.3.4
PATCH 6/17 Remove useless mdas parameter from PV read functions.
Quoted 1 line · Peter Rajnoha
...metadata areas are now stored within
pv->fid.
looks OK
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 346 lines
--- lib/format1/format1.c | 3 +-- lib/format_pool/format_pool.c | 1 - lib/format_text/format-text.c | 15 +-------------- lib/metadata/metadata-exported.h | 4 ++-- lib/metadata/metadata.c | 37 +++++++++++++------------------------ lib/metadata/metadata.h | 3 +-- tools/pvremove.c | 10 ++++------ tools/pvresize.c | 8 +++----- tools/toollib.c | 14 ++++++-------- 9 files changed, 31 insertions(+), 64 deletions(-)lib/format1/format1.c +1
-2@@ -331,8 +331,7 @@ static int _format1_vg_write(struct format_instance *fid, struct volume_group *v }static int _format1_pv_read (const struct format_type *fmt,const char *pv_name, -struct physical_volume *pv,struct dm_list *mdas __attribute__((unused)), -int scan_label_only __attribute__((unused))) +struct physical_volume *pv,int scan_label_only __attribute__((unused))) {struct dm_pool *mem =dm_pool_create ("lvm1 pv_read" ,1024 );struct disk_list *dl;lib/format_pool/format_pool.c +0
-1@@ -206,7 +206,6 @@ static int _pool_pv_setup(const struct format_type *fmt __attribute__((unused)),static int _pool_pv_read (const struct format_type *fmt,const char *pv_name,struct physical_volume *pv, -struct dm_list *mdas __attribute__((unused)),int scan_label_only __attribute__((unused))) {struct dm_pool *mem =dm_pool_create ("pool pv_read" ,1024 );lib/format_text/format-text.c +1
-14@@ -1669,10 +1669,8 @@ static uint64_t _metadata_locn_offset_raw(void *metadata_locn) }static int _text_pv_read (const struct format_type *fmt,const char *pv_name, -struct physical_volume *pv,struct dm_list *mdas, -int scan_label_only) +struct physical_volume *pv,int scan_label_only) { -struct metadata_area *mda, *mda_new;struct label *label;struct device *dev;struct lvmcache_info *info;@@ -1687,17 +1685,6 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,if (!_populate_pv_fields (info, pv, scan_label_only))return 0 ; -if (!mdas) -return 1 ; - -/* Add copy of mdas to supplied list */ - dm_list_iterate_items(mda, &info->mdas) { - mda_new =mda_copy (fmt->cmd->mem, mda); -if (!mda_new) -return 0 ; -dm_list_add (mdas, &mda_new->list); - } -return 1 ; }lib/metadata/metadata-exported.h +2
-2@@ -340,8 +340,8 @@ int vg_revert(struct volume_group *vg);struct volume_group *vg_read_internal (struct cmd_context *cmd,const char *vg_name,const char *vgid,int warnings,int *consistent);struct physical_volume *pv_read (struct cmd_context *cmd,const char *pv_name, -struct dm_list *mdas,uint64_t *label_sector, -int warnings,int scan_label_only); +uint64_t *label_sector,int warnings, +int scan_label_only);struct dm_list *get_pvs (struct cmd_context *cmd);/* lib/metadata/metadata.c +13
-24@@ -38,7 +38,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only);@@ -1330,14 +1329,11 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name, {struct physical_volume *pv;struct device *dev; -struct dm_list mdas; - -dm_list_init (&mdas);/* FIXME Check partition type is LVM unless --force is given */ /* Is there a pv here already? */ - pv =pv_read (cmd, name, &mdas,NULL ,0 ,0 ); + pv =pv_read (cmd, name,NULL ,0 ,0 );/* * If a PV has no MDAs it may appear to be an orphan until the @@ -1345,10 +1341,10 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,* this means checking every VG by scanning every PV on the * system. */ -if (pv &&is_orphan (pv) &&mdas_empty_or_ignored (&mdas)) { +if (pv &&is_orphan (pv) && !dm_list_size (&pv->fid->metadata_areas_in_use)) {if (!scan_vgs_for_pvs (cmd,0 )) return_0; - pv =pv_read (cmd, name,NULL ,NULL ,0 ,0 ); + pv =pv_read (cmd, name,NULL ,0 ,0 ); }/* Allow partial & exported VGs to be destroyed. */ @@ -1811,20 +1807,18 @@ struct physical_volume *find_pv_by_name(struct cmd_context *cmd,static struct physical_volume *_find_pv_by_name (struct cmd_context *cmd,const char *pv_name) { -struct dm_list mdas;struct physical_volume *pv; -dm_list_init (&mdas); -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; } -if (is_orphan_vg (pv->vg_name) &&mdas_empty_or_ignored (&mdas)) { +if (is_orphan_vg (pv->vg_name) && !dm_list_size (&pv->fid->metadata_areas_in_use)) {/* If a PV has no MDAs - need to search all VGs for it */ if (!scan_vgs_for_pvs (cmd,1 )) return_NULL; -if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,NULL ,1 ,0 ))) { +if (!(pv =_pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ))) {log_error ("Physical volume %s not found" , pv_name);return NULL ; }@@ -2649,8 +2643,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, } dm_list_iterate_items(info, &vginfo->infos) { -if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), vg->fid, -NULL ,NULL , warnings,0 ))) { +if (!(pv =_pv_read (cmd, mem,dev_name (info->dev), + vg->fid,NULL , warnings,0 ))) {continue ; }if (!(pvl =dm_pool_zalloc (mem,sizeof (*pvl)))) {@@ -3360,10 +3354,10 @@ const char *find_vgname_from_pvname(struct cmd_context *cmd,* FIXME - liblvm todo - make into function that returns handle */ struct physical_volume *pv_read (struct cmd_context *cmd,const char *pv_name, -struct dm_list *mdas,uint64_t *label_sector, -int warnings,int scan_label_only) +uint64_t *label_sector,int warnings, +int scan_label_only) { -return _pv_read (cmd, cmd->mem, pv_name,NULL , mdas, label_sector, warnings, scan_label_only); +return _pv_read (cmd, cmd->mem, pv_name,NULL , label_sector, warnings, scan_label_only); }/* FIXME Use label functions instead of PV functions */ @@ -3371,7 +3365,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd,struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - struct dm_list *mdas, uint64_t *label_sector, int warnings, int scan_label_only) {@@ -3401,8 +3394,7 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, }/* FIXME Move more common code up here */ -if (!(info->fmt->ops->pv_read (info->fmt, pv_name, pv, mdas, - scan_label_only))) { +if (!(info->fmt->ops->pv_read (info->fmt, pv_name, pv, scan_label_only))) {log_error ("Failed to read existing physical volume '%s'" , pv_name); goto bad;@@ -4239,8 +4231,5 @@ char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags)*/ struct physical_volume *pv_by_path (struct cmd_context *cmd,const char *pv_name) { -struct dm_list mdas; - -dm_list_init (&mdas); -return _pv_read (cmd, cmd->mem, pv_name,NULL , &mdas,NULL ,1 ,0 ); +return _pv_read (cmd, cmd->mem, pv_name,NULL ,NULL ,1 ,0 ); }lib/metadata/metadata.h +1
-2@@ -241,8 +241,7 @@ struct format_handler {* Return PV with given path. */ int (*pv_read) (const struct format_type * fmt,const char *pv_name, -struct physical_volume * pv,struct dm_list *mdas, -int scan_label_only); +struct physical_volume * pv,int scan_label_only);/* * Tweak an already filled out a pv ready for importing into a tools/pvremove.c +4
-6@@ -25,15 +25,12 @@ const char _really_wipe[] =static int pvremove_check (struct cmd_context *cmd,const char *name) {struct physical_volume *pv; -struct dm_list mdas; - -dm_list_init (&mdas);/* FIXME Check partition type is LVM unless --force is given */ /* Is there a pv here already? */ /* If not, this is an error unless you used -f. */ -if (!(pv =pv_read (cmd, name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, name,NULL ,1 ,0 ))) {if (arg_count (cmd, force_ARG))return 1 ;log_error ("Physical Volume %s not found" , name);@@ -47,13 +44,14 @@ static int pvremove_check(struct cmd_context *cmd, const char *name)* means checking every VG by scanning every * PV on the system. */ -if (is_orphan (pv) && !dm_list_size (&mdas)) { +if (is_orphan (pv) && !dm_list_size (&pv->fid->metadata_areas_in_use) && + !dm_list_size (&pv->fid->metadata_areas_ignored)) {if (!scan_vgs_for_pvs (cmd,0 )) {log_error ("Rescan for PVs without metadata areas " "failed." );return 0 ; } -if (!(pv =pv_read (cmd, name,NULL ,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, name,NULL ,1 ,0 ))) {log_error ("Failed to read physical volume %s" , name);return 0 ; }tools/pvresize.c +3
-5@@ -32,28 +32,26 @@ static int _pv_resize_single(struct cmd_context *cmd,uint64_t size =0 ;uint32_t new_pe_count =0 ;int r =0 ; -struct dm_list mdas;const char *pv_name =pv_dev_name (pv);const char *vg_name =pv_vg_name (pv);struct lvmcache_info *info;int mda_count =0 ;struct volume_group *old_vg = vg; -dm_list_init (&mdas); -if (is_orphan_vg (vg_name)) {if (!lock_vol (cmd, vg_name,LCK_VG_WRITE )) {log_error ("Can't get lock for orphans" );return 0 ; } -if (!(pv =pv_read (cmd, pv_name, &mdas,NULL ,1 ,0 ))) { +if (!(pv =pv_read (cmd, pv_name,NULL ,1 ,0 ))) {unlock_vg (cmd, vg_name);log_error ("Unable to read PV \"%s\"" , pv_name);return 0 ; } - mda_count =dm_list_size (&mdas); + mda_count =dm_list_size (&pv->fid->metadata_areas_in_use) + +dm_list_size (&pv->fid->metadata_areas_ignored); }else { vg =vg_read_for_update (cmd, vg_name,NULL ,0 );tools/toollib.c +6
-8@@ -640,7 +640,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle, }while ((dev =dev_iter_get (iter))) { -if (!(pv =pv_read (cmd,dev_name (dev),NULL ,NULL ,0 ,0 ))) { +if (!(pv =pv_read (cmd,dev_name (dev),NULL ,0 ,0 ))) {memset (&pv_dummy,0 ,sizeof (pv_dummy));dm_list_init (&pv_dummy.tags);dm_list_init (&pv_dummy.segments);@@ -682,7 +682,6 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,struct str_list *sll;char *at_sign, *tagname;int scanned =0 ; -struct dm_list mdas;dm_list_init (&tags);@@ -724,10 +723,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, } pv = pvl->pv; }else { - -dm_list_init (&mdas); -if (!(pv =pv_read (cmd, argv[opt], &mdas, -NULL ,1 , scan_label_only))) { +if (!(pv =pv_read (cmd, argv[opt],NULL , +1 , scan_label_only))) {log_error ("Failed to read physical " "volume \"%s\"" , argv[opt]); ret_max =ECMD_FAILED ;@@ -742,7 +739,8 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,* PV on the system. */ if (!scanned &&is_orphan (pv) && - !dm_list_size (&mdas)) { + !dm_list_size (&pv->fid->metadata_areas_in_use) && + !dm_list_size (&pv->fid->metadata_areas_ignored)) {if (!scan_label_only && !scan_vgs_for_pvs (cmd,1 )) { stack;@@ -751,7 +749,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, } scanned =1 ;if (!(pv =pv_read (cmd, argv[opt], -NULL ,NULL ,1 , +NULL ,1 , scan_label_only))) {log_error ("Failed to read " "physical volume "
PATCH 7/17 Add pv_add_metadata_area fn to support adding metadata areas on demand.
In reply to Peter RajnohaMy previous version of the patch used the cache and that was not quite a happy solution (but it was easy to use :)) since any revert would be quite complex (or we'd need to destroy the cache item and rescan).
Now, we can use the format_instance to store metadata areas. If anything goes wrong, we can just throw the instance away and create a new one to work with (so we don't need to revert the cache or rescan).
--- lib/format_text/format-text.c | 245 +++++++++++++++++++++++++++++++++++++++++ lib/format_text/format-text.h | 5 + lib/metadata/metadata.h | 10 ++ 3 files changed, 260 insertions(+), 0 deletions(-)
lib/format_text/format-text.c +245 -0
@@ -2031,6 +2031,250 @@ static int _create_vg_text_instance(struct format_instance *fid,return 1 ; } +int add_metadata_area_to_pv (struct physical_volume *pv, +unsigned mda_index, +uint64_t mda_start, +uint64_t mda_size, +unsigned mda_ignored) +{ +struct metadata_area *mda; +struct mda_context *mdac; +struct mda_lists *mda_lists = (struct mda_lists *) pv->fmt->private; + +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "can't add metadata area with " +"index %u to PV %s. Metadata " +"layout not supported by %s format." , + mda_index,dev_name (pv->dev), + pv->fmt->name); + } + +if (!(mda =dm_malloc (sizeof (struct metadata_area )))) { +log_error ("struct metadata_area allocation failed" ); +return 0 ; + } + +if (!(mdac =dm_malloc (sizeof (struct mda_context )))) { +log_error ("struct mda_context allocation failed" ); +dm_free (mda); +return 0 ; + } + + mda->ops = mda_lists->raw_ops; + mda->metadata_locn = mdac; + mda->status =0 ; + + mdac->area.dev = pv->dev; + mdac->area.start = mda_start; + mdac->area.size = mda_size; + mdac->free_sectors =UINT64_C (0 ); +memset (&mdac->rlocn,0 ,sizeof (mdac->rlocn)); +mda_set_ignored (mda, mda_ignored); + +fid_add_mda (pv->fid ? pv->fid : pv->vg->fid, mda, + (char *) &pv->id,ID_LEN , mda_index); + +return 1 ; +} + +static int _text_pv_add_metadata_area (const struct format_type *fmt, +struct physical_volume *pv, +int pe_start_locked, +unsigned mda_index, +uint64_t mda_size, +unsigned mda_ignored) +{ +struct format_instance *fid = pv->fid; +const char *pvid = (char *) &pv->id; +uint64_t pe_start, pe_end; +uint64_t alignment, alignment_offset; +uint64_t disk_size; +uint64_t mda_start; +uint64_t adjustment, limit; +uint64_t wipe_size =8 <<SECTOR_SHIFT ; +size_t page_size =lvm_getpagesize (); +struct metadata_area *mda; +struct mda_context *mdac; + +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "invalid index of value %u used " +"while trying to add metadata area on PV %s. " +"Metadata layout not supported by %s format." , + mda_index,pv_dev_name (pv), fmt->name); +return 0 ; + } + + pe_start = pv->pe_start <<SECTOR_SHIFT ; + alignment = pv->pe_align <<SECTOR_SHIFT ; + alignment_offset = pv->pe_align_offset <<SECTOR_SHIFT ; + disk_size = pv->size <<SECTOR_SHIFT ; + mda_size = mda_size <<SECTOR_SHIFT ; + +if (fid_get_mda_indexed (fid, pvid,ID_LEN , mda_index)) { +log_error (INTERNAL_ERROR "metadata area with index %u already " +"exists on PV %s." , mda_index,pv_dev_name (pv)); +return 0 ; + } + +/* First metadata area@the start of the device. */ +if (mda_index ==0 ) { +/* +* Try to fit MDA0 end within given pe_start limit if its value +* is locked. If it's not locked, count with any existing MDA1. +* If there's no MDA1, just use disk size as the limit. +*/ +if (pe_start_locked) + limit = pe_start; +else if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,1 )) && + (mdac = mda->metadata_locn)) + limit = mdac->area.start; +else + limit = disk_size; + +if (limit > disk_size) + goto bad; + + mda_start =LABEL_SCAN_SIZE ; + +/* Align MDA0 start with page size if possible. */ +if (limit - mda_start >=MDA_SIZE_MIN ) { +if ((adjustment = mda_start % page_size)) + mda_start += (page_size - adjustment); + } + +/* Align MDA0 end position with given alignment if possible. */ +if (alignment) { +if ((adjustment = (mda_start + mda_size) % alignment)) { + mda_size += (alignment - adjustment); +if (mda_start + mda_size > limit) + mda_size -= (alignment - adjustment); + } + } + +/* Align MDA0 end position with given alignment offset if possible. */ +if (alignment_offset && + (((mda_start + mda_size) % alignment) ==0 )) { + mda_size += alignment_offset; +if (mda_start + mda_size > limit) + mda_size -= alignment_offset; + } + +if (mda_start + mda_size > limit) { +log_warn ("WARNING: metadata area size outreaches " +"a limit on PV %s specified by its %s. " +"Trying to adjust metadata area size." , +pv_dev_name (pv), + pe_start_locked ?"PE start" :"disk size" ); + +/* +* Try to decrease the MDA0 size with twice the +* alignment and then align with given alignment. +* If pe_start is locked, skip this type of +* alignment since it would be useless. +* Check first whether we can apply that! +*/ +if (!pe_start_locked && + ((limit - mda_start) > alignment *2 )) { + mda_size = limit - mda_start - alignment *2 ; + +if ((adjustment = (mda_start + mda_size) % alignment)) + mda_size += (alignment - adjustment); + +/* Still too much? Then there's nothing else to do. */ +if (mda_start + mda_size > limit) + goto bad; + } +/* Otherwise, give up and take any usable space. */ +/* FIXME: We should probably check for some minimum MDA size here. */ +else + mda_size = limit - mda_start; + } + +/* +* If PV's pe_start is not locked, update pe_start value with the +* start of the area that follows the MDA0 we've just calculated. +*/ +if (!pe_start_locked) { + pe_start = mda_start + mda_size; + pv->pe_start = pe_start >>SECTOR_SHIFT ; + } + } +/* Second metadata area at the end of the device. */ +else { +/* +* Try to fit MDA1 start within given pe_end or pe_start limit +* if it's locked. If pe_start and pe_end are not defined yet, +* count with any existing MDA0 and pe_start. If MDA0 does not +* exist, just use LABEL_SCAN_SIZE. +*/ + pe_end = pv->pe_count ? (pv->pe_start + + pv->pe_count * pv->pe_size -1 ) <<SECTOR_SHIFT + :0 ; +if (pe_start_locked) + limit = pe_end ? pe_end : pe_start; +else if (pe_start) + limit = pe_start; +/* +* Normally MDA0's start + size should be pe_start. +* The statemet here is probably useless since the +* situation is covered by previous statement. +*/ +else if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,0 )) && + (mdac = mda->metadata_locn)) + limit = mdac->area.start + mdac->area.size; +else + limit =LABEL_SCAN_SIZE ; + +if (limit > disk_size || mda_size > disk_size) + goto bad; + + mda_start = disk_size - mda_size; + +if (alignment) { + adjustment = mda_start % alignment; +if (adjustment) + mda_size += adjustment; + } + +if (disk_size - mda_size < limit) + mda_size = disk_size - limit; + +/* +* If PV's pe_end not set yet, set it to the end of the +* area that precedes the MDA1 we've just calculated. +* FIXME: do we need to set this? Isn't it always set before? +*/ +/*if (!pe_end) { +pe_end = mda_start; +pv->pe_end = pe_end >> SECTOR_SHIFT; +}*/ + } + +if (mda_size) { +/* Wipe metadata area with zeroes. */ +if (!dev_set ((struct device *) pv->dev, mda_start, + (size_t ) (mda_size > wipe_size ? : mda_size),0 )) { +log_error ("Failed to wipe new metadata area " +"at the %s of the %s" , + mda_index ?"end" :"start" , +pv_dev_name (pv)); +return 0 ; + } + +/* Finally, add new metadata area to PV's format instance. */ +if (!add_metadata_area_to_pv (pv, mda_index, mda_start, + mda_size, mda_ignored)) + return_0; + } + +return 1 ; + +bad: +log_error ("Not enough space available for metadata area " +"with index %u on PV %s." , mda_index,pv_dev_name (pv)); +return 0 ; +} +/* NULL vgname means use only the supplied context e.g. an archive file */ static struct format_instance *_text_create_text_instance(const struct format_type *fmt, const char *pvid,
@@ -2111,6 +2355,7 @@ static struct format_handler _text_handler = { .scan = _text_scan, .pv_read = _text_pv_read, .pv_setup = _text_pv_setup, + .pv_add_metadata_area = _text_pv_add_metadata_area, .pv_write = _text_pv_write, .vg_setup = _text_vg_setup, .lv_setup = _text_lv_setup,
lib/format_text/format-text.h +5 -0
@@ -56,6 +56,11 @@ int add_da(struct dm_pool *mem, struct dm_list *das, uint64_t start, uint64_t size);void del_das (struct dm_list *das); +int add_metadata_area_to_pv (struct physical_volume *pv, +unsigned mda_index, +uint64_t mda_start, +uint64_t mda_size, +unsigned mda_ignored);int add_mda (const struct format_type *fmt,struct dm_pool *mem,struct dm_list *mdas,struct device *dev,uint64_t start,uint64_t size,unsigned ignored);void del_mdas (struct dm_list *mdas);
lib/metadata/metadata.h +10 -0
@@ -256,6 +256,16 @@ struct format_handler { struct physical_volume * pv, struct volume_group * vg);/* +* Add metadata area to a PV. Changes will take effect on pv_write. +*/ +int (*pv_add_metadata_area) (const struct format_type * fmt, +struct physical_volume * pv, +int pe_start_locked, +unsigned metadata_index, +uint64_t metadata_size, +unsigned metadata_ignored); + +/* * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be a valid orphan VG name */
Signature · 1 line
1.7.3.4
PATCH 7/17 Add pv_add_metadata_area fn to support adding metadata areas on demand.
Quoted 7 lines · Peter Rajnoha
My previous version of the patch used the cache and that was not quite a happy solution (but it was easy to use :)) since any revert would be quite complex (or we'd need to destroy the cache item and rescan).
Now, we can use the
format_instanceto store metadata areas. If anything goes wrong, we can just throw the instance away and create a new one to work with (so we don't need to revert the cache or rescan).
This one looks OK. I see a lot of overlap with existing PV manipulation code, but from scanning the whole bundle I think this is addressed in a later patch.
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
(One minor tweak below)
Quoted 243 lines
--- lib/format_text/format-text.c | 245 +++++++++++++++++++++++++++++++++++++++++ lib/format_text/format-text.h | 5 + lib/metadata/metadata.h | 10 ++ 3 files changed, 260 insertions(+), 0 deletions(-)lib/format_text/format-text.c +229
-0@@ -2031,6 +2031,250 @@ static int _create_vg_text_instance(struct format_instance *fid,return 1 ; } +int add_metadata_area_to_pv (struct physical_volume *pv, +unsigned mda_index, +uint64_t mda_start, +uint64_t mda_size, +unsigned mda_ignored) +{ +struct metadata_area *mda; +struct mda_context *mdac; +struct mda_lists *mda_lists = (struct mda_lists *) pv->fmt->private; + +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "can't add metadata area with " +"index %u to PV %s. Metadata " +"layout not supported by %s format." , + mda_index,dev_name (pv->dev), + pv->fmt->name); + } + +if (!(mda =dm_malloc (sizeof (struct metadata_area )))) { +log_error ("struct metadata_area allocation failed" ); +return 0 ; + } + +if (!(mdac =dm_malloc (sizeof (struct mda_context )))) { +log_error ("struct mda_context allocation failed" ); +dm_free (mda); +return 0 ; + } + + mda->ops = mda_lists->raw_ops; + mda->metadata_locn = mdac; + mda->status =0 ; + + mdac->area.dev = pv->dev; + mdac->area.start = mda_start; + mdac->area.size = mda_size; + mdac->free_sectors =UINT64_C (0 ); +memset (&mdac->rlocn,0 ,sizeof (mdac->rlocn)); +mda_set_ignored (mda, mda_ignored); + +fid_add_mda (pv->fid ? pv->fid : pv->vg->fid, mda, + (char *) &pv->id,ID_LEN , mda_index); + +return 1 ; +} + +static int _text_pv_add_metadata_area (const struct format_type *fmt, +struct physical_volume *pv, +int pe_start_locked, +unsigned mda_index, +uint64_t mda_size, +unsigned mda_ignored) +{ +struct format_instance *fid = pv->fid; +const char *pvid = (char *) &pv->id; +uint64_t pe_start, pe_end; +uint64_t alignment, alignment_offset; +uint64_t disk_size; +uint64_t mda_start; +uint64_t adjustment, limit; +uint64_t wipe_size =8 <<SECTOR_SHIFT ; +size_t page_size =lvm_getpagesize (); +struct metadata_area *mda; +struct mda_context *mdac; + +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "invalid index of value %u used " +"while trying to add metadata area on PV %s. " +"Metadata layout not supported by %s format." , + mda_index,pv_dev_name (pv), fmt->name); +return 0 ; + } + + pe_start = pv->pe_start <<SECTOR_SHIFT ; + alignment = pv->pe_align <<SECTOR_SHIFT ; + alignment_offset = pv->pe_align_offset <<SECTOR_SHIFT ; + disk_size = pv->size <<SECTOR_SHIFT ; + mda_size = mda_size <<SECTOR_SHIFT ; + +if (fid_get_mda_indexed (fid, pvid,ID_LEN , mda_index)) { +log_error (INTERNAL_ERROR "metadata area with index %u already " +"exists on PV %s." , mda_index,pv_dev_name (pv)); +return 0 ; + } + +/* First metadata area at the start of the device. */ +if (mda_index ==0 ) { +/* +* Try to fit MDA0 end within given pe_start limit if its value +* is locked. If it's not locked, count with any existing MDA1. +* If there's no MDA1, just use disk size as the limit. +*/ +if (pe_start_locked) + limit = pe_start; +else if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,1 )) && + (mdac = mda->metadata_locn)) + limit = mdac->area.start; +else + limit = disk_size; + +if (limit > disk_size) + goto bad; + + mda_start =LABEL_SCAN_SIZE ; + +/* Align MDA0 start with page size if possible. */ +if (limit - mda_start >=MDA_SIZE_MIN ) { +if ((adjustment = mda_start % page_size)) + mda_start += (page_size - adjustment); + } + +/* Align MDA0 end position with given alignment if possible. */ +if (alignment) { +if ((adjustment = (mda_start + mda_size) % alignment)) { + mda_size += (alignment - adjustment); +if (mda_start + mda_size > limit) + mda_size -= (alignment - adjustment); + } + } + +/* Align MDA0 end position with given alignment offset if possible. */ +if (alignment_offset && + (((mda_start + mda_size) % alignment) ==0 )) { + mda_size += alignment_offset; +if (mda_start + mda_size > limit) + mda_size -= alignment_offset; + } + +if (mda_start + mda_size > limit) { +log_warn ("WARNING: metadata area size outreaches " +"a limit on PV %s specified by its %s. " +"Trying to adjust metadata area size." , +pv_dev_name (pv), + pe_start_locked ?"PE start" :"disk size" ); + +/* +* Try to decrease the MDA0 size with twice the +* alignment and then align with given alignment. +* If pe_start is locked, skip this type of +* alignment since it would be useless. +* Check first whether we can apply that! +*/ +if (!pe_start_locked && + ((limit - mda_start) > alignment *2 )) { + mda_size = limit - mda_start - alignment *2 ; + +if ((adjustment = (mda_start + mda_size) % alignment)) + mda_size += (alignment - adjustment); + +/* Still too much? Then there's nothing else to do. */ +if (mda_start + mda_size > limit) + goto bad; + } +/* Otherwise, give up and take any usable space. */ +/* FIXME: We should probably check for some minimum MDA size here. */ +else + mda_size = limit - mda_start; + } + +/* +* If PV's pe_start is not locked, update pe_start value with the +* start of the area that follows the MDA0 we've just calculated. +*/ +if (!pe_start_locked) { + pe_start = mda_start + mda_size; + pv->pe_start = pe_start >>SECTOR_SHIFT ; + } + } +/* Second metadata area at the end of the device. */ +else { +/* +* Try to fit MDA1 start within given pe_end or pe_start limit +* if it's locked. If pe_start and pe_end are not defined yet, +* count with any existing MDA0 and pe_start. If MDA0 does not +* exist, just use LABEL_SCAN_SIZE. +*/ + pe_end = pv->pe_count ? (pv->pe_start + + pv->pe_count * pv->pe_size -1 ) <<SECTOR_SHIFT + :0 ; +if (pe_start_locked) + limit = pe_end ? pe_end : pe_start; +else if (pe_start) + limit = pe_start; +/* +* Normally MDA0's start + size should be pe_start. +* The statemet here is probably useless since the +* situation is covered by previous statement. +*/ +else if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,0 )) && + (mdac = mda->metadata_locn)) + limit = mdac->area.start + mdac->area.size; +else + limit =LABEL_SCAN_SIZE ; + +if (limit > disk_size || mda_size > disk_size) + goto bad; + + mda_start = disk_size - mda_size; + +if (alignment) { + adjustment = mda_start % alignment; +if (adjustment) + mda_size += adjustment; + } + +if (disk_size - mda_size < limit) + mda_size = disk_size - limit; + +/* +* If PV's pe_end not set yet, set it to the end of the +* area that precedes the MDA1 we've just calculated. +* FIXME: do we need to set this? Isn't it always set before? +*/ +/*if (!pe_end) { +pe_end = mda_start; +pv->pe_end = pe_end >> SECTOR_SHIFT; +}*/ + } + +if (mda_size) { +/* Wipe metadata area with zeroes. */ +if (!dev_set ((struct device *) pv->dev, mda_start, + (size_t ) (mda_size > wipe_size ? : mda_size),0 )) { +log_error ("Failed to wipe new metadata area " +"at the %s of the %s" , + mda_index ?"end" :"start" , +pv_dev_name (pv)); +return 0 ; + }
lib/format_text/format-text.c static int _create_vg_text_instance(struct format_instance *fid, · line 2272
Quoted 10 lines
lib/format_text/format-text.c +10
-0+ +/* Finally, add new metadata area to PV's format instance. */ +if (!add_metadata_area_to_pv (pv, mda_index, mda_start, + mda_size, mda_ignored)) + return_0; + } + +return 1 ; + +bad:
^^ Should this label be renamed to nospace or no_space for clarity?
Quoted 53 lines
lib/format_text/format-text.c +6
-0+log_error ("Not enough space available for metadata area " +"with index %u on PV %s." , mda_index,pv_dev_name (pv)); +return 0 ; +} +/* NULL vgname means use only the supplied context e.g. an archive file */ static struct format_instance *_text_create_text_instance(const struct format_type *fmt, const char *pvid,@@ -2111,6 +2355,7 @@ static struct format_handler _text_handler = { .scan = _text_scan, .pv_read = _text_pv_read, .pv_setup = _text_pv_setup, + .pv_add_metadata_area = _text_pv_add_metadata_area, .pv_write = _text_pv_write, .vg_setup = _text_vg_setup, .lv_setup = _text_lv_setup,lib/format_text/format-text.h +5
-0@@ -56,6 +56,11 @@ int add_da(struct dm_pool *mem, struct dm_list *das, uint64_t start, uint64_t size);void del_das (struct dm_list *das); +int add_metadata_area_to_pv (struct physical_volume *pv, +unsigned mda_index, +uint64_t mda_start, +uint64_t mda_size, +unsigned mda_ignored);int add_mda (const struct format_type *fmt,struct dm_pool *mem,struct dm_list *mdas,struct device *dev,uint64_t start,uint64_t size,unsigned ignored);void del_mdas (struct dm_list *mdas);lib/metadata/metadata.h +10
-0@@ -256,6 +256,16 @@ struct format_handler { struct physical_volume * pv, struct volume_group * vg);/* +* Add metadata area to a PV. Changes will take effect on pv_write. +*/ +int (*pv_add_metadata_area) (const struct format_type * fmt, +struct physical_volume * pv, +int pe_start_locked, +unsigned metadata_index, +uint64_t metadata_size, +unsigned metadata_ignored); + +/* * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be a valid orphan VG name */
PATCH 8/17 Add pv_remove_metadata_area fn to support removing metadata areas on demand.
In reply to Peter RajnohaThe same as for pv_add_metadata_area, but removing...
--- lib/format_text/format-text.c | 24 ++++++++++++++++++++++++ lib/format_text/format-text.h | 2 ++ lib/metadata/metadata.h | 7 +++++++ 3 files changed, 33 insertions(+), 0 deletions(-)
lib/format_text/format-text.c +24 -0
@@ -2275,6 +2275,29 @@ bad:return 0 ; } +int remove_metadata_area_from_pv (struct physical_volume *pv, +unsigned mda_index) +{ +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "can't remove metadata area with " +"index %u from PV %s. Metadata " +"layou not supported by %s format." , + mda_index,dev_name (pv->dev), + pv->fmt->name); +return 0 ; + } + +return fid_remove_mda (pv->fid,NULL , (const char *) &pv->id, +ID_LEN , mda_index); +} + +static int _text_pv_remove_metadata_area (const struct format_type *fmt, +struct physical_volume *pv, +unsigned mda_index) +{ +return remove_metadata_area_from_pv (pv, mda_index); +} +/* NULL vgname means use only the supplied context e.g. an archive file */ static struct format_instance *_text_create_text_instance(const struct format_type *fmt, const char *pvid,
@@ -2356,6 +2379,7 @@ static struct format_handler _text_handler = { .pv_read = _text_pv_read, .pv_setup = _text_pv_setup, .pv_add_metadata_area = _text_pv_add_metadata_area, + .pv_remove_metadata_area = _text_pv_remove_metadata_area, .pv_write = _text_pv_write, .vg_setup = _text_vg_setup, .lv_setup = _text_lv_setup,
lib/format_text/format-text.h +2 -0
@@ -61,6 +61,8 @@ int add_metadata_area_to_pv(struct physical_volume *pv,uint64_t mda_start, uint64_t mda_size, unsigned mda_ignored); +int remove_metadata_area_from_pv (struct physical_volume *pv, +unsigned mda_index);int add_mda (const struct format_type *fmt,struct dm_pool *mem,struct dm_list *mdas,struct device *dev,uint64_t start,uint64_t size,unsigned ignored);void del_mdas (struct dm_list *mdas);
lib/metadata/metadata.h +7 -0
@@ -266,6 +266,13 @@ struct format_handler { unsigned metadata_ignored);/* +* Remove metadata area from a PV. Changes will take effect on pv_write. +*/ +int (*pv_remove_metadata_area) (const struct format_type *fmt, +struct physical_volume *pv, +unsigned metadata_index); + +/* * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be a valid orphan VG name */
Signature · 1 line
1.7.3.4
PATCH 8/17 Add pv_remove_metadata_area fn to support removing metadata areas on demand.
Quoted 1 line · Peter Rajnoha
The same as for
pv_add_metadata_area, but removing...
These look OK (although the FMT_TEXT_MAX_MDAS_PER_PV is a bit fiddly).
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 79 lines
--- lib/format_text/format-text.c | 24 ++++++++++++++++++++++++ lib/format_text/format-text.h | 2 ++ lib/metadata/metadata.h | 7 +++++++ 3 files changed, 33 insertions(+), 0 deletions(-)lib/format_text/format-text.c +24
-0@@ -2275,6 +2275,29 @@ bad:return 0 ; } +int remove_metadata_area_from_pv (struct physical_volume *pv, +unsigned mda_index) +{ +if (mda_index >=FMT_TEXT_MAX_MDAS_PER_PV ) { +log_error (INTERNAL_ERROR "can't remove metadata area with " +"index %u from PV %s. Metadata " +"layou not supported by %s format." , + mda_index,dev_name (pv->dev), + pv->fmt->name); +return 0 ; + } + +return fid_remove_mda (pv->fid,NULL , (const char *) &pv->id, +ID_LEN , mda_index); +} + +static int _text_pv_remove_metadata_area (const struct format_type *fmt, +struct physical_volume *pv, +unsigned mda_index) +{ +return remove_metadata_area_from_pv (pv, mda_index); +} +/* NULL vgname means use only the supplied context e.g. an archive file */ static struct format_instance *_text_create_text_instance(const struct format_type *fmt, const char *pvid,@@ -2356,6 +2379,7 @@ static struct format_handler _text_handler = { .pv_read = _text_pv_read, .pv_setup = _text_pv_setup, .pv_add_metadata_area = _text_pv_add_metadata_area, + .pv_remove_metadata_area = _text_pv_remove_metadata_area, .pv_write = _text_pv_write, .vg_setup = _text_vg_setup, .lv_setup = _text_lv_setup,lib/format_text/format-text.h +2
-0@@ -61,6 +61,8 @@ int add_metadata_area_to_pv(struct physical_volume *pv,uint64_t mda_start, uint64_t mda_size, unsigned mda_ignored); +int remove_metadata_area_from_pv (struct physical_volume *pv, +unsigned mda_index);int add_mda (const struct format_type *fmt,struct dm_pool *mem,struct dm_list *mdas,struct device *dev,uint64_t start,uint64_t size,unsigned ignored);void del_mdas (struct dm_list *mdas);lib/metadata/metadata.h +7
-0@@ -266,6 +266,13 @@ struct format_handler { unsigned metadata_ignored);/* +* Remove metadata area from a PV. Changes will take effect on pv_write. +*/ +int (*pv_remove_metadata_area) (const struct format_type *fmt, +struct physical_volume *pv, +unsigned metadata_index); + +/* * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be a valid orphan VG name */
PATCH 9/17 Add pv_initialise fn to format_handler interface.
In reply to Peter RajnohaThis is a split-off from the original pv_setup code, a simple refactor. It makes the code easier to read and cleans up the interface a bit. So now we will call pv_initialise when we initialise a PV only, creating a brand new PV. It will also initialise a new format_instance to use later on.
--- lib/format1/format1.c | 35 ++++++++++++++------ lib/format_pool/format_pool.c | 14 ++++++++ lib/format_text/format-text.c | 71 +++++++++++++++++++++++++++++++++++++++++ lib/metadata/metadata.h | 13 +++++++ 4 files changed, 123 insertions(+), 10 deletions(-)
lib/format1/format1.c +25 -10
@@ -361,16 +361,15 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,return r; } -static int _format1_pv_setup (const struct format_type *fmt, -uint64_t pe_start,uint32_t extent_count, -uint32_t extent_size, -unsigned long data_alignment __attribute__((unused)), -unsigned long data_alignment_offset __attribute__((unused)), -int pvmetadatacopies __attribute__((unused)), -uint64_t pvmetadatasize __attribute__((unused)), -unsigned metadataignore __attribute__((unused)), -struct dm_list *mdas __attribute__((unused)), -struct physical_volume *pv,struct volume_group *vg __attribute__((unused))) +static int _format1_pv_initialise (const struct format_type * fmt, +int64_t label_sector __attribute__((unused)), +uint64_t pe_start, +int pe_start_locked __attribute__((unused)), +uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +struct physical_volume * pv) {if (pv->size >MAX_PV_SIZE ) pv->size--;
@@ -400,6 +399,21 @@ static int _format1_pv_setup(const struct format_type *fmt,return 1 ; } +static int _format1_pv_setup (const struct format_type *fmt, +uint64_t pe_start,uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +int pvmetadatacopies __attribute__((unused)), +uint64_t pvmetadatasize __attribute__((unused)), +unsigned metadataignore __attribute__((unused)), +struct dm_list *mdas __attribute__((unused)), +struct physical_volume *pv, +struct volume_group *vg __attribute__((unused))) +{ +return _format1_pv_initialise (fmt,-1 ,0 ,0 ,0 , vg->extent_size,0 ,0 , pv); +} +static int _format1_lv_setup (struct format_instance *fid,struct logical_volume *lv) {uint64_t max_size =UINT_MAX ;
@@ -563,6 +577,7 @@ static void _format1_destroy(struct format_type *fmt)static struct format_handler _format1_ops = { .pv_read = _format1_pv_read, + .pv_initialise = _format1_pv_initialise, .pv_setup = _format1_pv_setup, .pv_write = _format1_pv_write, .lv_setup = _format1_lv_setup,
lib/format_pool/format_pool.c +14 -0
@@ -188,6 +188,19 @@ out:return NULL ; } +static int _pool_pv_initialise (const struct format_type *fmt __attribute__((unused)), +int64_t label_sector __attribute__((unused)), +uint64_t pe_start __attribute__((unused)), +int pe_start_locked __attribute__((unused)), +uint32_t extent_count __attribute__((unused)), +uint32_t extent_size __attribute__((unused)), +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +struct physical_volume *pv __attribute__((unused))) +{ +return 1 ; +} + static int _pool_pv_setup(const struct format_type *fmt __attribute__((unused)), uint64_t pe_start __attribute__((unused)), uint32_t extent_count __attribute__((unused)),
@@ -295,6 +308,7 @@ static void _pool_destroy(struct format_type *fmt)/* *INDENT-OFF* */ static struct format_handler _format_pool_ops = { .pv_read = _pool_pv_read, + .pv_initialise = _pool_pv_initialise, .pv_setup = _pool_pv_setup, .create_instance = _pool_create_instance, .destroy_instance = _pool_destroy_instance,
lib/format_text/format-text.c +71 -0
83 lines not on this page · raw message
lib/metadata/metadata.h +13 -0
@@ -244,6 +244,19 @@ struct format_handler { struct physical_volume * pv, int scan_label_only);/* +* Initialise a new PV. +*/ +int (*pv_initialise) (const struct format_type * fmt, +int64_t label_sector, +uint64_t pe_start, +int pe_start_locked, +uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment, +unsigned long data_alignment_offset, +struct physical_volume * pv); + +/* * Tweak an already filled out a pv ready for importing into a * vg. eg. pe_count is format specific. */
Signature · 1 line
1.7.3.4
PATCH 9/17 Add pv_initialise fn to format_handler interface.
Quoted 4 lines · Peter Rajnoha
This is a split-off from the original
pv_setupcode, a simple refactor. It makes the code easier to read and cleans up the interface a bit. So now we will callpv_initialisewhen we initialise a PV only, creating a brand new PV. It will also initialise a newformat_instanceto use later on.
OK, although the parameter lists are huge -- calls to these functions are plain unreadable. Please consider doing something about it... (this is a widespread problem in LVM, I know, but that's no excuse to keep not fixing it).
Yours,
Petr
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 212 lines
--- lib/format1/format1.c | 35 ++++++++++++++------ lib/format_pool/format_pool.c | 14 ++++++++ lib/format_text/format-text.c | 71 +++++++++++++++++++++++++++++++++++++++++ lib/metadata/metadata.h | 13 +++++++ 4 files changed, 123 insertions(+), 10 deletions(-)lib/format1/format1.c +25
-10@@ -361,16 +361,15 @@ static int _format1_pv_read(const struct format_type *fmt, const char *pv_name,return r; } -static int _format1_pv_setup (const struct format_type *fmt, -uint64_t pe_start,uint32_t extent_count, -uint32_t extent_size, -unsigned long data_alignment __attribute__((unused)), -unsigned long data_alignment_offset __attribute__((unused)), -int pvmetadatacopies __attribute__((unused)), -uint64_t pvmetadatasize __attribute__((unused)), -unsigned metadataignore __attribute__((unused)), -struct dm_list *mdas __attribute__((unused)), -struct physical_volume *pv,struct volume_group *vg __attribute__((unused))) +static int _format1_pv_initialise (const struct format_type * fmt, +int64_t label_sector __attribute__((unused)), +uint64_t pe_start, +int pe_start_locked __attribute__((unused)), +uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +struct physical_volume * pv) {if (pv->size >MAX_PV_SIZE ) pv->size--;@@ -400,6 +399,21 @@ static int _format1_pv_setup(const struct format_type *fmt,return 1 ; } +static int _format1_pv_setup (const struct format_type *fmt, +uint64_t pe_start,uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +int pvmetadatacopies __attribute__((unused)), +uint64_t pvmetadatasize __attribute__((unused)), +unsigned metadataignore __attribute__((unused)), +struct dm_list *mdas __attribute__((unused)), +struct physical_volume *pv, +struct volume_group *vg __attribute__((unused))) +{ +return _format1_pv_initialise (fmt,-1 ,0 ,0 ,0 , vg->extent_size,0 ,0 , pv); +} +static int _format1_lv_setup (struct format_instance *fid,struct logical_volume *lv) {uint64_t max_size =UINT_MAX ;@@ -563,6 +577,7 @@ static void _format1_destroy(struct format_type *fmt)static struct format_handler _format1_ops = { .pv_read = _format1_pv_read, + .pv_initialise = _format1_pv_initialise, .pv_setup = _format1_pv_setup, .pv_write = _format1_pv_write, .lv_setup = _format1_lv_setup,lib/format_pool/format_pool.c +14
-0@@ -188,6 +188,19 @@ out:return NULL ; } +static int _pool_pv_initialise (const struct format_type *fmt __attribute__((unused)), +int64_t label_sector __attribute__((unused)), +uint64_t pe_start __attribute__((unused)), +int pe_start_locked __attribute__((unused)), +uint32_t extent_count __attribute__((unused)), +uint32_t extent_size __attribute__((unused)), +unsigned long data_alignment __attribute__((unused)), +unsigned long data_alignment_offset __attribute__((unused)), +struct physical_volume *pv __attribute__((unused))) +{ +return 1 ; +} + static int _pool_pv_setup(const struct format_type *fmt __attribute__((unused)), uint64_t pe_start __attribute__((unused)), uint32_t extent_count __attribute__((unused)),@@ -295,6 +308,7 @@ static void _pool_destroy(struct format_type *fmt)/* *INDENT-OFF* */ static struct format_handler _format_pool_ops = { .pv_read = _pool_pv_read, + .pv_initialise = _pool_pv_initialise, .pv_setup = _pool_pv_setup, .create_instance = _pool_create_instance, .destroy_instance = _pool_destroy_instance,lib/format_text/format-text.c +71
-0@@ -1688,6 +1688,76 @@ static int _text_pv_read(const struct format_type *fmt, const char *pv_name,return 1 ; } +static int _text_pv_initialise (const struct format_type *fmt, +const int64_t label_sector, +uint64_t pe_start, +int pe_start_locked, +uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment, +unsigned long data_alignment_offset, +struct physical_volume *pv) +{ +struct text_fid_pv_context *fid_pv_tc; + +/* +* Try to keep the value of PE start set to a firm value if requested. +* This is usefull when restoring existing PE start value (backups etc.). +*/ +if (pe_start_locked) + pv->pe_start = pe_start; + +if (!data_alignment) + data_alignment =find_config_tree_int (pv->fmt->cmd, +"devices/data_alignment" , +0 ) *2 ; + +if (set_pe_align (pv, data_alignment) != data_alignment && + data_alignment) { +log_error ("%s: invalid data alignment of " +"%lu sectors (requested %lu sectors)" , +pv_dev_name (pv), pv->pe_align, data_alignment); +return 0 ; + } + +if (set_pe_align_offset (pv, data_alignment_offset) != data_alignment_offset && + data_alignment_offset) { +log_error ("%s: invalid data alignment offset of " +"%lu sectors (requested %lu sectors)" , +pv_dev_name (pv), pv->pe_align_offset, data_alignment_offset); +return 0 ; + } + +if (pv->pe_align < pv->pe_align_offset) { +log_error ("%s: pe_align (%lu sectors) must not be less " +"than pe_align_offset (%lu sectors)" , +pv_dev_name (pv), pv->pe_align, pv->pe_align_offset); +return 0 ; + } + +if (!pe_start_locked && pv->pe_start < pv->pe_align) + pv->pe_start = pv->pe_align; + +if (extent_size) + pv->pe_size = extent_size; + +if (extent_count) + pv->pe_count = extent_count; + +if ((pv->pe_start + pv->pe_count * pv->pe_size -1 ) > (pv->size <<SECTOR_SHIFT )) { +log_error ("Physical extents end beyond end of device %s." , +pv_dev_name (pv)); +return 0 ; + } + +if (label_sector !=-1 ) { + fid_pv_tc = (struct text_fid_pv_context *) pv->fid->private; + fid_pv_tc->label_sector = label_sector; + } + +return 1 ; +} +static void _text_destroy_instance (struct format_instance *fid __attribute__((unused))) { }@@ -2377,6 +2447,7 @@ void *create_text_context(struct cmd_context *cmd, const char *path,static struct format_handler _text_handler = { .scan = _text_scan, .pv_read = _text_pv_read, + .pv_initialise = _text_pv_initialise, .pv_setup = _text_pv_setup, .pv_add_metadata_area = _text_pv_add_metadata_area, .pv_remove_metadata_area = _text_pv_remove_metadata_area,lib/metadata/metadata.h +13
-0@@ -244,6 +244,19 @@ struct format_handler { struct physical_volume * pv, int scan_label_only);/* +* Initialise a new PV. +*/ +int (*pv_initialise) (const struct format_type * fmt, +int64_t label_sector, +uint64_t pe_start, +int pe_start_locked, +uint32_t extent_count, +uint32_t extent_size, +unsigned long data_alignment, +unsigned long data_alignment_offset, +struct physical_volume * pv); + +/* * Tweak an already filled out a pv ready for importing into a * vg. eg. pe_count is format specific. */
PATCH 10/17 Add pe_start_locked parameter to pv_create fn.
In reply to Peter RajnohaSo we can define and hint the metadata area handling code that the pe_start is supposed to be firmly set to a certain value and it should not be changed during calculations.
--- lib/metadata/metadata-exported.h | 1 + lib/metadata/metadata.c | 4 +++- tools/vgconvert.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-)
lib/metadata/metadata-exported.h +1 -0
@@ -394,6 +394,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,unsigned long data_alignment, unsigned long data_alignment_offset, uint64_t pe_start, + int pe_start_locked, uint32_t existing_extent_count, uint32_t existing_extent_size, int pvmetadatacopies, uint64_t pvmetadatasize,
lib/metadata/metadata.c +3 -1
@@ -1486,7 +1486,8 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,dm_list_init (&mdas);if (!(pv =pv_create (cmd, dev, pp->idp, pp->size, pp->data_alignment, pp->data_alignment_offset, - pp->pe_start, pp->extent_count, pp->extent_size, + pp->pe_start, pp->pe_start ?1 :0 , + pp->extent_count, pp->extent_size, pp->pvmetadatacopies, pp->pvmetadatasize, pp->metadataignore, &mdas))) {log_error ("Failed to setup physical volume \"%s\"" , pv_name);
@@ -1591,6 +1592,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,unsigned long data_alignment, unsigned long data_alignment_offset, uint64_t pe_start, + int pe_start_locked, uint32_t existing_extent_count, uint32_t existing_extent_size, int pvmetadatacopies, uint64_t pvmetadatasize,
tools/vgconvert.c +1 -1
@@ -125,7 +125,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,dm_list_init (&mdas);if (!(pv =pv_create (cmd,pv_dev (existing_pv), &existing_pv->id, size,0 ,0 , - pe_start,pv_pe_count (existing_pv), + pe_start,1 ,pv_pe_count (existing_pv),pv_pe_size (existing_pv), pvmetadatacopies, pvmetadatasize,0 , &mdas))) { log_error("Failed to setup physical volume \"%s\"",
Signature · 1 line
1.7.3.4
PATCH 10/17 Add pe_start_locked parameter to pv_create fn.
Quoted 3 lines · Peter Rajnoha
So we can define and hint the metadata area handling code that the
pe_startis supposed to be firmly set to a certain value and it should not be changed during calculations.
All clear. However, it adds another parameter to an already huge list. Please consider other options. Also, not using int as a bool would help in lots of places, but I guess we are stuck with that. (You could for example create a structure for the parameters, so at least at the call site, we have know which parameter means what... having a 10-tuple of integers is not exactly informative.)
Quoted 1 line
Signed-off-by Peter Rajnoha <[email protected]>
Quoted 53 lines
--- lib/metadata/metadata-exported.h | 1 + lib/metadata/metadata.c | 4 +++- tools/vgconvert.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-)lib/metadata/metadata-exported.h +1
-0@@ -394,6 +394,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,unsigned long data_alignment, unsigned long data_alignment_offset, uint64_t pe_start, + int pe_start_locked, uint32_t existing_extent_count, uint32_t existing_extent_size, int pvmetadatacopies, uint64_t pvmetadatasize,lib/metadata/metadata.c +3
-1@@ -1486,7 +1486,8 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,dm_list_init (&mdas);if (!(pv =pv_create (cmd, dev, pp->idp, pp->size, pp->data_alignment, pp->data_alignment_offset, - pp->pe_start, pp->extent_count, pp->extent_size, + pp->pe_start, pp->pe_start ?1 :0 , + pp->extent_count, pp->extent_size, pp->pvmetadatacopies, pp->pvmetadatasize, pp->metadataignore, &mdas))) {log_error ("Failed to setup physical volume \"%s\"" , pv_name);@@ -1591,6 +1592,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,unsigned long data_alignment, unsigned long data_alignment_offset, uint64_t pe_start, + int pe_start_locked, uint32_t existing_extent_count, uint32_t existing_extent_size, int pvmetadatacopies, uint64_t pvmetadatasize,tools/vgconvert.c +1
-1@@ -125,7 +125,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,dm_list_init (&mdas);if (!(pv =pv_create (cmd,pv_dev (existing_pv), &existing_pv->id, size,0 ,0 , - pe_start,pv_pe_count (existing_pv), + pe_start,1 ,pv_pe_count (existing_pv),pv_pe_size (existing_pv), pvmetadatacopies, pvmetadatasize,0 , &mdas))) { log_error("Failed to setup physical volume \"%s\"",
PATCH 11/17 Refactor pv_setup to not include the PV initialisation code.
In reply to Peter RajnohaPV initialisation is done using the new pv_initialise fn. Now, the pv_setup is supposed to be used only when we're trying to put the existing PV together with an existing VG.
Also, since the PV is now becoming the part of the VG, we move any metadata areas from PV-based format instance to VG-based format_instance. Then we destroy the PV-based one and pv->fid now references vg->fid.
(...we can still use the same functions to set/get metadata areas as with the PV-based format_instance, there's no change in use. The fid handling interface will take care of this internally...)
--- lib/format1/format1.c | 8 -- lib/format_pool/format_pool.c | 9 -- lib/format_text/archiver.c | 5 +- lib/format_text/format-text.c | 183 +++++++++++--------------------------- lib/metadata/metadata-exported.h | 7 +- lib/metadata/metadata.c | 53 +++++------ lib/metadata/metadata.h | 8 +-- tools/vgconvert.c | 6 +- 8 files changed, 85 insertions(+), 194 deletions(-)
lib/format1/format1.c +0 -8
@@ -400,14 +400,6 @@ static int _format1_pv_initialise(const struct format_type * fmt, }static int _format1_pv_setup (const struct format_type *fmt, -uint64_t pe_start,uint32_t extent_count, -uint32_t extent_size, -unsigned long data_alignment __attribute__((unused)), -unsigned long data_alignment_offset __attribute__((unused)), -int pvmetadatacopies __attribute__((unused)), -uint64_t pvmetadatasize __attribute__((unused)), -unsigned metadataignore __attribute__((unused)), -struct dm_list *mdas __attribute__((unused)),struct physical_volume *pv,struct volume_group *vg __attribute__((unused))) {
lib/format_pool/format_pool.c +0 -9
@@ -202,15 +202,6 @@ static int _pool_pv_initialise(const struct format_type *fmt __attribute__((unus }static int _pool_pv_setup (const struct format_type *fmt __attribute__((unused)), -uint64_t pe_start __attribute__((unused)), -uint32_t extent_count __attribute__((unused)), -uint32_t extent_size __attribute__((unused)), -unsigned long data_alignment __attribute__((unused)), -unsigned long data_alignment_offset __attribute__((unused)), -int pvmetadatacopies __attribute__((unused)), -uint64_t pvmetadatasize __attribute__((unused)), -unsigned metadataignore __attribute__((unused)), -struct dm_list *mdas __attribute__((unused)),struct physical_volume *pv __attribute__((unused)),struct volume_group *vg __attribute__((unused))) {
lib/format_text/archiver.c +1 -4
@@ -333,10 +333,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg) pv_dev_name(pv), info->fmt->name);return 0 ; } -if (!vg->fid->fmt->ops-> -pv_setup (vg->fid->fmt,UINT64_C (0 ),0 ,0 ,0 ,0 ,0UL , -UINT64_C (0 ),0 , - &vg->fid->metadata_areas_in_use, pv, vg)) { +if (!vg->fid->fmt->ops->pv_setup (vg->fid->fmt, pv, vg)) {log_error ("Format-specific setup for %s failed" ,pv_dev_name (pv));return 0 ;
lib/format_text/format-text.c +51 -132
202 lines not on this page · raw message
lib/metadata/metadata-exported.h +4 -3
@@ -397,9 +397,10 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,int pe_start_locked, uint32_t existing_extent_count, uint32_t existing_extent_size, - int pvmetadatacopies, uint64_t pvmetadatasize, - unsigned metadataignore, - struct dm_list *mdas); + uint64_t label_sector, + int pvmetadatacopies, + uint64_t pvmetadatasize, + unsigned metadataignore);int pv_resize (struct physical_volume *pv,struct volume_group *vg,uint32_t new_pe_count); int pv_analyze(struct cmd_context *cmd, const char *pv_name,
lib/metadata/metadata.c +23 -30
90 lines not on this page · raw message
lib/metadata/metadata.h +2 -6
@@ -261,12 +261,8 @@ struct format_handler {* vg. eg. pe_count is format specific. */ int (*pv_setup) (const struct format_type * fmt, -uint64_t pe_start,uint32_t extent_count, -uint32_t extent_size,unsigned long data_alignment, -unsigned long data_alignment_offset, -int pvmetadatacopies,uint64_t pvmetadatasize, -unsigned metadataignore,struct dm_list * mdas, -struct physical_volume * pv,struct volume_group * vg); +struct physical_volume * pv, +struct volume_group * vg);/* * Add metadata area to a PV. Changes will take effect on pv_write.
tools/vgconvert.c +4 -2
@@ -126,8 +126,10 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,if (!(pv =pv_create (cmd,pv_dev (existing_pv), &existing_pv->id, size,0 ,0 , pe_start,1 ,pv_pe_count (existing_pv), -pv_pe_size (existing_pv), pvmetadatacopies, - pvmetadatasize,0 , &mdas))) { +pv_pe_size (existing_pv), +arg_int64_value (cmd, labelsector_ARG, +DEFAULT_LABELSECTOR ), + pvmetadatacopies, pvmetadatasize,0 ))) {log_error ("Failed to setup physical volume \"%s\"" ,pv_dev_name (existing_pv));if (change_made)
Signature · 1 line
1.7.3.4
PATCH 12/17 Remove unused _mda_setup code.
In reply to Peter RajnohaThe functionality of former _mda_setup fn is now covered by pv_add_metadata_area fn.
--- lib/format_text/format-text.c | 153 ----------------------------------------- 1 files changed, 0 insertions(+), 153 deletions(-)
lib/format_text/format-text.c +0 -153
@@ -1256,159 +1256,6 @@ static int _text_scan(const struct format_type *fmt, const char *vgname)return (_scan_file (fmt, vgname) &_scan_raw (fmt, vgname)); } -/* For orphan, creates new mdas according to policy. -Always have an mda between end-of-label and pe_align() boundary */ -static int _mda_setup (const struct format_type *fmt, -uint64_t pe_start,uint64_t pe_end, -int pvmetadatacopies,uint64_t pvmetadatasize, -unsigned metadataignore,struct dm_list *mdas, -struct physical_volume *pv, -struct volume_group *vg __attribute__((unused))) -{ -uint64_t mda_adjustment, disk_size, alignment, alignment_offset; -uint64_t start1, mda_size1;/* First area - start of disk */ -uint64_t start2, mda_size2;/* Second area - end of disk */ -uint64_t wipe_size =8 <<SECTOR_SHIFT ; -size_t pagesize =lvm_getpagesize (); - -if (!pvmetadatacopies) -return 1 ; - - alignment = pv->pe_align <<SECTOR_SHIFT ; - alignment_offset = pv->pe_align_offset <<SECTOR_SHIFT ; - disk_size = pv->size <<SECTOR_SHIFT ; - pe_start <<=SECTOR_SHIFT ; - pe_end <<=SECTOR_SHIFT ; - -if (pe_end > disk_size) { -log_error ("Physical extents end beyond end of device %s!" , -pv_dev_name (pv)); -return 0 ; - } - -/* Requested metadatasize */ - mda_size1 = pvmetadatasize <<SECTOR_SHIFT ; - -/* Place mda straight after label area@start of disk */ - start1 =LABEL_SCAN_SIZE ; - -/* Unless the space available is tiny, round to PAGE_SIZE boundary */ -if ((!pe_start && !pe_end) || - ((pe_start > start1) && (pe_start - start1 >=MDA_SIZE_MIN ))) { - mda_adjustment = start1 % pagesize; -if (mda_adjustment) - start1 += (pagesize - mda_adjustment); - } - -/* Round up to pe_align boundary */ - mda_adjustment = (mda_size1 + start1) % alignment; -if (mda_adjustment) { - mda_size1 += (alignment - mda_adjustment); -/* Revert if it's now too large */ -if (start1 + mda_size1 > disk_size) - mda_size1 -= (alignment - mda_adjustment); - } - -/* Add pe_align_offset if on pe_align boundary */ -if (alignment_offset && - (((start1 + mda_size1) % alignment) ==0 )) { - mda_size1 += alignment_offset; -/* Revert if it's now too large */ -if (start1 + mda_size1 > disk_size) - mda_size1 -= alignment_offset; - } - -/* Ensure it's not going to be bigger than the disk! */ -if (start1 + mda_size1 > disk_size) { -log_warn ("WARNING: metadata area fills disk leaving no " -"space for data on %s." ,pv_dev_name (pv)); -/* Leave some free space for rounding */ -/* Avoid empty data area as could cause tools problems */ - mda_size1 = disk_size - start1 - alignment *2 ; -if (start1 + mda_size1 > disk_size) { -log_error ("Insufficient space for first mda on %s" , -pv_dev_name (pv)); -return 0 ; - } -/* Round up to pe_align boundary */ - mda_adjustment = (mda_size1 + start1) % alignment; -if (mda_adjustment) - mda_size1 += (alignment - mda_adjustment); -/* Only have 1 mda in this case */ - pvmetadatacopies =1 ; - } - -/* If we already have PEs, avoid overlap */ -if (pe_start || pe_end) { -if (pe_start <= start1) - mda_size1 =0 ; -else if (start1 + mda_size1 > pe_start) - mda_size1 = pe_start - start1; - } - -/* FIXME If creating new mdas, wipe them! */ -if (mda_size1) { -if (!add_mda (fmt, fmt->cmd->mem, mdas, pv->dev, start1, - mda_size1, metadataignore)) -return 0 ; - -if (!dev_set ((struct device *) pv->dev, start1, - (size_t ) (mda_size1 > - wipe_size ? : mda_size1),0 )) { -log_error ("Failed to wipe new metadata area" ); -return 0 ; - } - -if (pvmetadatacopies ==1 ) -return 1 ; - }else - start1 =0 ; - -/* A second copy at end of disk */ - mda_size2 = pvmetadatasize <<SECTOR_SHIFT ; - -/* Ensure it's not going to be bigger than the disk! */ -if (mda_size2 > disk_size) - mda_size2 = disk_size - start1 - mda_size1; - - mda_adjustment = (disk_size - mda_size2) % alignment; -if (mda_adjustment) - mda_size2 += mda_adjustment; - - start2 = disk_size - mda_size2; - -/* If we already have PEs, avoid overlap */ -if (pe_start || pe_end) { -if (start2 < pe_end) { - mda_size2 -= (pe_end - start2); - start2 = pe_end; - } - } - -/* If we already have a first mda, avoid overlap */ -if (mda_size1) { -if (start2 < start1 + mda_size1) { - mda_size2 -= (start1 + mda_size1 - start2); - start2 = start1 + mda_size1; - } -/* No room for any PEs here now! */ - } - -if (mda_size2) { -if (!add_mda (fmt, fmt->cmd->mem, mdas, pv->dev, start2, - mda_size2, metadataignore))return 0 ; -if (!dev_set (pv->dev, start2, - (size_t ) (mda_size1 > - wipe_size ? : mda_size1),0 )) { -log_error ("Failed to wipe new metadata area" ); -return 0 ; - } - }else -return 0 ; - -return 1 ; -} -/* Only for orphans */ /* Set label_sector to -1 if rewriting existing label into same sector */ /* If mdas is supplied it overwrites existing mdas e.g. used with pvcreate */
Signature · 1 line
1.7.3.4
PATCH 13/17 Cleanup pv_write code to use recent changes in metadata handling interface.
In reply to Peter RajnohaNow, we use the format_instance to retrieve the metadata areas to write to. Also, we sync the cache here (like we did before, but now with the format_instance).
--- lib/format1/format1.c | 3 +- lib/format_text/format-text.c | 147 ++++++++++++------------------------- lib/metadata/metadata-exported.h | 3 +- lib/metadata/metadata.c | 11 ++-- lib/metadata/metadata.h | 3 +- tools/pvchange.c | 4 +- tools/pvresize.c | 2 +- tools/vgconvert.c | 4 +- tools/vgreduce.c | 2 +- 9 files changed, 61 insertions(+), 118 deletions(-)
lib/format1/format1.c +1 -2
@@ -427,8 +427,7 @@ static int _format1_lv_setup(struct format_instance *fid, struct logical_volumereturn 1 ; } -static int _format1_pv_write (const struct format_type *fmt,struct physical_volume *pv, -struct dm_list *mdas __attribute__((unused)),int64_t sector __attribute__((unused))) +static int _format1_pv_write (const struct format_type *fmt,struct physical_volume *pv) {struct dm_pool *mem;struct disk_list *dl;
lib/format_text/format-text.c +48 -99
188 lines not on this page · raw message
lib/metadata/metadata-exported.h +1 -2
@@ -356,8 +356,7 @@ struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);struct dm_list *get_vgids (struct cmd_context *cmd,int include_internal);int scan_vgs_for_pvs (struct cmd_context *cmd,int warnings); -int pv_write (struct cmd_context *cmd,struct physical_volume *pv, -struct dm_list *mdas,int64_t label_sector); +int pv_write (struct cmd_context *cmd,struct physical_volume *pv);int move_pv (struct volume_group *vg_from,struct volume_group *vg_to,const char *pv_name); int move_pvs_used_by_lv(struct volume_group *vg_from,
lib/metadata/metadata.c +5 -6
@@ -586,7 +586,7 @@ int vg_remove(struct volume_group *vg) }/* FIXME Write to same sector label was read from */ -if (!pv_write (vg->cmd, pv,NULL ,INT64_C (-1 ))) { +if (!pv_write (vg->cmd, pv)) {log_error ("Failed to remove physical volume \"%s\"" " from volume group \"%s\"" ,pv_dev_name (pv), vg->name);
@@ -1503,7 +1503,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd,log_very_verbose ("Writing physical volume data to disk \"%s\"" , pv_name); -if (!(pv_write (cmd, pv, &mdas, pp->labelsector))) { +if (!(pv_write (cmd, pv))) {log_error ("Failed to write physical volume \"%s\"" , pv_name); goto error; }
@@ -3517,8 +3517,7 @@ int scan_vgs_for_pvs(struct cmd_context *cmd, int warnings) }int pv_write (struct cmd_context *cmd __attribute__((unused)), -struct physical_volume *pv, -struct dm_list *mdas,int64_t label_sector) +struct physical_volume *pv) {if (!pv->fmt->ops->pv_write) {log_error ("Format does not support writing physical volumes" );
@@ -3531,7 +3530,7 @@ int pv_write(struct cmd_context *cmd __attribute__((unused)),return 0 ; } -if (!pv->fmt->ops->pv_write (pv->fmt, pv, mdas, label_sector)) +if (!pv->fmt->ops->pv_write (pv->fmt, pv)) return_0;return 1 ;
@@ -3550,7 +3549,7 @@ int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)return 0 ; } -if (!pv_write (cmd, pv,NULL ,INT64_C (-1 ))) { +if (!pv_write (cmd, pv)) {log_error ("Failed to clear metadata from physical " "volume \"%s\" after removal from \"%s\"" ,pv_dev_name (pv), old_vg_name);
lib/metadata/metadata.h +1 -2
@@ -286,8 +286,7 @@ struct format_handler {* pv->vg_name must be a valid orphan VG name */ int (*pv_write) (const struct format_type * fmt, -struct physical_volume * pv,struct dm_list * mdas, -int64_t label_sector); +struct physical_volume * pv);/* * Tweak an already filled out a lv eg, check there
tools/pvchange.c +2 -2
@@ -160,7 +160,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg, pv->vg_name = pv->fmt->orphan_vg_name; pv->pe_alloc_count =0 ; -if (!(pv_write (cmd, pv,NULL ,INT64_C (-1 )))) { +if (!(pv_write (cmd, pv))) {log_error ("pv_write with new uuid failed " "for %s." , pv_name); goto out;
@@ -182,7 +182,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg, goto out; }backup (vg); - }else if (!(pv_write (cmd, pv,NULL ,INT64_C (-1 )))) { + }else if (!(pv_write (cmd, pv))) {log_error ("Failed to store physical volume \"%s\"" , pv_name); goto out;
tools/pvresize.c +1 -1
@@ -150,7 +150,7 @@ static int _pv_resize_single(struct cmd_context *cmd, goto out; }backup (vg); - }else if (!(pv_write (cmd, pv,NULL ,INT64_C (-1 )))) { + }else if (!(pv_write (cmd, pv))) {log_error ("Failed to store physical volume \"%s\"" , pv_name); goto out;
tools/vgconvert.c +1 -3
@@ -155,9 +155,7 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name,log_very_verbose ("Writing physical volume data to disk \"%s\"" ,pv_dev_name (pv)); -if (!(pv_write (cmd, pv, &mdas, -arg_int64_value (cmd, labelsector_ARG, -DEFAULT_LABELSECTOR )))) { +if (!(pv_write (cmd, pv))) {log_error ("Failed to write physical volume \"%s\"" ,pv_dev_name (pv)); log_error("Use pvcreate and vgcfgrestore to repair "
tools/vgreduce.c +1 -1
@@ -438,7 +438,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, goto bad; } -if (!pv_write (cmd, pv,NULL ,INT64_C (-1 ))) { +if (!pv_write (cmd, pv)) {log_error ("Failed to clear metadata from physical " "volume \"%s\" " "after removal from \"%s\"" , name, vg->name);
Signature · 1 line
1.7.3.4
PATCH 14/17 Use new metadata handling interface to provide better support for PV resize.
In reply to Peter RajnohaWhen resizing a PV that contains the 2nd metadata area at the end of the disk, we'll just remove the metadata area, do a resize and add the new one.
We also need a format-specific resize part of the code to be called so the format_handler interface now includes the pv_resize fn (metadata location is format-specific as well as the number of supported metadata area and the metadata layout itself).
The patch moves some parts of the PV resize code a bit to fit the changes better.
--- lib/format_text/format-text.c | 49 ++++++++++++++++++++++++++ lib/metadata/metadata-exported.h | 2 +- lib/metadata/metadata.h | 8 ++++ lib/metadata/pv_manip.c | 70 +++++++++++++++++++++++++++++--------- tools/pvresize.c | 51 +-------------------------- 5 files changed, 114 insertions(+), 66 deletions(-)
lib/format_text/format-text.c +49 -0
@@ -2083,6 +2083,54 @@ static int _text_pv_remove_metadata_area(const struct format_type *fmt,return remove_metadata_area_from_pv (pv, mda_index); } +static int _text_pv_resize (const struct format_type *fmt, +struct physical_volume *pv, +struct volume_group *vg, +uint64_t size) +{ +struct format_instance *fid = pv->fid; +const char *pvid = (const char *) &pv->id; +struct metadata_area *mda; +struct mda_context *mdac; +uint64_t size_reduction; +uint64_t mda_size; +unsigned mda_ignored; + +/* +* First, set the new size and update the cache and reset pe_count. +* (pe_count must be reset otherwise it would be considered as +* a limiting factor while moving the mda!) +*/ + pv->size = size; + pv->pe_count =0 ; + +/* If there's an mda at the end, move it to a new position. */ +if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,1 )) && + (mdac = mda->metadata_locn)) { +/* FIXME: Maybe MDA0 size would be better? */ + mda_size = mdac->area.size >>SECTOR_SHIFT ; + mda_ignored =mda_is_ignored (mda); + +if (!_text_pv_remove_metadata_area (fmt, pv,1 ) || + !_text_pv_add_metadata_area (fmt, pv,1 ,1 , mda_size, mda_ignored)) { +log_error ("Failed to move metadata area with index 1 " +"while resizing PV %s." ,pv_dev_name (pv)); +return 0 ; + } + } + +/* If there's a VG, reduce size by counting in pe_start and metadata areas. */ +if (vg) { + size_reduction =pv_pe_start (pv); +if ((mda =fid_get_mda_indexed (fid, pvid,ID_LEN ,1 )) && + (mdac = mda->metadata_locn)) + size_reduction += mdac->area.size >>SECTOR_SHIFT ; + pv->size -= size_reduction; + } + +return 1 ; +} +/* NULL vgname means use only the supplied context e.g. an archive file */ static struct format_instance *_text_create_text_instance(const struct format_type *fmt, const char *pvid,
@@ -2166,6 +2214,7 @@ static struct format_handler _text_handler = { .pv_setup = _text_pv_setup, .pv_add_metadata_area = _text_pv_add_metadata_area, .pv_remove_metadata_area = _text_pv_remove_metadata_area, + .pv_resize = _text_pv_resize, .pv_write = _text_pv_write, .vg_setup = _text_vg_setup, .lv_setup = _text_lv_setup,
lib/metadata/metadata-exported.h +1 -1
@@ -401,7 +401,7 @@ struct physical_volume *pv_create(const struct cmd_context *cmd,uint64_t pvmetadatasize, unsigned metadataignore);int pv_resize (struct physical_volume *pv,struct volume_group *vg, -uint32_t new_pe_count); +uint64_t size);int pv_analyze (struct cmd_context *cmd,const char *pv_name,uint64_t label_sector);
lib/metadata/metadata.h +8 -0
@@ -282,6 +282,14 @@ struct format_handler { unsigned metadata_index);/* +* Recalculate the PV size taking into account any existing metadata areas. +*/ +int (*pv_resize) (const struct format_type *fmt, +struct physical_volume *pv, +struct volume_group *vg, +uint64_t size); + +/* * Write a PV structure to disk. Fails if the PV is in a VG ie * pv->vg_name must be a valid orphan VG name */
lib/metadata/pv_manip.c +54 -16
94 lines not on this page · raw message
tools/pvresize.c +2 -49
82 lines not on this page · raw message
Signature · 1 line
1.7.3.4
PATCH 15/17 Change vg_convert code to actually work with recent changes in metadata handling interface.
In reply to Peter RajnohaWell, the problem with vgconvert was that it was a little bit mixed up code that used new PVs in new format to write PVs out and used former VG with the PV list to do a vg_write/vg_commit. So there was no interconnection among newly created PVs and the former VG.
When we pass the metadata area information in format_instance, this really couldn't work with current vgconvert code (unless I do an ugly hack :)). I need that PV<->VG interconnection. Otherwise I end up with no metadata areas to write to.
So, imho, to clean this up, we should probably replace VG's pv list with the newly created PVs in target format directly as we're creating those new PVs.
I defined a vg_convert fn that takes a VG and target format parameter and does the conversion. The converted VG structure could be used after that since it has also the right PV list with the new PVs in new format.
--- lib/format_text/format-text.c | 9 ++-- lib/metadata/metadata-exported.h | 3 + lib/metadata/metadata.c | 103 ++++++++++++++++++++++++++++++++++++++ tools/vgconvert.c | 93 ++++++++-------------------------- 4 files changed, 133 insertions(+), 75 deletions(-)
lib/format_text/format-text.c +5 -4
@@ -1656,11 +1656,12 @@ static int _text_pv_setup(const struct format_type *fmt, (pv_mdac = pv_mda->metadata_locn)) size_reduction = pv_mdac->area.size >>SECTOR_SHIFT ; -/* VG format instance will be used from now on. */ -if (pv->fid->pv_only) { +/* Destroy PV specific format instance. */ +if (pv->fid->pv_only) pv->fmt->ops->destroy_instance (pv->fid); - pv->fid = vg->fid; - } + +/* VG format instance will be used from now on. */ + pv->fid = vg->fid;/* FIXME Cope with genuine pe_count 0 */
lib/metadata/metadata-exported.h +3 -0
@@ -415,6 +415,9 @@ void vg_remove_pvs(struct volume_group *vg);int vg_remove (struct volume_group *vg);int vg_rename (struct cmd_context *cmd,struct volume_group *vg,const char *new_name); +int vg_convert (struct cmd_context *cmd,struct volume_group *vg, +const struct format_type *target_fmt,int64_t label_sector, +int pvmetadatacopies,uint64_t pvmetadatasize);int vg_extend (struct volume_group *vg,int pv_count,char **pv_names,struct pvcreate_params *pp);int vg_reduce (struct volume_group *vg,char *pv_name);
lib/metadata/metadata.c +103 -0
109 lines not on this page · raw message
tools/vgconvert.c +22 -71
159 lines not on this page · raw message
Signature · 1 line
1.7.3.4
PATCH 16/17 Fix pvchange -u to work with recent changes in metadata handling interface.
In reply to Peter RajnohaI use PV id as a key for format instance's metadata_areas_index. But since we change this one, I still need to work with the original one to access the metadata areas (e.g. in pv_write). So, I defined the pv->old_id to store that.
--- lib/format_text/format-text.c | 10 +++++----- lib/metadata/pv.h | 1 + tools/pvchange.c | 1 + 3 files changed, 7 insertions(+), 5 deletions(-)
lib/format_text/format-text.c +5 -5
@@ -1261,6 +1261,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume {struct text_fid_pv_context *fid_pv_tc;struct format_instance *fid = pv->fid; +const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);struct label *label;int64_t label_sector;struct lvmcache_info *info;
@@ -1303,8 +1304,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume* just pass the right format_instance in. */ for (mda_index =0 ; mda_index <FMT_TEXT_MAX_MDAS_PER_PV ; mda_index++) { -if (!(mda =fid_get_mda_indexed (fid, (const char *) &pv->id, -ID_LEN , mda_index))) +if (!(mda =fid_get_mda_indexed (fid, pvid,ID_LEN , mda_index)))continue ; mdac = (struct mda_context *) mda->metadata_locn;
@@ -1627,7 +1627,7 @@ static int _text_pv_setup(const struct format_type *fmt, struct volume_group *vg) {struct format_instance *fid = pv->fid; -const char *pvid = (const char *) &pv->id; +const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);unsigned mda_index;struct metadata_area *pv_mda;struct mda_context *pv_mdac;
@@ -1871,7 +1871,7 @@ static int _text_pv_add_metadata_area(const struct format_type *fmt, unsigned mda_ignored) {struct format_instance *fid = pv->fid; -const char *pvid = (char *) &pv->id; +const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);uint64_t pe_start, pe_end;uint64_t alignment, alignment_offset;uint64_t disk_size;
@@ -2090,7 +2090,7 @@ static int _text_pv_resize(const struct format_type *fmt, uint64_t size) {struct format_instance *fid = pv->fid; -const char *pvid = (const char *) &pv->id; +const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id);struct metadata_area *mda;struct mda_context *mdac;uint64_t size_reduction;
lib/metadata/pv.h +1 -0
@@ -22,6 +22,7 @@ struct volume_group;struct physical_volume {struct id id; +struct id old_id;/* Set during pvchange -u. */ struct device *dev;const struct format_type *fmt;struct format_instance *fid;
tools/pvchange.c +1 -0
@@ -141,6 +141,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg, goto out; }else {/* --uuid: Change PV ID randomly */ +memcpy (&pv->old_id, &pv->id,sizeof (pv->id));if (!id_create (&pv->id)) {log_error ("Failed to generate new random UUID for %s." , pv_name);
Signature · 1 line
1.7.3.4
PATCH 16/17 Fix pvchange -u to work with recent changes in metadata handling interface.
Quoted 4 lines · Peter Rajnoha
I use PV id as a key for format instance's
metadata_areas_index. But since we change this one, I still need to work with the original one to access the metadata areas (e.g. inpv_write). So, I defined thepv->old_idto store that.
One more thing to note. We should probably allow writing non-orphan PVs directly... The pv_write code calls:
/* Add a new cache entry with PV info or update existing one. */
if (!(info = lvmcache_add(fmt->labeller, (const char *) &pv->id,
pv->dev, FMT_TEXT_ORPHAN_VG_NAME, NULL, 0)))
return_0;..that changes any existing cache entry to be "orphaned", even if that PV is already part of a VG!
The code concerned is in outer pv_write fn that calls format specific pv_write code:
if (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count) {
log_error("Assertion failed: can't _pv_write non-orphan PV "
"(in VG %s)", pv->vg_name);
return 0;
}Also, the pvchange -u call is not quite nice today:
pv->vg_name = pv->fmt->orphan_vg_name;
pv->pe_alloc_count = 0;
if (!(pv_write(cmd, pv))) {
log_error("pv_write with new uuid failed "
"for %s.", pv_name);
goto out;
}
pv->vg_name = orig_vg_name;
pv->pe_alloc_count = orig_pe_alloc_count;To support calling pv_write on non-orphan PVs, we need to destroy the old cache item and insert a new one or just update the existing cache entry. But since the pvid is used as a key to cache pvid hash, we need to update this entry as well... But I don't see that as a problem. The change is quite easy, the question is whether it won't cause any other problems...
Peter
PATCH 17/17 Fix pvchange --metadataignore to work with recent changes in metadata handling interface.
In reply to Peter RajnohaThe pvchange --metadataignore is also hit by recent changes. We use the format_instance's metadata list, not the cache now (pv_write reads the format_instance, not the cache, so any changes in the cache would not take effect!).
--- lib/metadata/pv.c | 20 ++++++++++++-------- 1 files changed, 12 insertions(+), 8 deletions(-)
lib/metadata/pv.c +12 -8
@@ -248,13 +248,17 @@ unsigned pv_mda_set_ignored(const struct physical_volume *pv, unsigned mda_ignor {struct lvmcache_info *info;struct metadata_area *mda, *vg_mda, *tmda; -struct dm_list *vg_mdas_in_use, *vg_mdas_ignored; +struct dm_list *mdas_in_use, *mdas_ignored, *mdas_to_change;if (!(info =info_from_pvid ((const char *)&pv->id.uuid,0 ))) return_0; + mdas_in_use = &pv->fid->metadata_areas_in_use; + mdas_ignored = &pv->fid->metadata_areas_ignored; + mdas_to_change = mda_ignored ? mdas_in_use : mdas_ignored; +if (is_orphan (pv)) { - dm_list_iterate_items(mda, &info->mdas) + dm_list_iterate_items(mda, mdas_to_change)mda_set_ignored (mda, mda_ignored);return 1 ; }
@@ -279,19 +283,19 @@ unsigned pv_mda_set_ignored(const struct physical_volume *pv, unsigned mda_ignor* list, ensuring the new state will get written to disk in the * vg_write() path. */ - vg_mdas_in_use = &pv->vg->fid->metadata_areas_in_use; - vg_mdas_ignored = &pv->vg->fid->metadata_areas_ignored; - +/* FIXME: Try not to update the cache here! Also, try to iterate over +* PV mdas only using the format instance's index somehow +* (i.e. try to avoid using mda_locn_match call). */ dm_list_iterate_items(mda, &info->mdas) {if (mda_is_ignored (mda) && !mda_ignored)/* Changing an ignored mda to one in_use requires moving it */ - dm_list_iterate_items_safe(vg_mda, tmda, vg_mdas_ignored) + dm_list_iterate_items_safe(vg_mda, tmda, mdas_ignored)if (mda_locns_match (mda, vg_mda)) {mda_set_ignored (vg_mda, mda_ignored); -dm_list_move (vg_mdas_in_use, &vg_mda->list); +dm_list_move (mdas_in_use, &vg_mda->list); } - dm_list_iterate_items_safe(vg_mda, tmda, vg_mdas_in_use) + dm_list_iterate_items_safe(vg_mda, tmda, mdas_in_use)if (mda_locns_match (mda, vg_mda))/* Don't move mda: needs writing to disk. */ mda_set_ignored (vg_mda, mda_ignored);
Signature · 1 line
1.7.3.4
cover Add interface to support adding and removing metadata areas on demand (v2)
In reply to Peter RajnohaQuoted 1 line · Peter Rajnoha
The tests seems to be passing, just one is still failing - it's lvm2 format
...I meant lvm1 :) lvm2 format is fine.
Peter