From 2b52f658e23ba3a51e4396d767b61eab17ca3c99 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 31 2019 14:49:15 +0000 Subject: import lvm2-2.02.186-2.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f69a918 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/LVM2.2.02.186.tgz +SOURCES/boom-0.9.tar.gz diff --git a/.lvm2.metadata b/.lvm2.metadata new file mode 100644 index 0000000..e9512fd --- /dev/null +++ b/.lvm2.metadata @@ -0,0 +1,2 @@ +7a3834ca1ddaa7c4edc3863f18ec604f45722c65 SOURCES/LVM2.2.02.186.tgz +dd96613e238f342641b5be8977ee8598662e8ab9 SOURCES/boom-0.9.tar.gz diff --git a/SOURCES/lvm2-2_02_187-WHATS_NEW-vgcreate-vgextend-logical-block-size.patch b/SOURCES/lvm2-2_02_187-WHATS_NEW-vgcreate-vgextend-logical-block-size.patch new file mode 100644 index 0000000..586bfbe --- /dev/null +++ b/SOURCES/lvm2-2_02_187-WHATS_NEW-vgcreate-vgextend-logical-block-size.patch @@ -0,0 +1,33 @@ +From c5515908de62c3c68e12effad1aed7adc9e235f6 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 1 Aug 2019 10:15:27 -0500 +Subject: [PATCH 3/6] WHATS_NEW: vgcreate/vgextend logical block size + +(cherry picked from commit 3a0d493d918510d863ddbdbc63d8a8ccb6ca2dd9) + +Conflicts: + WHATS_NEW + +(cherry picked from commit 9fcda0d9752bf06b619d29aa6738b4ac52acedfc) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index cf2ec3e..d99f183 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,3 +1,7 @@ ++Version 2.02.187 - ++=================================== ++ Prevent creating VGs with PVs with different logical block sizes. ++ + Version 2.02.186 - 27th August 2019 + =================================== + Improve internal removal of cached devices. +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_187-cov-Fix-memory-leak.patch b/SOURCES/lvm2-2_02_187-cov-Fix-memory-leak.patch new file mode 100644 index 0000000..243bc2d --- /dev/null +++ b/SOURCES/lvm2-2_02_187-cov-Fix-memory-leak.patch @@ -0,0 +1,26 @@ +From a76bab1d408d75acc95a6ea8faaaaa298008b63e Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 28 Aug 2019 10:45:04 +0200 +Subject: [PATCH 1/6] cov: Fix memory leak + +--- + libdm/libdm-common.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c +index c300223..b06e678 100644 +--- a/libdm/libdm-common.c ++++ b/libdm/libdm-common.c +@@ -2012,7 +2012,8 @@ static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, siz + log_sys_error("readlink", sysfs_path); + else { + log_sys_debug("readlink", sysfs_path); +- return _sysfs_find_kernel_name(major, minor, buf, buf_size); ++ r = _sysfs_find_kernel_name(major, minor, buf, buf_size); ++ goto bad; + } + goto bad; + } +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_187-lvconvert-improve-validation-thin-and-cache-pool-con.patch b/SOURCES/lvm2-2_02_187-lvconvert-improve-validation-thin-and-cache-pool-con.patch new file mode 100644 index 0000000..2ba05aa --- /dev/null +++ b/SOURCES/lvm2-2_02_187-lvconvert-improve-validation-thin-and-cache-pool-con.patch @@ -0,0 +1,109 @@ +From 0cef052646dc4a1338a3febf38c3085cfa636cca Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Fri, 6 Sep 2019 18:09:40 +0200 +Subject: [PATCH 5/6] lvconvert: improve validation thin and cache pool + conversion + +Limit convertible LVs to thin-pool and cache-pools. +Also fix return code on interal error path to return ECMD_FAILED. + +(cherry picked from commit e147786bac52fea240955329963c9eed0eebfb18) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 1 + + tools/lvconvert.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 48 insertions(+), 5 deletions(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index 399864d..d1f4530 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -2,6 +2,7 @@ Version 2.02.187 - + =================================== + Prevent creating VGs with PVs with different logical block sizes. + Pvmove runs in exlusively activating mode for exclusively active LVs. ++ Enhance validation for thin and cache pool conversion and swapping. + + Version 2.02.186 - 27th August 2019 + =================================== +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index e66f063..799e746 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -4309,24 +4309,66 @@ static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd, + struct dm_list *use_pvh = NULL; + int to_thinpool = 0; + int to_cachepool = 0; ++ int lvt_enum = get_lvt_enum(lv); ++ struct lv_type *lvtype; + + switch (cmd->command->command_enum) { + case lvconvert_to_thinpool_or_swap_metadata_CMD: ++ if (lv_is_cache(lv)) ++ /* For cached LV check the cache origin LV type */ ++ lvt_enum = get_lvt_enum(seg_lv(first_seg(lv), 0)); + to_thinpool = 1; + break; + case lvconvert_to_cachepool_or_swap_metadata_CMD: ++ if (lv_is_cache(lv)) ++ goto_bad; /* Cache over cache is not supported */ + to_cachepool = 1; + break; + default: +- log_error(INTERNAL_ERROR "Invalid lvconvert pool command"); +- return 0; +- }; ++ log_error(INTERNAL_ERROR "Invalid lvconvert pool command."); ++ return ECMD_FAILED; ++ } ++ ++ switch (lvt_enum) { ++ case thinpool_LVT: ++ if (!to_thinpool) ++ goto_bad; /* can't accept cache-pool */ ++ break; /* swap thin-pool */ ++ case cachepool_LVT: ++ if (!to_cachepool) ++ goto_bad; /* can't accept thin-pool */ ++ break; /* swap cache-pool */ ++ case linear_LVT: ++ case raid_LVT: ++ case striped_LVT: ++ case zero_LVT: ++ break; ++ default: ++bad: ++ lvtype = get_lv_type(lvt_enum); ++ log_error("LV %s with type %s cannot be used as a %s pool LV.", ++ display_lvname(lv), lvtype ? lvtype->name : "unknown", ++ to_thinpool ? "thin" : "cache"); ++ return ECMD_FAILED; ++ } + + if (lv_is_origin(lv)) { + log_error("Cannot convert logical volume %s under snapshot.", + display_lvname(lv)); +- return 0; +- }; ++ return ECMD_FAILED; ++ } ++ ++ if (!lv_is_visible(lv)) { ++ log_error("Can't convert internal LV %s.", ++ display_lvname(lv)); ++ return ECMD_FAILED; ++ } ++ ++ if (lv_is_locked(lv)) { ++ log_error("Can't convert locked LV %s.", ++ display_lvname(lv)); ++ return ECMD_FAILED; ++ } + + if (cmd->position_argc > 1) { + /* First pos arg is required LV, remaining are optional PVs. */ +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_187-pvmove-check-if-participating-LV-is-already-exlcusiv.patch b/SOURCES/lvm2-2_02_187-pvmove-check-if-participating-LV-is-already-exlcusiv.patch new file mode 100644 index 0000000..2bd795d --- /dev/null +++ b/SOURCES/lvm2-2_02_187-pvmove-check-if-participating-LV-is-already-exlcusiv.patch @@ -0,0 +1,52 @@ +From 36265f58ae0def19b2bbe55443d77a10bad8eeca Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Wed, 18 Sep 2019 12:42:50 +0200 +Subject: [PATCH 4/6] pvmove: check if participating LV is already exlcusively + active + +When running pvmove, we need to decide whether pvmove has to be doing +exlusive or non-exclusive activations for LV. + +Whenever LV that requires exlusive activation is present, it makes +pvmove exlusive. But when there is already activate i.e. linear LV +in exclusive mode it also needs to switch pvmove into 'exlusively +activating' pvmove. + +(cherry picked from commit 1349b61bb72d3a42636053ede0d6fa71cd4f2d93) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 1 + + tools/pvmove.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/WHATS_NEW b/WHATS_NEW +index d99f183..399864d 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -1,6 +1,7 @@ + Version 2.02.187 - + =================================== + Prevent creating VGs with PVs with different logical block sizes. ++ Pvmove runs in exlusively activating mode for exclusively active LVs. + + Version 2.02.186 - 27th August 2019 + =================================== +diff --git a/tools/pvmove.c b/tools/pvmove.c +index 754bd58..3a447c4 100644 +--- a/tools/pvmove.c ++++ b/tools/pvmove.c +@@ -674,7 +674,8 @@ static int _pvmove_setup_single(struct cmd_context *cmd, + dm_list_iterate_items(lvl, lvs_changed) { + lvh = lv_lock_holder(lvl->lv); + /* Exclusive LV decides whether pvmove must be also exclusive */ +- if (lv_is_origin(lvh) || seg_only_exclusive(first_seg(lvh))) ++ if (lv_is_origin(lvh) || seg_only_exclusive(first_seg(lvh)) || ++ lv_is_active_exclusive(lvh)) + exclusive = 1; + } + +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_187-thin-activate-layer-pool-aas-read-only-LV.patch b/SOURCES/lvm2-2_02_187-thin-activate-layer-pool-aas-read-only-LV.patch new file mode 100644 index 0000000..41c70e3 --- /dev/null +++ b/SOURCES/lvm2-2_02_187-thin-activate-layer-pool-aas-read-only-LV.patch @@ -0,0 +1,55 @@ +From c1a6e218334ac561a695fa4cefd69208ba93107e Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Sat, 14 Sep 2019 01:08:14 +0200 +Subject: [PATCH 6/6] thin: activate layer pool aas read-only LV + +When lvm2 is activating layered pool LV (to basically keep pool opened, +the other function used to be 'locking' be in sync with DM table) +use this LV in read-only mode - this prevents 'write' access into +data volume content of thin-pool. + +Note: since EMPTY/unused thin-pool is created as 'public LV' for generic +use by any user who i.e. wish to maintain thin-pool and thins himself. +At this moment, thin-pool appears as writable LV. As soon as the 1st. +thinLV is created, layer volume will appear is 'read-only' LV from this moment. + +(cherry picked from commit 2e51535b18f3a05428f087f3916ebce5c08d58d1) + +Conflicts: + WHATS_NEW +--- + WHATS_NEW | 1 + + lib/activate/dev_manager.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/WHATS_NEW b/WHATS_NEW +index d1f4530..00b84f9 100644 +--- a/WHATS_NEW ++++ b/WHATS_NEW +@@ -2,6 +2,7 @@ Version 2.02.187 - + =================================== + Prevent creating VGs with PVs with different logical block sizes. + Pvmove runs in exlusively activating mode for exclusively active LVs. ++ Activate thin-pool layered volume as 'read-only' device. + Enhance validation for thin and cache pool conversion and swapping. + + Version 2.02.186 - 27th August 2019 +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index dc64159..56608e3 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -84,6 +84,11 @@ int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts + if (lv_is_raid_image(lv) || lv_is_raid_metadata(lv)) + return 0; /* Keep RAID SubLvs writable */ + ++ if (!layer) { ++ if (lv_is_thin_pool(lv)) ++ return 1; ++ } ++ + return (laopts->read_only || !(lv->status & LVM_WRITE)); + } + +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_187-vgcreate-vgextend-restrict-PVs-with-mixed-block-size.patch b/SOURCES/lvm2-2_02_187-vgcreate-vgextend-restrict-PVs-with-mixed-block-size.patch new file mode 100644 index 0000000..7a1f31f --- /dev/null +++ b/SOURCES/lvm2-2_02_187-vgcreate-vgextend-restrict-PVs-with-mixed-block-size.patch @@ -0,0 +1,231 @@ +From f450ffed18936a3b9a6249ad46b24741f7e7b2a3 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Thu, 1 Aug 2019 10:06:47 -0500 +Subject: [PATCH 2/6] vgcreate/vgextend: restrict PVs with mixed block sizes + +Avoid having PVs with different logical block sizes in the same VG. +This prevents LVs from having mixed block sizes, which can produce +file system errors. + +The new config setting devices/allow_mixed_block_sizes (default 0) +can be changed to 1 to return to the unrestricted mode. + +(cherry picked from commit 0404539edb25e4a9d3456bb3e6b402aa2767af6b) + +Conflicts: + tools/lvmcmdline.c + tools/toollib.c + +(cherry picked from commit a57b92dec396ac79c57e02e54c04e205aa85f084) +--- + lib/commands/toolcontext.h | 1 + + lib/config/config_settings.h | 5 +++++ + lib/metadata/metadata-exported.h | 1 + + lib/metadata/metadata.c | 44 +++++++++++++++++++++++++++++++++++++ + tools/lvmcmdline.c | 2 ++ + tools/toollib.c | 47 ++++++++++++++++++++++++++++++++++++++++ + tools/vgcreate.c | 2 ++ + 7 files changed, 102 insertions(+) + +diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h +index 4b2a079..497f4bd 100644 +--- a/lib/commands/toolcontext.h ++++ b/lib/commands/toolcontext.h +@@ -155,6 +155,7 @@ struct cmd_context { + unsigned include_shared_vgs:1; /* report/display cmds can reveal lockd VGs */ + unsigned include_active_foreign_vgs:1; /* cmd should process foreign VGs with active LVs */ + unsigned vg_read_print_access_error:1; /* print access errors from vg_read */ ++ unsigned allow_mixed_block_sizes:1; + unsigned force_access_clustered:1; + unsigned lockd_gl_disable:1; + unsigned lockd_vg_disable:1; +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index 9904a62..622e982 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -470,6 +470,11 @@ cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_ + "Enabling this setting allows the VG to be used as usual even with\n" + "uncertain devices.\n") + ++cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 3, 6), NULL, 0, NULL, ++ "Allow PVs in the same VG with different logical block sizes.\n" ++ "When allowed, the user is responsible to ensure that an LV is\n" ++ "using PVs with matching block sizes when necessary.\n") ++ + cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 77), NULL, 0, NULL, + "Advise LVM which PVs to use when searching for new space.\n" + "When searching for free space to extend an LV, the 'cling' allocation\n" +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index 2245c29..5674545 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -593,6 +593,7 @@ struct pvcreate_params { + unsigned is_remove : 1; /* is removing PVs, not creating */ + unsigned preserve_existing : 1; + unsigned check_failed : 1; ++ unsigned check_consistent_block_size : 1; + }; + + struct lvresize_params { +diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c +index 3620240..123f7f5 100644 +--- a/lib/metadata/metadata.c ++++ b/lib/metadata/metadata.c +@@ -699,12 +699,40 @@ int vg_extend_each_pv(struct volume_group *vg, struct pvcreate_params *pp) + { + struct pv_list *pvl; + unsigned int max_phys_block_size = 0; ++ unsigned int physical_block_size, logical_block_size; ++ unsigned int prev_lbs = 0; ++ int inconsistent_existing_lbs = 0; + + log_debug_metadata("Adding PVs to VG %s.", vg->name); + + if (vg_bad_status_bits(vg, RESIZEABLE_VG)) + return_0; + ++ /* ++ * Check if existing PVs have inconsistent block sizes. ++ * If so, do not enforce new devices to be consistent. ++ */ ++ dm_list_iterate_items(pvl, &vg->pvs) { ++ logical_block_size = 0; ++ physical_block_size = 0; ++ ++ if (!dev_get_direct_block_sizes(pvl->pv->dev, &physical_block_size, &logical_block_size)) ++ continue; ++ ++ if (!logical_block_size) ++ continue; ++ ++ if (!prev_lbs) { ++ prev_lbs = logical_block_size; ++ continue; ++ } ++ ++ if (prev_lbs != logical_block_size) { ++ inconsistent_existing_lbs = 1; ++ break; ++ } ++ } ++ + dm_list_iterate_items(pvl, &pp->pvs) { + log_debug_metadata("Adding PV %s to VG %s.", pv_dev_name(pvl->pv), vg->name); + +@@ -715,6 +743,22 @@ int vg_extend_each_pv(struct volume_group *vg, struct pvcreate_params *pp) + return 0; + } + ++ logical_block_size = 0; ++ physical_block_size = 0; ++ ++ if (!dev_get_direct_block_sizes(pvl->pv->dev, &physical_block_size, &logical_block_size)) ++ log_warn("WARNING: PV %s has unknown block size.", pv_dev_name(pvl->pv)); ++ ++ else if (prev_lbs && logical_block_size && (logical_block_size != prev_lbs)) { ++ if (vg->cmd->allow_mixed_block_sizes || inconsistent_existing_lbs) ++ log_debug("Devices have inconsistent block sizes (%u and %u)", prev_lbs, logical_block_size); ++ else { ++ log_error("Devices have inconsistent logical block sizes (%u and %u).", ++ prev_lbs, logical_block_size); ++ return 0; ++ } ++ } ++ + if (!add_pv_to_vg(vg, pv_dev_name(pvl->pv), pvl->pv, 0)) { + log_error("PV %s cannot be added to VG %s.", + pv_dev_name(pvl->pv), vg->name); +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index f238b64..f82827d 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -2308,6 +2308,8 @@ static int _get_current_settings(struct cmd_context *cmd) + if (cmd->cname->flags & CAN_USE_ONE_SCAN) + cmd->can_use_one_scan = 1; + ++ cmd->allow_mixed_block_sizes = find_config_tree_bool(cmd, devices_allow_mixed_block_sizes_CFG, NULL); ++ + cmd->partial_activation = 0; + cmd->degraded_activation = 0; + activation_mode = find_config_tree_str(cmd, activation_mode_CFG, NULL); +diff --git a/tools/toollib.c b/tools/toollib.c +index 81953ee..0b957cc 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -5506,6 +5506,8 @@ int pvcreate_each_device(struct cmd_context *cmd, + struct device_list *devl; + const char *pv_name; + int consistent = 0; ++ unsigned int physical_block_size, logical_block_size; ++ unsigned int prev_pbs = 0, prev_lbs = 0; + int must_use_all = (cmd->cname->flags & MUST_USE_ALL_ARGS); + int found; + unsigned i; +@@ -5584,6 +5586,51 @@ int pvcreate_each_device(struct cmd_context *cmd, + pd->dev = dev_cache_get(pd->name, cmd->full_filter); + + /* ++ * Check for consistent block sizes. ++ */ ++ if (pp->check_consistent_block_size) { ++ dm_list_iterate_items(pd, &pp->arg_devices) { ++ if (!pd->dev) ++ continue; ++ ++ logical_block_size = 0; ++ physical_block_size = 0; ++ ++ if (!dev_get_direct_block_sizes(pd->dev, &physical_block_size, &logical_block_size)) { ++ log_warn("WARNING: Unknown block size for device %s.", dev_name(pd->dev)); ++ continue; ++ } ++ ++ if (!logical_block_size) { ++ log_warn("WARNING: Unknown logical_block_size for device %s.", dev_name(pd->dev)); ++ continue; ++ } ++ ++ if (!prev_lbs) { ++ prev_lbs = logical_block_size; ++ prev_pbs = physical_block_size; ++ continue; ++ } ++ ++ if (prev_lbs == logical_block_size) { ++ /* Require lbs to match, just warn about unmatching pbs. */ ++ if (!cmd->allow_mixed_block_sizes && prev_pbs && physical_block_size && ++ (prev_pbs != physical_block_size)) ++ log_warn("WARNING: Devices have inconsistent physical block sizes (%u and %u).", ++ prev_pbs, physical_block_size); ++ continue; ++ } ++ ++ if (!cmd->allow_mixed_block_sizes) { ++ log_error("Devices have inconsistent logical block sizes (%u and %u).", ++ prev_lbs, logical_block_size); ++ log_print("See lvm.conf allow_mixed_block_sizes."); ++ return 0; ++ } ++ } ++ } ++ ++ /* + * Use process_each_pv to search all existing PVs and devices. + * + * This is a slightly different way to use process_each_pv, because the +diff --git a/tools/vgcreate.c b/tools/vgcreate.c +index 4356d99..7add53b 100644 +--- a/tools/vgcreate.c ++++ b/tools/vgcreate.c +@@ -48,6 +48,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) + /* Don't create a new PV on top of an existing PV like pvcreate does. */ + pp.preserve_existing = 1; + ++ pp.check_consistent_block_size = 1; ++ + if (!vgcreate_params_set_defaults(cmd, &vp_def, NULL)) + return EINVALID_CMD_LINE; + vp_def.vg_name = vg_name; +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-default-allow-changes-with-duplicate-pvs.patch b/SOURCES/lvm2-default-allow-changes-with-duplicate-pvs.patch new file mode 100644 index 0000000..72b7d21 --- /dev/null +++ b/SOURCES/lvm2-default-allow-changes-with-duplicate-pvs.patch @@ -0,0 +1,30 @@ + conf/example.conf.in | 2 +- + lib/config/defaults.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index 7ccf928..4418f56 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -325,7 +325,7 @@ devices { + # or activating LVs in it while a PV appears on multiple devices. + # Enabling this setting allows the VG to be used as usual even with + # uncertain devices. +- allow_changes_with_duplicate_pvs = 0 ++ allow_changes_with_duplicate_pvs = 1 + } + + # Configuration section allocation. +diff --git a/lib/config/defaults.h b/lib/config/defaults.h +index 6d3c37c..0d55928 100644 +--- a/lib/config/defaults.h ++++ b/lib/config/defaults.h +@@ -45,7 +45,7 @@ + #define DEFAULT_DATA_ALIGNMENT_DETECTION 1 + #define DEFAULT_ISSUE_DISCARDS 0 + #define DEFAULT_PV_MIN_SIZE_KB 2048 +-#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 0 ++#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 1 + + #define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so" + #define DEFAULT_ERROR_WHEN_FULL 0 diff --git a/SOURCES/lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch b/SOURCES/lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch new file mode 100644 index 0000000..d3207da --- /dev/null +++ b/SOURCES/lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch @@ -0,0 +1,114 @@ +From e8b1625c56aa1e2017cbcf8f7dfba30ac79396ce Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Wed, 29 Mar 2017 15:38:54 +0200 +Subject: [PATCH 4/7] + lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection + +--- + configure | 20 ++++++++++---------- + configure.ac | 4 ++-- + lib/device/dev-type.c | 3 +-- + 3 files changed, 13 insertions(+), 14 deletions(-) + +diff --git a/configure b/configure +index 4d2fb2f..f357462 100755 +--- a/configure ++++ b/configure +@@ -12111,12 +12111,12 @@ if test -n "$BLKID_CFLAGS"; then + pkg_cv_BLKID_CFLAGS="$BLKID_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ +- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5 +- ($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5 ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.23\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "blkid >= 2.23") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then +- pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.24" 2>/dev/null` ++ pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid >= 2.23" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes + else + pkg_failed=yes +@@ -12128,12 +12128,12 @@ if test -n "$BLKID_LIBS"; then + pkg_cv_BLKID_LIBS="$BLKID_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ +- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.24\""; } >&5 +- ($PKG_CONFIG --exists --print-errors "blkid >= 2.24") 2>&5 ++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid >= 2.23\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "blkid >= 2.23") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then +- pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.24" 2>/dev/null` ++ pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid >= 2.23" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes + else + pkg_failed=yes +@@ -12154,9 +12154,9 @@ else + _pkg_short_errors_supported=no + fi + if test $_pkg_short_errors_supported = yes; then +- BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.24" 2>&1` ++ BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid >= 2.23" 2>&1` + else +- BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.24" 2>&1` ++ BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid >= 2.23" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$BLKID_PKG_ERRORS" >&5 +@@ -12164,7 +12164,7 @@ fi + if test "$BLKID_WIPING" = maybe; then + BLKID_WIPING=no + else +- as_fn_error $? "bailing out... blkid library >= 2.24 is required" "$LINENO" 5 ++ as_fn_error $? "bailing out... blkid library >= 2.23 is required" "$LINENO" 5 + fi + elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +@@ -12172,7 +12172,7 @@ $as_echo "no" >&6; } + if test "$BLKID_WIPING" = maybe; then + BLKID_WIPING=no + else +- as_fn_error $? "bailing out... blkid library >= 2.24 is required" "$LINENO" 5 ++ as_fn_error $? "bailing out... blkid library >= 2.23 is required" "$LINENO" 5 + fi + else + BLKID_CFLAGS=$pkg_cv_BLKID_CFLAGS +diff --git a/configure.ac b/configure.ac +index 379d37f..e6bb905 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1235,7 +1235,7 @@ AC_ARG_ENABLE(blkid_wiping, + DEFAULT_USE_BLKID_WIPING=0 + if test "$BLKID_WIPING" != no; then + pkg_config_init +- PKG_CHECK_MODULES(BLKID, blkid >= 2.24, ++ PKG_CHECK_MODULES(BLKID, blkid >= 2.23, + [ BLKID_WIPING=yes + BLKID_PC="blkid" + DEFAULT_USE_BLKID_WIPING=1 +@@ -1243,7 +1243,7 @@ if test "$BLKID_WIPING" != no; then + ], [if test "$BLKID_WIPING" = maybe; then + BLKID_WIPING=no + else +- AC_MSG_ERROR([bailing out... blkid library >= 2.24 is required]) ++ AC_MSG_ERROR([bailing out... blkid library >= 2.23 is required]) + fi]) + fi + AC_MSG_CHECKING([whether to enable libblkid detection of signatures when wiping]) +diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c +index 14a28dc..c2e2365 100644 +--- a/lib/device/dev-type.c ++++ b/lib/device/dev-type.c +@@ -711,8 +711,7 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam + BLKID_SUBLKS_TYPE | + BLKID_SUBLKS_USAGE | + BLKID_SUBLKS_VERSION | +- BLKID_SUBLKS_MAGIC | +- BLKID_SUBLKS_BADCSUM); ++ BLKID_SUBLKS_MAGIC); + + while (!blkid_do_probe(probe)) { + if ((r_wipe = _blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force)) == 1) { diff --git a/SOURCES/lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch b/SOURCES/lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch new file mode 100644 index 0000000..5a941ea --- /dev/null +++ b/SOURCES/lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch @@ -0,0 +1,21 @@ + libdm/.exported_symbols.DM_1_02_107 | 1 + + libdm/.exported_symbols.DM_1_02_110 | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libdm/.exported_symbols.DM_1_02_107 b/libdm/.exported_symbols.DM_1_02_107 +index 89d3464..0c7b7af 100644 +--- a/libdm/.exported_symbols.DM_1_02_107 ++++ b/libdm/.exported_symbols.DM_1_02_107 +@@ -13,3 +13,4 @@ dm_stats_create_region + dm_stats_driver_supports_histogram + dm_stats_get_histogram + dm_stats_get_region_nr_histogram_bins ++dm_tree_node_size_changed +diff --git a/libdm/.exported_symbols.DM_1_02_110 b/libdm/.exported_symbols.DM_1_02_110 +index eba5625..da742ee 100644 +--- a/libdm/.exported_symbols.DM_1_02_110 ++++ b/libdm/.exported_symbols.DM_1_02_110 +@@ -1,3 +1,2 @@ + dm_report_compact_given_fields + dm_hold_control_dev +-dm_tree_node_size_changed diff --git a/SOURCES/lvm2-make-generate.patch b/SOURCES/lvm2-make-generate.patch new file mode 100644 index 0000000..ac74f50 --- /dev/null +++ b/SOURCES/lvm2-make-generate.patch @@ -0,0 +1,239 @@ + conf/example.conf.in | 20 ++++++++++++++++---- + man/pvcreate.8_pregen | 7 ++++--- + man/vgcfgrestore.8_pregen | 9 +++++---- + man/vgconvert.8_pregen | 14 +++++++++----- + man/vgcreate.8_pregen | 7 ++++--- + man/vgextend.8_pregen | 7 ++++--- + man/vgsplit.8_pregen | 7 ++++--- + 7 files changed, 46 insertions(+), 25 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index 4418f56..6f7b161 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -716,17 +716,29 @@ global { + activation = 1 + + # Configuration option global/fallback_to_lvm1. +- # This setting is no longer used. ++ # Try running LVM1 tools if LVM cannot communicate with DM. ++ # This option only applies to 2.4 kernels and is provided to help ++ # switch between device-mapper kernels and LVM1 kernels. The LVM1 ++ # tools need to be installed with .lvm1 suffices, e.g. vgscan.lvm1. ++ # They will stop working once the lvm2 on-disk metadata format is used. + # This configuration option has an automatic default value. +- # fallback_to_lvm1 = 0 ++ # fallback_to_lvm1 = @DEFAULT_FALLBACK_TO_LVM1@ + + # Configuration option global/format. +- # This setting is no longer used. ++ # The default metadata format that commands should use. ++ # The -M 1|2 option overrides this setting. ++ # ++ # Accepted values: ++ # lvm1 ++ # lvm2 ++ # + # This configuration option has an automatic default value. + # format = "lvm2" + + # Configuration option global/format_libraries. +- # This setting is no longer used. ++ # Shared libraries that process different metadata formats. ++ # If support for LVM1 metadata was compiled as a shared library use ++ # format_libraries = "liblvm2format1.so" + # This configuration option does not have a default value defined. + + # Configuration option global/segment_libraries. +diff --git a/man/pvcreate.8_pregen b/man/pvcreate.8_pregen +index c4b03da..abceb82 100644 +--- a/man/pvcreate.8_pregen ++++ b/man/pvcreate.8_pregen +@@ -38,7 +38,7 @@ normally prevent it, e.g. if the PV is already in a VG. + .ad b + .br + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -266,11 +266,12 @@ The size may be rounded. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l +diff --git a/man/vgcfgrestore.8_pregen b/man/vgcfgrestore.8_pregen +index cffd44b..e028103 100644 +--- a/man/vgcfgrestore.8_pregen ++++ b/man/vgcfgrestore.8_pregen +@@ -51,7 +51,7 @@ vgcfgrestore - Restore volume group configuration + .ad b + .br + .ad l +- \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .ad b + .br + .ad l +@@ -141,7 +141,7 @@ Common options for command: + . + .RS 4 + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -280,11 +280,12 @@ Display long help text. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l +diff --git a/man/vgconvert.8_pregen b/man/vgconvert.8_pregen +index 5e7f8a9..6228087 100644 +--- a/man/vgconvert.8_pregen ++++ b/man/vgconvert.8_pregen +@@ -8,9 +8,12 @@ vgconvert - Change volume group metadata format + [ \fIoption_args\fP ] + .br + .SH DESCRIPTION +-vgconvert converts VG metadata from one format to another. This command +-is no longer used because this version of lvm no longer supports the LVM1 ++vgconvert converts VG metadata from one format to another. The new ++metadata format must be able to fit into the space provided by the old + format. ++ ++Because the LVM1 format should no longer be used, this command is no ++longer needed in general. + .SH USAGE + \fBvgconvert\fP \fIVG\fP ... + .br +@@ -20,7 +23,7 @@ format. + .ad b + .br + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -191,11 +194,12 @@ The size may be rounded. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l +diff --git a/man/vgcreate.8_pregen b/man/vgcreate.8_pregen +index 09bf126..ddad391 100644 +--- a/man/vgcreate.8_pregen ++++ b/man/vgcreate.8_pregen +@@ -33,7 +33,7 @@ devices are also available with vgcreate. + .ad b + .br + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -324,11 +324,12 @@ The size may be rounded. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l +diff --git a/man/vgextend.8_pregen b/man/vgextend.8_pregen +index a6a30e9..ee805a8 100644 +--- a/man/vgextend.8_pregen ++++ b/man/vgextend.8_pregen +@@ -36,7 +36,7 @@ will initialize them. In this case pvcreate options can be used, e.g. + .ad b + .br + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -237,11 +237,12 @@ The size may be rounded. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l +diff --git a/man/vgsplit.8_pregen b/man/vgsplit.8_pregen +index 6c3e6ec..210c266 100644 +--- a/man/vgsplit.8_pregen ++++ b/man/vgsplit.8_pregen +@@ -62,7 +62,7 @@ Common options for command: + .ad b + .br + .ad l +-[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ] ++[ \fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP ] + .ad b + .br + .ad l +@@ -230,11 +230,12 @@ and --vgmetadatacopies for improving performance. + .ad b + .HP + .ad l +-\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP ++\fB-M\fP|\fB--metadatatype\fP \fBlvm2\fP|\fBlvm1\fP + .br + Specifies the type of on-disk metadata to use. + \fBlvm2\fP (or just \fB2\fP) is the current, standard format. +-\fBlvm1\fP (or just \fB1\fP) is no longer used. ++\fBlvm1\fP (or just \fB1\fP) is a historical format that ++can be used for accessing old data. + .ad b + .HP + .ad l diff --git a/SOURCES/lvm2-rhel7-add-lvm1-and-pool-back.patch b/SOURCES/lvm2-rhel7-add-lvm1-and-pool-back.patch new file mode 100644 index 0000000..a16d52e --- /dev/null +++ b/SOURCES/lvm2-rhel7-add-lvm1-and-pool-back.patch @@ -0,0 +1,6368 @@ + configure | 93 ++++- + configure.ac | 58 +++ + daemons/clvmd/clvmd-command.c | 1 + + daemons/clvmd/lvm-functions.c | 10 + + daemons/clvmd/lvm-functions.h | 1 + + daemons/lvmetad/lvmetad-client.h | 1 + + daemons/lvmetad/lvmetad-core.c | 9 +- + include/configure.h.in | 14 + + lib/Makefile.in | 29 ++ + lib/activate/activate.c | 13 + + lib/activate/activate.h | 1 + + lib/cache/lvmcache.c | 4 + + lib/cache/lvmetad.c | 23 +- + lib/commands/toolcontext.c | 24 ++ + lib/config/config_settings.h | 22 +- + lib/display/display.c | 9 +- + lib/format1/.exported_symbols | 1 + + lib/format1/Makefile.in | 33 ++ + lib/format1/disk-rep.c | 761 ++++++++++++++++++++++++++++++++++++++ + lib/format1/disk-rep.h | 250 +++++++++++++ + lib/format1/format1.c | 630 +++++++++++++++++++++++++++++++ + lib/format1/format1.h | 29 ++ + lib/format1/import-export.c | 680 ++++++++++++++++++++++++++++++++++ + lib/format1/import-extents.c | 377 +++++++++++++++++++ + lib/format1/layout.c | 172 +++++++++ + lib/format1/lvm1-label.c | 129 +++++++ + lib/format1/lvm1-label.h | 23 ++ + lib/format1/vg_number.c | 60 +++ + lib/format_pool/.exported_symbols | 1 + + lib/format_pool/Makefile.in | 30 ++ + lib/format_pool/disk_rep.c | 409 ++++++++++++++++++++ + lib/format_pool/disk_rep.h | 156 ++++++++ + lib/format_pool/format_pool.c | 337 +++++++++++++++++ + lib/format_pool/format_pool.h | 28 ++ + lib/format_pool/import_export.c | 285 ++++++++++++++ + lib/format_pool/pool_label.c | 104 ++++++ + lib/format_pool/pool_label.h | 23 ++ + lib/format_pool/sptype_names.h | 42 +++ + lib/format_text/export.c | 2 + + lib/format_text/format-text.c | 4 +- + lib/format_text/import_vsn1.c | 9 +- + lib/locking/locking.c | 40 ++ + lib/metadata/lv_manip.c | 26 ++ + lib/metadata/metadata-exported.h | 10 +- + lib/metadata/metadata.c | 18 +- + lib/metadata/segtype.h | 2 +- + lib/metadata/snapshot_manip.c | 11 + + lib/metadata/vg.c | 17 +- + lib/metadata/vg.h | 1 + + lib/report/report.c | 4 +- + lib/striped/striped.c | 3 +- + man/vgconvert.8_des | 7 +- + test/shell/format-lvm1.sh | 38 ++ + test/shell/lvm1-basic.sh | 36 ++ + test/shell/snapshot-lvm1.sh | 35 ++ + tools/args.h | 3 +- + tools/lvconvert.c | 5 + + tools/lvmcmdline.c | 59 ++- + tools/pvscan.c | 5 +- + tools/stub.h | 1 + + tools/toollib.c | 29 +- + tools/vals.h | 4 +- + tools/vgchange.c | 10 + + tools/vgconvert.c | 53 ++- + tools/vgscan.c | 4 +- + 65 files changed, 5255 insertions(+), 53 deletions(-) + create mode 100644 lib/format1/.exported_symbols + create mode 100644 lib/format1/Makefile.in + create mode 100644 lib/format1/disk-rep.c + create mode 100644 lib/format1/disk-rep.h + create mode 100644 lib/format1/format1.c + create mode 100644 lib/format1/format1.h + create mode 100644 lib/format1/import-export.c + create mode 100644 lib/format1/import-extents.c + create mode 100644 lib/format1/layout.c + create mode 100644 lib/format1/lvm1-label.c + create mode 100644 lib/format1/lvm1-label.h + create mode 100644 lib/format1/vg_number.c + create mode 100644 lib/format_pool/.exported_symbols + create mode 100644 lib/format_pool/Makefile.in + create mode 100644 lib/format_pool/disk_rep.c + create mode 100644 lib/format_pool/disk_rep.h + create mode 100644 lib/format_pool/format_pool.c + create mode 100644 lib/format_pool/format_pool.h + create mode 100644 lib/format_pool/import_export.c + create mode 100644 lib/format_pool/pool_label.c + create mode 100644 lib/format_pool/pool_label.h + create mode 100644 lib/format_pool/sptype_names.h + create mode 100644 test/shell/format-lvm1.sh + create mode 100644 test/shell/lvm1-basic.sh + create mode 100644 test/shell/snapshot-lvm1.sh + +diff --git a/configure b/configure +index f357462..2585e58 100755 +--- a/configure ++++ b/configure +@@ -675,6 +675,7 @@ PYTHON_BINDINGS + PYTHON3 + PTHREAD_LIBS + M_LIBS ++POOL + PKGCONFIG + ODIRECT + OCFDIR +@@ -689,6 +690,8 @@ LVM_MINOR + LVM_MAJOR + LVM_LIBAPI + LVM_VERSION ++LVM1_FALLBACK ++LVM1 + LIB_SUFFIX + LDDEPS + JOBS +@@ -716,6 +719,7 @@ DEFAULT_RAID10_SEGTYPE + DEFAULT_PROFILE_SUBDIR + DEFAULT_PID_DIR + DEFAULT_MIRROR_SEGTYPE ++DEFAULT_FALLBACK_TO_LVM1 + DEFAULT_LOCK_DIR + DEFAULT_DM_RUN_DIR + DEFAULT_DATA_ALIGNMENT +@@ -908,6 +912,9 @@ with_device_gid + with_device_mode + with_device_nodes_on + with_default_name_mangling ++enable_lvm1_fallback ++with_lvm1 ++with_pool + with_cluster + with_snapshots + with_mirrors +@@ -1673,6 +1680,8 @@ Optional Features: + speeds up one-time build. + --enable-static_link use this to link the tools to their libraries + statically (default is dynamic linking ++ --enable-lvm1_fallback use this to fall back and use LVM1 binaries if ++ device-mapper is missing from the kernel + --disable-thin_check_needs_check + required if thin_check version is < 0.3.0 + --disable-cache_check_needs_check +@@ -1739,6 +1748,10 @@ Optional Packages: + create nodes on resume or create [ON=resume] + --with-default-name-mangling=MANGLING + default name mangling: auto/none/hex [auto] ++ --with-lvm1=TYPE LVM1 metadata support: internal/shared/none ++ [internal] ++ --with-pool=TYPE GFS pool read-only support: internal/shared/none ++ [internal] + --with-cluster=TYPE cluster LVM locking support: internal/shared/none + [internal] + --with-snapshots=TYPE snapshot support: internal/shared/none [internal] +@@ -8372,6 +8385,78 @@ _ACEOF + + + ################################################################################ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable lvm1 fallback" >&5 ++$as_echo_n "checking whether to enable lvm1 fallback... " >&6; } ++# Check whether --enable-lvm1_fallback was given. ++if test "${enable_lvm1_fallback+set}" = set; then : ++ enableval=$enable_lvm1_fallback; LVM1_FALLBACK=$enableval ++else ++ LVM1_FALLBACK=no ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LVM1_FALLBACK" >&5 ++$as_echo "$LVM1_FALLBACK" >&6; } ++ ++if test "$LVM1_FALLBACK" = yes; then ++ DEFAULT_FALLBACK_TO_LVM1=1 ++ ++$as_echo "#define LVM1_FALLBACK 1" >>confdefs.h ++ ++else ++ DEFAULT_FALLBACK_TO_LVM1=0 ++fi ++ ++cat >>confdefs.h <<_ACEOF ++#define DEFAULT_FALLBACK_TO_LVM1 $DEFAULT_FALLBACK_TO_LVM1 ++_ACEOF ++ ++ ++################################################################################ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include support for lvm1 metadata" >&5 ++$as_echo_n "checking whether to include support for lvm1 metadata... " >&6; } ++ ++# Check whether --with-lvm1 was given. ++if test "${with_lvm1+set}" = set; then : ++ withval=$with_lvm1; LVM1=$withval ++else ++ LVM1=internal ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LVM1" >&5 ++$as_echo "$LVM1" >&6; } ++ ++case "$LVM1" in ++ none|shared) ;; ++ internal) ++$as_echo "#define LVM1_INTERNAL 1" >>confdefs.h ++ ;; ++ *) as_fn_error $? "--with-lvm1 parameter invalid" "$LINENO" 5 ;; ++esac ++ ++################################################################################ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include support for GFS pool metadata" >&5 ++$as_echo_n "checking whether to include support for GFS pool metadata... " >&6; } ++ ++# Check whether --with-pool was given. ++if test "${with_pool+set}" = set; then : ++ withval=$with_pool; POOL=$withval ++else ++ POOL=internal ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $POOL" >&5 ++$as_echo "$POOL" >&6; } ++ ++case "$POOL" in ++ none|shared) ;; ++ internal) ++$as_echo "#define POOL_INTERNAL 1" >>confdefs.h ++ ;; ++ *) as_fn_error $? "--with-pool parameter invalid" "$LINENO" 5 ++esac ++ ++################################################################################ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to include support for cluster locking" >&5 + $as_echo_n "checking whether to include support for cluster locking... " >&6; } + +@@ -15558,8 +15643,12 @@ _ACEOF + + + ++ ++ ++ ++ + ################################################################################ +-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmeventd/plugins/vdo/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile device_mapper/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/api/python_lvm_unit.py test/unit/Makefile tools/Makefile udev/Makefile" ++ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmeventd/plugins/vdo/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile device_mapper/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/api/python_lvm_unit.py test/unit/Makefile tools/Makefile udev/Makefile" + + cat >confcache <<\_ACEOF + # This file is a shell script that caches the results of configure +@@ -16286,6 +16375,8 @@ do + "include/.symlinks") CONFIG_FILES="$CONFIG_FILES include/.symlinks" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; ++ "lib/format1/Makefile") CONFIG_FILES="$CONFIG_FILES lib/format1/Makefile" ;; ++ "lib/format_pool/Makefile") CONFIG_FILES="$CONFIG_FILES lib/format_pool/Makefile" ;; + "lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;; + "include/lvm-version.h") CONFIG_FILES="$CONFIG_FILES include/lvm-version.h" ;; + "libdaemon/Makefile") CONFIG_FILES="$CONFIG_FILES libdaemon/Makefile" ;; +diff --git a/configure.ac b/configure.ac +index e6bb905..ad356b8 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -283,6 +283,58 @@ AC_MSG_RESULT($MANGLING) + AC_DEFINE_UNQUOTED([DEFAULT_DM_NAME_MANGLING], $mangling, [Define default name mangling behaviour]) + + ################################################################################ ++dnl -- LVM1 tool fallback option ++AC_MSG_CHECKING(whether to enable lvm1 fallback) ++AC_ARG_ENABLE(lvm1_fallback, ++ AC_HELP_STRING([--enable-lvm1_fallback], ++ [use this to fall back and use LVM1 binaries if ++ device-mapper is missing from the kernel]), ++ LVM1_FALLBACK=$enableval, LVM1_FALLBACK=no) ++AC_MSG_RESULT($LVM1_FALLBACK) ++ ++if test "$LVM1_FALLBACK" = yes; then ++ DEFAULT_FALLBACK_TO_LVM1=1 ++ AC_DEFINE([LVM1_FALLBACK], 1, [Define to 1 if 'lvm' should fall back to using LVM1 binaries if device-mapper is missing from the kernel]) ++else ++ DEFAULT_FALLBACK_TO_LVM1=0 ++fi ++AC_DEFINE_UNQUOTED(DEFAULT_FALLBACK_TO_LVM1, [$DEFAULT_FALLBACK_TO_LVM1], ++ [Fall back to LVM1 by default if device-mapper is missing from the kernel.]) ++ ++################################################################################ ++dnl -- format1 inclusion type ++AC_MSG_CHECKING(whether to include support for lvm1 metadata) ++AC_ARG_WITH(lvm1, ++ AC_HELP_STRING([--with-lvm1=TYPE], ++ [LVM1 metadata support: internal/shared/none [internal]]), ++ LVM1=$withval, LVM1=internal) ++ ++AC_MSG_RESULT($LVM1) ++ ++case "$LVM1" in ++ none|shared) ;; ++ internal) AC_DEFINE([LVM1_INTERNAL], 1, ++ [Define to 1 to include built-in support for LVM1 metadata.]) ;; ++ *) AC_MSG_ERROR([--with-lvm1 parameter invalid]) ;; ++esac ++ ++################################################################################ ++dnl -- format_pool inclusion type ++AC_MSG_CHECKING(whether to include support for GFS pool metadata) ++AC_ARG_WITH(pool, ++ AC_HELP_STRING([--with-pool=TYPE], ++ [GFS pool read-only support: internal/shared/none [internal]]), ++ POOL=$withval, POOL=internal) ++AC_MSG_RESULT($POOL) ++ ++case "$POOL" in ++ none|shared) ;; ++ internal) AC_DEFINE([POOL_INTERNAL], 1, ++ [Define to 1 to include built-in support for GFS pool metadata.]) ;; ++ *) AC_MSG_ERROR([--with-pool parameter invalid]) ++esac ++ ++################################################################################ + dnl -- cluster_locking inclusion type + AC_MSG_CHECKING(whether to include support for cluster locking) + AC_ARG_WITH(cluster, +@@ -1967,6 +2019,7 @@ AC_SUBST(DEFAULT_CACHE_SUBDIR) + AC_SUBST(DEFAULT_DATA_ALIGNMENT) + AC_SUBST(DEFAULT_DM_RUN_DIR) + AC_SUBST(DEFAULT_LOCK_DIR) ++AC_SUBST(DEFAULT_FALLBACK_TO_LVM1) + AC_SUBST(DEFAULT_MIRROR_SEGTYPE) + AC_SUBST(DEFAULT_PID_DIR) + AC_SUBST(DEFAULT_PROFILE_SUBDIR) +@@ -1997,6 +2050,8 @@ AC_SUBST(JOBS) + AC_SUBST(LDDEPS) + AC_SUBST(LIBS) + AC_SUBST(LIB_SUFFIX) ++AC_SUBST(LVM1) ++AC_SUBST(LVM1_FALLBACK) + AC_SUBST(LVM_VERSION) + AC_SUBST(LVM_LIBAPI) + AC_SUBST(LVM_MAJOR) +@@ -2013,6 +2068,7 @@ AC_SUBST(OCF) + AC_SUBST(OCFDIR) + AC_SUBST(ODIRECT) + AC_SUBST(PKGCONFIG) ++AC_SUBST(POOL) + AC_SUBST(M_LIBS) + AC_SUBST(PTHREAD_LIBS) + AC_SUBST(PYTHON2) +@@ -2118,6 +2174,8 @@ conf/metadata_profile_template.profile + include/.symlinks + include/Makefile + lib/Makefile ++lib/format1/Makefile ++lib/format_pool/Makefile + lib/locking/Makefile + include/lvm-version.h + libdaemon/Makefile +diff --git a/daemons/clvmd/clvmd-command.c b/daemons/clvmd/clvmd-command.c +index ce7f500..2971ecb 100644 +--- a/daemons/clvmd/clvmd-command.c ++++ b/daemons/clvmd/clvmd-command.c +@@ -108,6 +108,7 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen, + lock_flags = args[1]; + lockname = &args[2]; + /* Check to see if the VG is in use by LVM1 */ ++ status = do_check_lvm1(lockname); + do_lock_vg(lock_cmd, lock_flags, lockname); + break; + +diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c +index d6d395f..477c252 100644 +--- a/daemons/clvmd/lvm-functions.c ++++ b/daemons/clvmd/lvm-functions.c +@@ -639,6 +639,16 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags, + return 0; + } + ++/* Check if a VG is in use by LVM1 so we don't stomp on it */ ++int do_check_lvm1(const char *vgname) ++{ ++ int status; ++ ++ status = check_lvm1_vg_inactive(cmd, vgname); ++ ++ return status == 1 ? 0 : EBUSY; ++} ++ + int do_refresh_cache(void) + { + DEBUGLOG("Refreshing context\n"); +diff --git a/daemons/clvmd/lvm-functions.h b/daemons/clvmd/lvm-functions.h +index 6785997..eac966f 100644 +--- a/daemons/clvmd/lvm-functions.h ++++ b/daemons/clvmd/lvm-functions.h +@@ -25,6 +25,7 @@ extern int do_lock_lv(unsigned char lock_cmd, unsigned char lock_flags, + extern const char *do_lock_query(char *resource); + extern int post_lock_lv(unsigned char lock_cmd, unsigned char lock_flags, + char *resource); ++extern int do_check_lvm1(const char *vgname); + extern int do_refresh_cache(void); + extern int init_clvm(struct dm_hash_table *excl_uuid); + extern void destroy_lvm(void); +diff --git a/daemons/lvmetad/lvmetad-client.h b/daemons/lvmetad/lvmetad-client.h +index be2623a..a2adfe6 100644 +--- a/daemons/lvmetad/lvmetad-client.h ++++ b/daemons/lvmetad/lvmetad-client.h +@@ -22,6 +22,7 @@ + #define LVMETAD_TOKEN_UPDATE_IN_PROGRESS "update in progress" + + #define LVMETAD_DISABLE_REASON_DIRECT "DIRECT" ++#define LVMETAD_DISABLE_REASON_LVM1 "LVM1" + #define LVMETAD_DISABLE_REASON_DUPLICATES "DUPLICATES" + #define LVMETAD_DISABLE_REASON_VGRESTORE "VGRESTORE" + #define LVMETAD_DISABLE_REASON_REPAIR "REPAIR" +diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c +index 9ae359b..3e379fe 100644 +--- a/daemons/lvmetad/lvmetad-core.c ++++ b/daemons/lvmetad/lvmetad-core.c +@@ -200,12 +200,12 @@ struct vg_info { + #define GLFL_INVALID 0x00000001 + #define GLFL_DISABLE 0x00000002 + #define GLFL_DISABLE_REASON_DIRECT 0x00000004 +- /* 0x00000008 */ ++#define GLFL_DISABLE_REASON_LVM1 0x00000008 + #define GLFL_DISABLE_REASON_DUPLICATES 0x00000010 + #define GLFL_DISABLE_REASON_VGRESTORE 0x00000020 + #define GLFL_DISABLE_REASON_REPAIR 0x00000040 + +-#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_REPAIR | GLFL_DISABLE_REASON_DUPLICATES | GLFL_DISABLE_REASON_VGRESTORE) ++#define GLFL_DISABLE_REASON_ALL (GLFL_DISABLE_REASON_DIRECT | GLFL_DISABLE_REASON_REPAIR | GLFL_DISABLE_REASON_LVM1 | GLFL_DISABLE_REASON_DUPLICATES | GLFL_DISABLE_REASON_VGRESTORE) + + #define VGFL_INVALID 0x00000001 + +@@ -2369,6 +2369,8 @@ static response set_global_info(lvmetad_state *s, request r) + reason_flags |= GLFL_DISABLE_REASON_DIRECT; + if (strstr(reason, LVMETAD_DISABLE_REASON_REPAIR)) + reason_flags |= GLFL_DISABLE_REASON_REPAIR; ++ if (strstr(reason, LVMETAD_DISABLE_REASON_LVM1)) ++ reason_flags |= GLFL_DISABLE_REASON_LVM1; + if (strstr(reason, LVMETAD_DISABLE_REASON_DUPLICATES)) + reason_flags |= GLFL_DISABLE_REASON_DUPLICATES; + if (strstr(reason, LVMETAD_DISABLE_REASON_VGRESTORE)) +@@ -2427,9 +2429,10 @@ static response get_global_info(lvmetad_state *s, request r) + pid = (int)daemon_request_int(r, "pid", 0); + + if (s->flags & GLFL_DISABLE) { +- snprintf(reason, REASON_BUF_SIZE, "%s%s%s%s", ++ snprintf(reason, REASON_BUF_SIZE, "%s%s%s%s%s", + (s->flags & GLFL_DISABLE_REASON_DIRECT) ? LVMETAD_DISABLE_REASON_DIRECT "," : "", + (s->flags & GLFL_DISABLE_REASON_REPAIR) ? LVMETAD_DISABLE_REASON_REPAIR "," : "", ++ (s->flags & GLFL_DISABLE_REASON_LVM1) ? LVMETAD_DISABLE_REASON_LVM1 "," : "", + (s->flags & GLFL_DISABLE_REASON_DUPLICATES) ? LVMETAD_DISABLE_REASON_DUPLICATES "," : "", + (s->flags & GLFL_DISABLE_REASON_VGRESTORE) ? LVMETAD_DISABLE_REASON_VGRESTORE "," : ""); + } +diff --git a/include/configure.h.in b/include/configure.h.in +index 812cacc..bbeb565 100644 +--- a/include/configure.h.in ++++ b/include/configure.h.in +@@ -72,6 +72,10 @@ + /* Default system configuration directory. */ + #undef DEFAULT_ETC_DIR + ++/* Fall back to LVM1 by default if device-mapper is missing from the kernel. ++ */ ++#undef DEFAULT_FALLBACK_TO_LVM1 ++ + /* Name of default locking directory. */ + #undef DEFAULT_LOCK_DIR + +@@ -619,6 +623,13 @@ + slash. */ + #undef LSTAT_FOLLOWS_SLASHED_SYMLINK + ++/* Define to 1 if 'lvm' should fall back to using LVM1 binaries if ++ device-mapper is missing from the kernel */ ++#undef LVM1_FALLBACK ++ ++/* Define to 1 to include built-in support for LVM1 metadata. */ ++#undef LVM1_INTERNAL ++ + /* Path to lvmetad pidfile. */ + #undef LVMETAD_PIDFILE + +@@ -681,6 +692,9 @@ + /* Define to the version of this package. */ + #undef PACKAGE_VERSION + ++/* Define to 1 to include built-in support for GFS pool metadata. */ ++#undef POOL_INTERNAL ++ + /* Define to 1 to include built-in support for raid. */ + #undef RAID_INTERNAL + +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 1d42235..241cf09 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -16,6 +16,14 @@ srcdir = @srcdir@ + top_srcdir = @top_srcdir@ + top_builddir = @top_builddir@ + ++ifeq ("@LVM1@", "shared") ++ SUBDIRS = format1 ++endif ++ ++ifeq ("@POOL@", "shared") ++ SUBDIRS += format_pool ++endif ++ + ifeq ("@CLUSTER@", "shared") + SUBDIRS += locking + endif +@@ -107,6 +115,25 @@ SOURCES =\ + uuid/uuid.c \ + zero/zero.c + ++ifeq ("@LVM1@", "internal") ++ SOURCES +=\ ++ format1/disk-rep.c \ ++ format1/format1.c \ ++ format1/import-export.c \ ++ format1/import-extents.c \ ++ format1/layout.c \ ++ format1/lvm1-label.c \ ++ format1/vg_number.c ++endif ++ ++ifeq ("@POOL@", "internal") ++ SOURCES +=\ ++ format_pool/disk_rep.c \ ++ format_pool/format_pool.c \ ++ format_pool/import_export.c \ ++ format_pool/pool_label.c ++endif ++ + ifeq ("@CLUSTER@", "internal") + SOURCES += locking/cluster_locking.c + endif +@@ -143,6 +170,8 @@ LIB_STATIC = $(LIB_NAME).a + + ifeq ($(MAKECMDGOALS),distclean) + SUBDIRS =\ ++ format1 \ ++ format_pool \ + notify \ + locking + endif +diff --git a/lib/activate/activate.c b/lib/activate/activate.c +index 561a965..0790817 100644 +--- a/lib/activate/activate.c ++++ b/lib/activate/activate.c +@@ -37,6 +37,19 @@ + + #define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args) + ++int lvm1_present(struct cmd_context *cmd) ++{ ++ static char path[PATH_MAX]; ++ ++ if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir) ++ < 0) { ++ log_error("LVM1 proc global snprintf failed"); ++ return 0; ++ } ++ ++ return (path_exists(path)) ? 1 : 0; ++} ++ + int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg, + struct dm_list *modules) + { +diff --git a/lib/activate/activate.h b/lib/activate/activate.h +index 524d2bf..43d26d1 100644 +--- a/lib/activate/activate.h ++++ b/lib/activate/activate.h +@@ -91,6 +91,7 @@ int activation(void); + + int driver_version(char *version, size_t size); + int library_version(char *version, size_t size); ++int lvm1_present(struct cmd_context *cmd); + + int module_present(struct cmd_context *cmd, const char *target_name); + int target_present_version(struct cmd_context *cmd, const char *target_name, +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index 9890325..0bec548 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -22,6 +22,8 @@ + #include "memlock.h" + #include "str_list.h" + #include "format-text.h" ++#include "format_pool.h" ++#include "format1.h" + #include "config.h" + + #include "lvmetad.h" +@@ -545,6 +547,8 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted) + /* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */ + if (!strcmp(vgname, VG_ORPHANS)) { + _drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0); ++ _drop_metadata(FMT_LVM1_ORPHAN_VG_NAME, 0); ++ _drop_metadata(FMT_POOL_ORPHAN_VG_NAME, 0); + } else + _drop_metadata(vgname, drop_precommitted); + } +diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c +index d7e798d..1eda567 100644 +--- a/lib/cache/lvmetad.c ++++ b/lib/cache/lvmetad.c +@@ -38,6 +38,8 @@ static const char *_lvmetad_socket = NULL; + static struct cmd_context *_lvmetad_cmd = NULL; + static int64_t _lvmetad_update_timeout; + ++static int _found_lvm1_metadata = 0; ++ + static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg, const char *vgid, struct format_type *fmt); + + static uint64_t _monotonic_seconds(void) +@@ -2290,6 +2292,18 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev, + if (!baton.fid) + goto_bad; + ++ if (fmt->features & FMT_OBSOLETE) { ++ fmt->ops->destroy_instance(baton.fid); ++ log_warn("WARNING: Disabling lvmetad cache which does not support obsolete (lvm1) metadata."); ++ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_LVM1); ++ _found_lvm1_metadata = 1; ++ /* ++ * return 1 (success) so that we'll continue to populate lvmetad ++ * instead of leaving the update incomplete. ++ */ ++ return 1; ++ } ++ + lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton); + + if (!baton.vg) +@@ -2454,9 +2468,11 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait) + } + + /* +- * If lvmetad is disabled, and no duplicate PVs were seen, then re-enable lvmetad. ++ * If lvmetad is disabled, and no lvm1 metadata was seen and no ++ * duplicate PVs were seen, then re-enable lvmetad. + */ +- if (lvmetad_is_disabled(cmd, &reason) && !lvmcache_found_duplicate_pvs()) { ++ if (lvmetad_is_disabled(cmd, &reason) && ++ !lvmcache_found_duplicate_pvs() && !_found_lvm1_metadata) { + log_debug_lvmetad("Enabling lvmetad which was previously disabled."); + lvmetad_clear_disabled(cmd); + } +@@ -3104,6 +3120,9 @@ int lvmetad_is_disabled(struct cmd_context *cmd, const char **reason) + } else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_REPAIR)) { + *reason = "a repair command was run"; + ++ } else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_LVM1)) { ++ *reason = "LVM1 metadata was found"; ++ + } else if (strstr(reply_reason, LVMETAD_DISABLE_REASON_DUPLICATES)) { + *reason = "duplicate PVs were found"; + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index 95fb343..3db9bb3 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -36,6 +36,14 @@ + #include "sharedlib.h" + #endif + ++#ifdef LVM1_INTERNAL ++#include "format1.h" ++#endif ++ ++#ifdef POOL_INTERNAL ++#include "format_pool.h" ++#endif ++ + #include + #include + #include +@@ -1138,12 +1146,14 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd) + } + nr_filt++; + ++#if 0 + /* signature filter. Required. */ + if (!(filters[nr_filt] = signature_filter_create(cmd->dev_types))) { + log_error("Failed to create signature device filter"); + goto bad; + } + nr_filt++; ++#endif + + /* md component filter. Optional, non-critical. */ + if (find_config_tree_bool(cmd, devices_md_component_detection_CFG, NULL)) { +@@ -1344,6 +1354,20 @@ static int _init_formats(struct cmd_context *cmd) + const struct dm_config_node *cn; + #endif + ++#ifdef LVM1_INTERNAL ++ if (!(fmt = init_lvm1_format(cmd))) ++ return 0; ++ fmt->library = NULL; ++ dm_list_add(&cmd->formats, &fmt->list); ++#endif ++ ++#ifdef POOL_INTERNAL ++ if (!(fmt = init_pool_format(cmd))) ++ return 0; ++ fmt->library = NULL; ++ dm_list_add(&cmd->formats, &fmt->list); ++#endif ++ + #ifdef HAVE_LIBDL + /* Load any formats in shared libs if not static */ + if (!is_static() && +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index 02e2b29..9904a62 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -780,14 +780,26 @@ cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, D + "is not present in the kernel, disabling this should suppress\n" + "the error messages.\n") + +-cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 18), NULL, 0, NULL, +- "This setting is no longer used.\n") ++cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LVM1, vsn(1, 0, 18), "@DEFAULT_FALLBACK_TO_LVM1@", 0, NULL, ++ "Try running LVM1 tools if LVM cannot communicate with DM.\n" ++ "This option only applies to 2.4 kernels and is provided to help\n" ++ "switch between device-mapper kernels and LVM1 kernels. The LVM1\n" ++ "tools need to be installed with .lvm1 suffices, e.g. vgscan.lvm1.\n" ++ "They will stop working once the lvm2 on-disk metadata format is used.\n") + + cfg(global_format_CFG, "format", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL, 0, NULL, +- "This setting is no longer used.\n") +- ++ "The default metadata format that commands should use.\n" ++ "The -M 1|2 option overrides this setting.\n" ++ "#\n" ++ "Accepted values:\n" ++ " lvm1\n" ++ " lvm2\n" ++ "#\n") ++ + cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL, +- "This setting is no longer used.") ++ "Shared libraries that process different metadata formats.\n" ++ "If support for LVM1 metadata was compiled as a shared library use\n" ++ "format_libraries = \"liblvm2format1.so\"\n") + + cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL, 0, NULL, NULL) + +diff --git a/lib/display/display.c b/lib/display/display.c +index 9b4be88..9a928d9 100644 +--- a/lib/display/display.c ++++ b/lib/display/display.c +@@ -705,10 +705,13 @@ void vgdisplay_full(const struct volume_group *vg) + + log_print("--- Volume group ---"); + log_print("VG Name %s", vg->name); +- log_print("System ID %s", (vg->system_id && *vg->system_id) ? vg->system_id : ""); ++ log_print("System ID %s", (vg->system_id && *vg->system_id) ? vg->system_id : vg->lvm1_system_id ? : ""); + log_print("Format %s", vg->fid->fmt->name); +- log_print("Metadata Areas %d", vg_mda_count(vg)); +- log_print("Metadata Sequence No %d", vg->seqno); ++ if (vg->fid->fmt->features & FMT_MDAS) { ++ log_print("Metadata Areas %d", ++ vg_mda_count(vg)); ++ log_print("Metadata Sequence No %d", vg->seqno); ++ } + access_str = vg->status & (LVM_READ | LVM_WRITE); + log_print("VG Access %s%s%s%s", + access_str == (LVM_READ | LVM_WRITE) ? "read/write" : "", +diff --git a/lib/format1/.exported_symbols b/lib/format1/.exported_symbols +new file mode 100644 +index 0000000..e9fac2e +--- /dev/null ++++ b/lib/format1/.exported_symbols +@@ -0,0 +1 @@ ++init_format +diff --git a/lib/format1/Makefile.in b/lib/format1/Makefile.in +new file mode 100644 +index 0000000..4a905c0 +--- /dev/null ++++ b/lib/format1/Makefile.in +@@ -0,0 +1,33 @@ ++# ++# Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. ++# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. ++# ++# This file is part of LVM2. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++top_builddir = @top_builddir@ ++ ++SOURCES =\ ++ disk-rep.c \ ++ format1.c \ ++ import-export.c \ ++ import-extents.c \ ++ layout.c \ ++ lvm1-label.c \ ++ vg_number.c ++ ++LIB_SHARED = liblvm2format1.$(LIB_SUFFIX) ++LIB_VERSION = $(LIB_VERSION_LVM) ++ ++include $(top_builddir)/make.tmpl ++ ++install: install_lvm2_plugin +diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c +new file mode 100644 +index 0000000..9169d82 +--- /dev/null ++++ b/lib/format1/disk-rep.c +@@ -0,0 +1,761 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "disk-rep.h" ++#include "xlate.h" ++#include "lvmcache.h" ++#include "metadata-exported.h" ++ ++#include ++ ++#define xx16(v) disk->v = xlate16(disk->v) ++#define xx32(v) disk->v = xlate32(disk->v) ++#define xx64(v) disk->v = xlate64(disk->v) ++ ++/* ++ * Functions to perform the endian conversion ++ * between disk and core. The same code works ++ * both ways of course. ++ */ ++static void _xlate_pvd(struct pv_disk *disk) ++{ ++ xx16(version); ++ ++ xx32(pv_on_disk.base); ++ xx32(pv_on_disk.size); ++ xx32(vg_on_disk.base); ++ xx32(vg_on_disk.size); ++ xx32(pv_uuidlist_on_disk.base); ++ xx32(pv_uuidlist_on_disk.size); ++ xx32(lv_on_disk.base); ++ xx32(lv_on_disk.size); ++ xx32(pe_on_disk.base); ++ xx32(pe_on_disk.size); ++ ++ xx32(pv_major); ++ xx32(pv_number); ++ xx32(pv_status); ++ xx32(pv_allocatable); ++ xx32(pv_size); ++ xx32(lv_cur); ++ xx32(pe_size); ++ xx32(pe_total); ++ xx32(pe_allocated); ++ xx32(pe_start); ++} ++ ++static void _xlate_lvd(struct lv_disk *disk) ++{ ++ xx32(lv_access); ++ xx32(lv_status); ++ xx32(lv_open); ++ xx32(lv_dev); ++ xx32(lv_number); ++ xx32(lv_mirror_copies); ++ xx32(lv_recovery); ++ xx32(lv_schedule); ++ xx32(lv_size); ++ xx32(lv_snapshot_minor); ++ xx16(lv_chunk_size); ++ xx16(dummy); ++ xx32(lv_allocated_le); ++ xx32(lv_stripes); ++ xx32(lv_stripesize); ++ xx32(lv_badblock); ++ xx32(lv_allocation); ++ xx32(lv_io_timeout); ++ xx32(lv_read_ahead); ++} ++ ++static void _xlate_vgd(struct vg_disk *disk) ++{ ++ xx32(vg_number); ++ xx32(vg_access); ++ xx32(vg_status); ++ xx32(lv_max); ++ xx32(lv_cur); ++ xx32(lv_open); ++ xx32(pv_max); ++ xx32(pv_cur); ++ xx32(pv_act); ++ xx32(dummy); ++ xx32(vgda); ++ xx32(pe_size); ++ xx32(pe_total); ++ xx32(pe_allocated); ++ xx32(pvg_total); ++} ++ ++static void _xlate_extents(struct pe_disk *extents, uint32_t count) ++{ ++ unsigned i; ++ ++ for (i = 0; i < count; i++) { ++ extents[i].lv_num = xlate16(extents[i].lv_num); ++ extents[i].le_num = xlate16(extents[i].le_num); ++ } ++} ++ ++/* ++ * Handle both minor metadata formats. ++ */ ++static int _munge_formats(struct pv_disk *pvd) ++{ ++ uint32_t pe_start; ++ unsigned b, e; ++ ++ switch (pvd->version) { ++ case 1: ++ pvd->pe_start = ((pvd->pe_on_disk.base + ++ pvd->pe_on_disk.size) >> SECTOR_SHIFT); ++ break; ++ ++ case 2: ++ pvd->version = 1; ++ pe_start = pvd->pe_start << SECTOR_SHIFT; ++ pvd->pe_on_disk.size = pe_start - pvd->pe_on_disk.base; ++ break; ++ ++ default: ++ return 0; ++ } ++ ++ /* UUID too long? */ ++ if (pvd->pv_uuid[ID_LEN]) { ++ /* Retain ID_LEN chars from end */ ++ for (e = ID_LEN; e < sizeof(pvd->pv_uuid); e++) { ++ if (!pvd->pv_uuid[e]) { ++ e--; ++ break; ++ } ++ } ++ for (b = 0; b < ID_LEN; b++) { ++ pvd->pv_uuid[b] = pvd->pv_uuid[++e - ID_LEN]; ++ /* FIXME Remove all invalid chars */ ++ if (pvd->pv_uuid[b] == '/') ++ pvd->pv_uuid[b] = '#'; ++ } ++ memset(&pvd->pv_uuid[ID_LEN], 0, sizeof(pvd->pv_uuid) - ID_LEN); ++ } ++ ++ /* If UUID is missing, create one */ ++ if (pvd->pv_uuid[0] == '\0') { ++ uuid_from_num((char *)pvd->pv_uuid, pvd->pv_number); ++ pvd->pv_uuid[ID_LEN] = '\0'; ++ } ++ ++ return 1; ++} ++ ++/* ++ * If exported, remove "PV_EXP" from end of VG name ++ */ ++static void _munge_exported_vg(struct pv_disk *pvd) ++{ ++ int l; ++ size_t s; ++ ++ /* Return if PV not in a VG */ ++ if ((!*pvd->vg_name)) ++ return; ++ /* FIXME also check vgd->status & VG_EXPORTED? */ ++ ++ l = strlen((char *)pvd->vg_name); ++ s = sizeof(EXPORTED_TAG); ++ if (!strncmp((char *)pvd->vg_name + l - s + 1, EXPORTED_TAG, s)) { ++ pvd->vg_name[l - s + 1] = '\0'; ++ pvd->pv_status |= VG_EXPORTED; ++ } ++} ++ ++int munge_pvd(struct device *dev, struct pv_disk *pvd) ++{ ++ _xlate_pvd(pvd); ++ ++ if (pvd->id[0] != 'H' || pvd->id[1] != 'M') { ++ log_very_verbose("%s does not have a valid LVM1 PV identifier", ++ dev_name(dev)); ++ return 0; ++ } ++ ++ if (!_munge_formats(pvd)) { ++ log_very_verbose("format1: Unknown metadata version %d " ++ "found on %s", pvd->version, dev_name(dev)); ++ return 0; ++ } ++ ++ /* If VG is exported, set VG name back to the real name */ ++ _munge_exported_vg(pvd); ++ ++ return 1; ++} ++ ++static int _read_pvd(struct device *dev, struct pv_disk *pvd) ++{ ++ if (!dev_read_bytes(dev, UINT64_C(0), sizeof(*pvd), pvd)) { ++ log_very_verbose("Failed to read PV data from %s", ++ dev_name(dev)); ++ return 0; ++ } ++ ++ return munge_pvd(dev, pvd); ++} ++ ++static int _read_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk) ++{ ++ if (!dev_read_bytes(dev, pos, sizeof(*disk), disk)) ++ return_0; ++ ++ _xlate_lvd(disk); ++ ++ return 1; ++} ++ ++int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd) ++{ ++ uint64_t pos = pvd->vg_on_disk.base; ++ ++ if (!dev_read_bytes(dev, pos, sizeof(*vgd), vgd)) ++ return_0; ++ ++ _xlate_vgd(vgd); ++ ++ if ((vgd->lv_max > MAX_LV) || (vgd->pv_max > MAX_PV)) ++ return_0; ++ ++ /* If UUID is missing, create one */ ++ if (vgd->vg_uuid[0] == '\0') ++ uuid_from_num((char *)vgd->vg_uuid, vgd->vg_number); ++ ++ return 1; ++} ++ ++static int _read_uuids(struct disk_list *data) ++{ ++ unsigned num_read = 0; ++ struct uuid_list *ul; ++ char buffer[NAME_LEN] __attribute__((aligned(8))); ++ uint64_t pos = data->pvd.pv_uuidlist_on_disk.base; ++ uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size; ++ ++ while (pos < end && num_read < data->vgd.pv_cur) { ++ if (!dev_read_bytes(data->dev, pos, sizeof(buffer), buffer)) ++ return_0; ++ ++ if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul)))) ++ return_0; ++ ++ memcpy(ul->uuid, buffer, NAME_LEN); ++ ul->uuid[NAME_LEN - 1] = '\0'; ++ ++ dm_list_add(&data->uuids, &ul->list); ++ ++ pos += NAME_LEN; ++ num_read++; ++ } ++ ++ return 1; ++} ++ ++static int _check_lvd(struct lv_disk *lvd) ++{ ++ return !(lvd->lv_name[0] == '\0'); ++} ++ ++static int _read_lvs(struct disk_list *data) ++{ ++ unsigned int i, lvs_read = 0; ++ uint64_t pos; ++ struct lvd_list *ll; ++ struct vg_disk *vgd = &data->vgd; ++ ++ for (i = 0; (i < vgd->lv_max) && (lvs_read < vgd->lv_cur); i++) { ++ pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk)); ++ ll = dm_pool_alloc(data->mem, sizeof(*ll)); ++ ++ if (!ll) ++ return_0; ++ ++ if (!_read_lvd(data->dev, pos, &ll->lvd)) ++ return_0; ++ ++ if (!_check_lvd(&ll->lvd)) ++ continue; ++ ++ lvs_read++; ++ dm_list_add(&data->lvds, &ll->list); ++ } ++ ++ return 1; ++} ++ ++static int _read_extents(struct disk_list *data) ++{ ++ size_t len = sizeof(struct pe_disk) * data->pvd.pe_total; ++ struct pe_disk *extents = dm_pool_alloc(data->mem, len); ++ uint64_t pos = data->pvd.pe_on_disk.base; ++ ++ if (!extents) ++ return_0; ++ ++ if (!dev_read_bytes(data->dev, pos, len, extents)) ++ return_0; ++ ++ _xlate_extents(extents, data->pvd.pe_total); ++ data->extents = extents; ++ ++ return 1; ++} ++ ++static void __update_lvmcache(const struct format_type *fmt, ++ struct disk_list *dl, ++ struct device *dev, const char *vgid, ++ unsigned exported) ++{ ++ struct lvmcache_info *info; ++ const char *vgname = *((char *)dl->pvd.vg_name) ? ++ (char *)dl->pvd.vg_name : fmt->orphan_vg_name; ++ ++ if (!(info = lvmcache_add(fmt->labeller, (char *)dl->pvd.pv_uuid, dev, ++ vgname, vgid, exported ? EXPORTED_VG : 0))) { ++ stack; ++ return; ++ } ++ ++ lvmcache_set_device_size(info, ((uint64_t)xlate32(dl->pvd.pv_size)) << SECTOR_SHIFT); ++ lvmcache_del_mdas(info); ++} ++ ++static struct disk_list *__read_disk(const struct format_type *fmt, ++ struct device *dev, struct dm_pool *mem, ++ const char *vg_name) ++{ ++ struct disk_list *dl = dm_pool_zalloc(mem, sizeof(*dl)); ++ const char *name = dev_name(dev); ++ ++ if (!dl) ++ return_NULL; ++ ++ dl->dev = dev; ++ dl->mem = mem; ++ dm_list_init(&dl->uuids); ++ dm_list_init(&dl->lvds); ++ ++ if (!_read_pvd(dev, &dl->pvd)) ++ goto_bad; ++ ++ /* ++ * is it an orphan ? ++ */ ++ if (!*dl->pvd.vg_name) { ++ log_very_verbose("%s is not a member of any format1 VG", name); ++ ++ __update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0); ++ return (vg_name) ? NULL : dl; ++ } ++ ++ if (!read_vgd(dl->dev, &dl->vgd, &dl->pvd)) { ++ log_error("Failed to read VG data from PV (%s)", name); ++ __update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0); ++ goto bad; ++ } ++ ++ if (vg_name && strcmp(vg_name, (char *)dl->pvd.vg_name)) { ++ log_very_verbose("%s is not a member of the VG %s", ++ name, vg_name); ++ __update_lvmcache(fmt, dl, dev, fmt->orphan_vg_name, 0); ++ goto bad; ++ } ++ ++ __update_lvmcache(fmt, dl, dev, (char *)dl->vgd.vg_uuid, ++ dl->vgd.vg_status & VG_EXPORTED); ++ ++ if (!_read_uuids(dl)) { ++ log_error("Failed to read PV uuid list from %s", name); ++ goto bad; ++ } ++ ++ if (!_read_lvs(dl)) { ++ log_error("Failed to read LV's from %s", name); ++ goto bad; ++ } ++ ++ if (!_read_extents(dl)) { ++ log_error("Failed to read extents from %s", name); ++ goto bad; ++ } ++ ++ log_very_verbose("Found %s in %sVG %s", name, ++ (dl->vgd.vg_status & VG_EXPORTED) ? "exported " : "", ++ dl->pvd.vg_name); ++ ++ return dl; ++ ++ bad: ++ dm_pool_free(dl->mem, dl); ++ return NULL; ++} ++ ++struct disk_list *read_disk(const struct format_type *fmt, struct device *dev, ++ struct dm_pool *mem, const char *vg_name) ++{ ++ struct disk_list *dl; ++ ++ if (!dev_open_readonly(dev)) ++ return_NULL; ++ ++ dl = __read_disk(fmt, dev, mem, vg_name); ++ ++ if (!dev_close(dev)) ++ stack; ++ ++ return dl; ++} ++ ++static void _add_pv_to_list(struct cmd_context *cmd, struct dm_list *head, struct disk_list *data) ++{ ++ struct pv_disk *pvd; ++ struct disk_list *diskl; ++ ++ dm_list_iterate_items(diskl, head) { ++ pvd = &diskl->pvd; ++ if (!strncmp((char *)data->pvd.pv_uuid, (char *)pvd->pv_uuid, ++ sizeof(pvd->pv_uuid))) { ++ if (!dev_subsystem_part_major(cmd->dev_types, data->dev)) { ++ log_very_verbose("Ignoring duplicate PV %s on " ++ "%s", pvd->pv_uuid, ++ dev_name(data->dev)); ++ return; ++ } ++ log_very_verbose("Duplicate PV %s - using %s %s", ++ pvd->pv_uuid, dev_subsystem_name(cmd->dev_types, data->dev), ++ dev_name(data->dev)); ++ dm_list_del(&diskl->list); ++ break; ++ } ++ } ++ dm_list_add(head, &data->list); ++} ++ ++struct _read_pvs_in_vg_baton { ++ const char *vg_name; ++ struct dm_list *head; ++ struct disk_list *data; ++ struct dm_pool *mem; ++ int empty; ++}; ++ ++static int _read_pv_in_vg(struct lvmcache_info *info, void *baton) ++{ ++ struct _read_pvs_in_vg_baton *b = baton; ++ ++ b->empty = 0; ++ ++ if (!lvmcache_device(info) || ++ !(b->data = read_disk(lvmcache_fmt(info), lvmcache_device(info), b->mem, b->vg_name))) ++ return 0; /* stop here */ ++ ++ _add_pv_to_list(lvmcache_fmt(info)->cmd, b->head, b->data); ++ return 1; ++} ++ ++/* ++ * Build a list of pv_d's structures, allocated from mem. ++ * We keep track of the first object allocated from the pool ++ * so we can free off all the memory if something goes wrong. ++ */ ++int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name, ++ struct dev_filter *filter, struct dm_pool *mem, ++ struct dm_list *head) ++{ ++ struct dev_iter *iter; ++ struct device *dev; ++ struct lvmcache_vginfo *vginfo; ++ struct _read_pvs_in_vg_baton baton; ++ ++ baton.head = head; ++ baton.empty = 1; ++ baton.data = NULL; ++ baton.mem = mem; ++ baton.vg_name = vg_name; ++ ++ /* Fast path if we already saw this VG and cached the list of PVs */ ++ if (vg_name && (vginfo = lvmcache_vginfo_from_vgname(vg_name, NULL))) { ++ ++ lvmcache_foreach_pv(vginfo, _read_pv_in_vg, &baton); ++ ++ if (!baton.empty) { ++ /* Did we find the whole VG? */ ++ if (!vg_name || is_orphan_vg(vg_name) || ++ (baton.data && *baton.data->pvd.vg_name && ++ dm_list_size(head) == baton.data->vgd.pv_cur)) ++ return 1; ++ ++ /* Failed */ ++ dm_list_init(head); ++ /* vgcache_del(vg_name); */ ++ } ++ } ++ ++ if (!(iter = dev_iter_create(filter, 1))) { ++ log_error("read_pvs_in_vg: dev_iter_create failed"); ++ return 0; ++ } ++ ++ /* Otherwise do a complete scan */ ++ for (dev = dev_iter_get(iter); dev; dev = dev_iter_get(iter)) { ++ if ((baton.data = read_disk(fmt, dev, mem, vg_name))) { ++ _add_pv_to_list(fmt->cmd, head, baton.data); ++ } ++ } ++ dev_iter_destroy(iter); ++ ++ if (dm_list_empty(head)) ++ return 0; ++ ++ return 1; ++} ++ ++static int _write_vgd(struct disk_list *data) ++{ ++ struct vg_disk *vgd = &data->vgd; ++ uint64_t pos = data->pvd.vg_on_disk.base; ++ ++ log_debug_metadata("Writing %s VG metadata to %s at %" PRIu64 " len %" PRIsize_t, ++ data->pvd.vg_name, dev_name(data->dev), pos, sizeof(*vgd)); ++ ++ _xlate_vgd(vgd); ++ if (!dev_write(data->dev, pos, sizeof(*vgd), DEV_IO_FMT1, vgd)) ++ return_0; ++ ++ _xlate_vgd(vgd); ++ ++ return 1; ++} ++ ++static int _write_uuids(struct disk_list *data) ++{ ++ struct uuid_list *ul; ++ uint64_t pos = data->pvd.pv_uuidlist_on_disk.base; ++ uint64_t end = pos + data->pvd.pv_uuidlist_on_disk.size; ++ ++ dm_list_iterate_items(ul, &data->uuids) { ++ if (pos >= end) { ++ log_error("Too many uuids to fit on %s", ++ dev_name(data->dev)); ++ return 0; ++ } ++ ++ log_debug_metadata("Writing %s uuidlist to %s at %" PRIu64 " len %d", ++ data->pvd.vg_name, dev_name(data->dev), ++ pos, NAME_LEN); ++ ++ if (!dev_write(data->dev, pos, NAME_LEN, DEV_IO_FMT1, ul->uuid)) ++ return_0; ++ ++ pos += NAME_LEN; ++ } ++ ++ return 1; ++} ++ ++static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk) ++{ ++ log_debug_metadata("Writing %s LV %s metadata to %s at %" PRIu64 " len %" ++ PRIsize_t, disk->vg_name, disk->lv_name, dev_name(dev), ++ pos, sizeof(*disk)); ++ ++ _xlate_lvd(disk); ++ if (!dev_write(dev, pos, sizeof(*disk), DEV_IO_FMT1, disk)) ++ return_0; ++ ++ _xlate_lvd(disk); ++ ++ return 1; ++} ++ ++static int _write_lvs(struct disk_list *data) ++{ ++ struct lvd_list *ll; ++ uint64_t pos, offset; ++ ++ pos = data->pvd.lv_on_disk.base; ++ ++ if (!dev_set(data->dev, pos, data->pvd.lv_on_disk.size, DEV_IO_FMT1, 0)) { ++ log_error("Couldn't zero lv area on device '%s'", ++ dev_name(data->dev)); ++ return 0; ++ } ++ ++ dm_list_iterate_items(ll, &data->lvds) { ++ offset = sizeof(struct lv_disk) * ll->lvd.lv_number; ++ if (offset + sizeof(struct lv_disk) > data->pvd.lv_on_disk.size) { ++ log_error("lv_number %d too large", ll->lvd.lv_number); ++ return 0; ++ } ++ ++ if (!_write_lvd(data->dev, pos + offset, &ll->lvd)) ++ return_0; ++ } ++ ++ return 1; ++} ++ ++static int _write_extents(struct disk_list *data) ++{ ++ size_t len = sizeof(struct pe_disk) * data->pvd.pe_total; ++ struct pe_disk *extents = data->extents; ++ uint64_t pos = data->pvd.pe_on_disk.base; ++ ++ log_debug_metadata("Writing %s extents metadata to %s at %" PRIu64 " len %" ++ PRIsize_t, data->pvd.vg_name, dev_name(data->dev), ++ pos, len); ++ ++ _xlate_extents(extents, data->pvd.pe_total); ++ if (!dev_write(data->dev, pos, len, DEV_IO_FMT1, extents)) ++ return_0; ++ ++ _xlate_extents(extents, data->pvd.pe_total); ++ ++ return 1; ++} ++ ++static int _write_pvd(struct disk_list *data) ++{ ++ char *buf; ++ uint64_t pos = data->pvd.pv_on_disk.base; ++ size_t size = data->pvd.pv_on_disk.size; ++ ++ if (size < sizeof(struct pv_disk)) { ++ log_error("Invalid PV structure size."); ++ return 0; ++ } ++ ++ /* Make sure that the gap between the PV structure and ++ the next one is zeroed in order to make non LVM tools ++ happy (idea from AED) */ ++ buf = dm_zalloc(size); ++ if (!buf) { ++ log_error("Couldn't allocate temporary PV buffer."); ++ return 0; ++ } ++ ++ memcpy(buf, &data->pvd, sizeof(struct pv_disk)); ++ ++ log_debug_metadata("Writing %s PV metadata to %s at %" PRIu64 " len %" ++ PRIsize_t, data->pvd.vg_name, dev_name(data->dev), ++ pos, size); ++ ++ _xlate_pvd((struct pv_disk *) buf); ++ if (!dev_write(data->dev, pos, size, DEV_IO_FMT1, buf)) { ++ dm_free(buf); ++ return_0; ++ } ++ ++ dm_free(buf); ++ return 1; ++} ++ ++/* ++ * assumes the device has been opened. ++ */ ++static int __write_all_pvd(const struct format_type *fmt __attribute__((unused)), ++ struct disk_list *data, int write_vg_metadata) ++{ ++ const char *pv_name = dev_name(data->dev); ++ ++ if (!_write_pvd(data)) { ++ log_error("Failed to write PV structure onto %s", pv_name); ++ return 0; ++ } ++ ++ /* vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, fmt); */ ++ /* ++ * Stop here for orphan PVs or if VG metadata write not requested. ++ */ ++ if ((data->pvd.vg_name[0] == '\0') || !write_vg_metadata) { ++ /* if (!test_mode()) ++ vgcache_add(data->pvd.vg_name, NULL, data->dev, fmt); */ ++ return 1; ++ } ++ ++ /* if (!test_mode()) ++ vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, ++ fmt); */ ++ ++ if (!_write_vgd(data)) { ++ log_error("Failed to write VG data to %s", pv_name); ++ return 0; ++ } ++ ++ if (!_write_uuids(data)) { ++ log_error("Failed to write PV uuid list to %s", pv_name); ++ return 0; ++ } ++ ++ if (!_write_lvs(data)) { ++ log_error("Failed to write LV's to %s", pv_name); ++ return 0; ++ } ++ ++ if (!_write_extents(data)) { ++ log_error("Failed to write extents to %s", pv_name); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* ++ * opens the device and hands to the above fn. ++ */ ++static int _write_all_pvd(const struct format_type *fmt, struct disk_list *data, int write_vg_metadata) ++{ ++ int r; ++ ++ if (!data->dev) ++ return_0; ++ ++ if (!dev_open(data->dev)) ++ return_0; ++ ++ r = __write_all_pvd(fmt, data, write_vg_metadata); ++ ++ if (!dev_close(data->dev)) ++ stack; ++ ++ return r; ++} ++ ++/* ++ * Writes all the given pv's to disk. Does very ++ * little sanity checking, so make sure correct ++ * data is passed to here. ++ */ ++int write_disks(const struct format_type *fmt, struct dm_list *pvs, int write_vg_metadata) ++{ ++ struct disk_list *dl; ++ ++ dm_list_iterate_items(dl, pvs) { ++ if (!(_write_all_pvd(fmt, dl, write_vg_metadata))) ++ return_0; ++ ++ log_very_verbose("Successfully wrote data to %s", ++ dev_name(dl->dev)); ++ } ++ ++ return 1; ++} +diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h +new file mode 100644 +index 0000000..221ae8e +--- /dev/null ++++ b/lib/format1/disk-rep.h +@@ -0,0 +1,250 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef DISK_REP_FORMAT1_H ++#define DISK_REP_FORMAT1_H ++ ++#include "metadata.h" ++#include "toolcontext.h" ++ ++#define MAX_PV 256 ++#define MAX_LV 256 ++#define MAX_VG 99 ++ ++#define LVM_BLK_MAJOR 58 ++ ++#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */ ++#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */ ++#define MAX_LE_TOTAL 65534 /* 2^16 - 2 */ ++#define MAX_PE_TOTAL ((uint32_t) -2) ++ ++#define UNMAPPED_EXTENT 0 ++ ++/* volume group */ ++#define VG_ACTIVE 0x01 /* vg_status */ ++#define VG_EXPORTED 0x02 /* " */ ++#define VG_EXTENDABLE 0x04 /* " */ ++ ++#define VG_READ 0x01 /* vg_access */ ++#define VG_WRITE 0x02 /* " */ ++#define VG_CLUSTERED 0x04 /* " */ ++#define VG_SHARED 0x08 /* " */ ++ ++/* logical volume */ ++#define LV_ACTIVE 0x01 /* lv_status */ ++#define LV_SPINDOWN 0x02 /* " */ ++#define LV_PERSISTENT_MINOR 0x04 /* " */ ++ ++#define LV_READ 0x01 /* lv_access */ ++#define LV_WRITE 0x02 /* " */ ++#define LV_SNAPSHOT 0x04 /* " */ ++#define LV_SNAPSHOT_ORG 0x08 /* " */ ++ ++#define LV_BADBLOCK_ON 0x01 /* lv_badblock */ ++ ++#define LV_STRICT 0x01 /* lv_allocation */ ++#define LV_CONTIGUOUS 0x02 /* " */ ++ ++/* physical volume */ ++#define PV_ACTIVE 0x01 /* pv_status */ ++#define PV_ALLOCATABLE 0x02 /* pv_allocatable */ ++ ++#define EXPORTED_TAG "PV_EXP" /* Identifier for exported PV */ ++#define IMPORTED_TAG "PV_IMP" /* Identifier for imported PV */ ++ ++struct data_area { ++ uint32_t base; ++ uint32_t size; ++} __attribute__ ((packed)); ++ ++struct pv_disk { ++ int8_t id[2]; ++ uint16_t version; /* lvm version */ ++ struct data_area pv_on_disk; ++ struct data_area vg_on_disk; ++ struct data_area pv_uuidlist_on_disk; ++ struct data_area lv_on_disk; ++ struct data_area pe_on_disk; ++ int8_t pv_uuid[NAME_LEN]; ++ int8_t vg_name[NAME_LEN]; ++ int8_t system_id[NAME_LEN]; /* for vgexport/vgimport */ ++ uint32_t pv_major; ++ uint32_t pv_number; ++ uint32_t pv_status; ++ uint32_t pv_allocatable; ++ uint32_t pv_size; ++ uint32_t lv_cur; ++ uint32_t pe_size; ++ uint32_t pe_total; ++ uint32_t pe_allocated; ++ ++ /* only present on version == 2 pv's */ ++ uint32_t pe_start; ++} __attribute__ ((packed)); ++ ++struct lv_disk { ++ int8_t lv_name[NAME_LEN]; ++ int8_t vg_name[NAME_LEN]; ++ uint32_t lv_access; ++ uint32_t lv_status; ++ uint32_t lv_open; ++ uint32_t lv_dev; ++ uint32_t lv_number; ++ uint32_t lv_mirror_copies; /* for future use */ ++ uint32_t lv_recovery; /* " */ ++ uint32_t lv_schedule; /* " */ ++ uint32_t lv_size; ++ uint32_t lv_snapshot_minor; /* minor number of original */ ++ uint16_t lv_chunk_size; /* chunk size of snapshot */ ++ uint16_t dummy; ++ uint32_t lv_allocated_le; ++ uint32_t lv_stripes; ++ uint32_t lv_stripesize; ++ uint32_t lv_badblock; /* for future use */ ++ uint32_t lv_allocation; ++ uint32_t lv_io_timeout; /* for future use */ ++ uint32_t lv_read_ahead; ++} __attribute__ ((packed)); ++ ++struct vg_disk { ++ int8_t vg_uuid[ID_LEN]; /* volume group UUID */ ++ int8_t vg_name_dummy[NAME_LEN - ID_LEN]; /* rest of v1 VG name */ ++ uint32_t vg_number; /* volume group number */ ++ uint32_t vg_access; /* read/write */ ++ uint32_t vg_status; /* active or not */ ++ uint32_t lv_max; /* maximum logical volumes */ ++ uint32_t lv_cur; /* current logical volumes */ ++ uint32_t lv_open; /* open logical volumes */ ++ uint32_t pv_max; /* maximum physical volumes */ ++ uint32_t pv_cur; /* current physical volumes FU */ ++ uint32_t pv_act; /* active physical volumes */ ++ uint32_t dummy; ++ uint32_t vgda; /* volume group descriptor arrays FU */ ++ uint32_t pe_size; /* physical extent size in sectors */ ++ uint32_t pe_total; /* total of physical extents */ ++ uint32_t pe_allocated; /* allocated physical extents */ ++ uint32_t pvg_total; /* physical volume groups FU */ ++} __attribute__ ((packed)); ++ ++struct pe_disk { ++ uint16_t lv_num; ++ uint16_t le_num; ++} __attribute__ ((packed)); ++ ++struct uuid_list { ++ struct dm_list list; ++ char uuid[NAME_LEN] __attribute__((aligned(8))); ++}; ++ ++struct lvd_list { ++ struct dm_list list; ++ struct lv_disk lvd; ++}; ++ ++struct disk_list { ++ struct dm_list list; ++ struct dm_pool *mem; ++ struct device *dev; ++ ++ struct pv_disk pvd __attribute__((aligned(8))); ++ struct vg_disk vgd __attribute__((aligned(8))); ++ struct dm_list uuids __attribute__((aligned(8))); ++ struct dm_list lvds __attribute__((aligned(8))); ++ struct pe_disk *extents __attribute__((aligned(8))); ++}; ++ ++/* ++ * Layout constants. ++ */ ++#define METADATA_ALIGN 4096UL ++#define LVM1_PE_ALIGN (65536UL >> SECTOR_SHIFT) /* PE alignment */ ++ ++#define METADATA_BASE 0UL ++#define PV_SIZE 1024UL ++#define VG_SIZE 4096UL ++ ++/* ++ * Functions to calculate layout info. ++ */ ++int calculate_layout(struct disk_list *dl); ++int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size, ++ uint32_t max_extent_count, uint64_t pe_start); ++ ++/* ++ * Low level io routines which read/write ++ * disk_lists. ++ */ ++ ++struct disk_list *read_disk(const struct format_type *fmt, struct device *dev, ++ struct dm_pool *mem, const char *vg_name); ++ ++int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name, ++ struct dev_filter *filter, ++ struct dm_pool *mem, struct dm_list *results); ++ ++int write_disks(const struct format_type *fmt, struct dm_list *pvds, ++ int write_vg_metadata); ++ ++/* ++ * Functions to translate to between disk and in ++ * core structures. ++ */ ++int import_pv(const struct format_type *fmt, struct dm_pool *mem, ++ struct device *dev, struct volume_group *vg, ++ struct physical_volume *pv, struct pv_disk *pvd, ++ struct vg_disk *vgd); ++int export_pv(struct cmd_context *cmd, struct dm_pool *mem, ++ struct volume_group *vg, ++ struct pv_disk *pvd, struct physical_volume *pv); ++ ++int import_vg(struct dm_pool *mem, ++ struct volume_group *vg, struct disk_list *dl); ++int export_vg(struct vg_disk *vgd, struct volume_group *vg); ++ ++int import_lv(struct cmd_context *cmd, struct dm_pool *mem, ++ struct logical_volume *lv, struct lv_disk *lvd); ++ ++int import_extents(struct cmd_context *cmd, struct volume_group *vg, ++ struct dm_list *pvds); ++int export_extents(struct disk_list *dl, uint32_t lv_num, ++ struct logical_volume *lv, struct physical_volume *pv); ++ ++int import_pvs(const struct format_type *fmt, struct dm_pool *mem, ++ struct volume_group *vg, struct dm_list *pvds); ++ ++int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds); ++int export_lvs(struct disk_list *dl, struct volume_group *vg, ++ struct physical_volume *pv, const char *dev_dir); ++ ++int import_snapshots(struct dm_pool *mem, struct volume_group *vg, ++ struct dm_list *pvds); ++ ++int export_uuids(struct disk_list *dl, struct volume_group *vg); ++ ++void export_numbers(struct dm_list *pvds, struct volume_group *vg); ++ ++void export_pv_act(struct dm_list *pvds); ++int munge_pvd(struct device *dev, struct pv_disk *pvd); ++int read_vgd(struct device *dev, struct vg_disk *vgd, struct pv_disk *pvd); ++ ++/* blech */ ++int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, ++ const char *candidate_vg, int *result); ++int export_vg_number(struct format_instance *fid, struct dm_list *pvds, ++ const char *vg_name, struct dev_filter *filter); ++ ++int generate_lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix); ++ ++#endif +diff --git a/lib/format1/format1.c b/lib/format1/format1.c +new file mode 100644 +index 0000000..6e7e888 +--- /dev/null ++++ b/lib/format1/format1.c +@@ -0,0 +1,630 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "disk-rep.h" ++#include "limits.h" ++#include "display.h" ++#include "toolcontext.h" ++#include "lvm1-label.h" ++#include "format1.h" ++#include "segtype.h" ++#include "pv_alloc.h" ++ ++/* VG consistency checks */ ++static int _check_vgs(struct dm_list *pvs, struct volume_group *vg) ++{ ++ struct dm_list *pvh, *t; ++ struct disk_list *dl = NULL; ++ struct disk_list *first = NULL; ++ ++ uint32_t pv_count = 0; ++ uint32_t exported = 0; ++ int first_time = 1; ++ ++ /* ++ * If there are exported and unexported PVs, ignore exported ones. ++ * This means an active VG won't be affected if disks are inserted ++ * bearing an exported VG with the same name. ++ */ ++ dm_list_iterate_items(dl, pvs) { ++ if (first_time) { ++ exported = dl->pvd.pv_status & VG_EXPORTED; ++ first_time = 0; ++ continue; ++ } ++ ++ if (exported != (dl->pvd.pv_status & VG_EXPORTED)) { ++ /* Remove exported PVs */ ++ dm_list_iterate_safe(pvh, t, pvs) { ++ dl = dm_list_item(pvh, struct disk_list); ++ if (dl->pvd.pv_status & VG_EXPORTED) ++ dm_list_del(pvh); ++ } ++ break; ++ } ++ } ++ ++ /* Remove any PVs with VG structs that differ from the first */ ++ dm_list_iterate_safe(pvh, t, pvs) { ++ dl = dm_list_item(pvh, struct disk_list); ++ ++ if (!first) ++ first = dl; ++ ++ else if (memcmp(&first->vgd, &dl->vgd, sizeof(first->vgd))) { ++ log_error("VG data differs between PVs %s and %s", ++ dev_name(first->dev), dev_name(dl->dev)); ++ log_debug_metadata("VG data on %s: %s %s %" PRIu32 " %" PRIu32 ++ " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" ++ PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 ++ " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" ++ PRIu32 " %" PRIu32 " %" PRIu32, ++ dev_name(first->dev), first->vgd.vg_uuid, ++ first->vgd.vg_name_dummy, ++ first->vgd.vg_number, first->vgd.vg_access, ++ first->vgd.vg_status, first->vgd.lv_max, ++ first->vgd.lv_cur, first->vgd.lv_open, ++ first->vgd.pv_max, first->vgd.pv_cur, ++ first->vgd.pv_act, first->vgd.dummy, ++ first->vgd.vgda, first->vgd.pe_size, ++ first->vgd.pe_total, first->vgd.pe_allocated, ++ first->vgd.pvg_total); ++ log_debug_metadata("VG data on %s: %s %s %" PRIu32 " %" PRIu32 ++ " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" ++ PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 ++ " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" ++ PRIu32 " %" PRIu32 " %" PRIu32, ++ dev_name(dl->dev), dl->vgd.vg_uuid, ++ dl->vgd.vg_name_dummy, dl->vgd.vg_number, ++ dl->vgd.vg_access, dl->vgd.vg_status, ++ dl->vgd.lv_max, dl->vgd.lv_cur, ++ dl->vgd.lv_open, dl->vgd.pv_max, ++ dl->vgd.pv_cur, dl->vgd.pv_act, dl->vgd.dummy, ++ dl->vgd.vgda, dl->vgd.pe_size, ++ dl->vgd.pe_total, dl->vgd.pe_allocated, ++ dl->vgd.pvg_total); ++ dm_list_del(pvh); ++ return 0; ++ } ++ pv_count++; ++ } ++ ++ /* On entry to fn, list known to be non-empty */ ++ if (pv_count != first->vgd.pv_cur) { ++ log_error("%d PV(s) found for VG %s: expected %d", ++ pv_count, first->pvd.vg_name, first->vgd.pv_cur); ++ vg->status |= PARTIAL_VG; ++ } ++ ++ return 1; ++} ++ ++static int _fix_partial_vg(struct volume_group *vg, struct dm_list *pvs) ++{ ++ uint32_t extent_count = 0; ++ struct disk_list *dl; ++ struct dm_list *pvh; ++ struct pv_list *pvl; ++ struct lv_list *ll; ++ struct lv_segment *seg; ++ ++ /* ++ * FIXME: code should remap missing segments to error segment. ++ * Also current mapping code allocates 1 segment per missing extent. ++ * For now bail out completely - allocated structures are not complete ++ */ ++ dm_list_iterate_items(ll, &vg->lvs) ++ dm_list_iterate_items(seg, &ll->lv->segments) { ++ ++ /* area_count is always 1 here, s == 0 */ ++ if (seg_type(seg, 0) != AREA_PV) ++ continue; ++ ++ if (seg_pv(seg, 0)) ++ continue; ++ ++ log_error("Partial mode support for missing lvm1 PVs and " ++ "partially available LVs is currently not implemented."); ++ return 0; ++ } ++ ++ dm_list_iterate(pvh, pvs) { ++ dl = dm_list_item(pvh, struct disk_list); ++ extent_count += dl->pvd.pe_total; ++ } ++ ++ /* FIXME: move this to one place to pv_manip */ ++ if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl))) || ++ !(pvl->pv = dm_pool_zalloc(vg->vgmem, sizeof(*pvl->pv)))) ++ return_0; ++ ++ /* Use vg uuid with replaced first chars to "missing" as missing PV UUID */ ++ memcpy(&pvl->pv->id.uuid, vg->id.uuid, sizeof(pvl->pv->id.uuid)); ++ memcpy(&pvl->pv->id.uuid, "missing", 7); ++ ++ if (!(pvl->pv->vg_name = dm_pool_strdup(vg->vgmem, vg->name))) ++ goto_out; ++ memcpy(&pvl->pv->vgid, &vg->id, sizeof(vg->id)); ++ pvl->pv->status |= MISSING_PV; ++ dm_list_init(&pvl->pv->tags); ++ dm_list_init(&pvl->pv->segments); ++ ++ pvl->pv->pe_size = vg->extent_size; ++ pvl->pv->pe_count = vg->extent_count - extent_count; ++ if (!alloc_pv_segment_whole_pv(vg->vgmem, pvl->pv)) ++ goto_out; ++ ++ add_pvl_to_vgs(vg, pvl); ++ log_debug_metadata("%s: partial VG, allocated missing PV using %d extents.", ++ vg->name, pvl->pv->pe_count); ++ ++ return 1; ++out: ++ dm_pool_free(vg->vgmem, pvl); ++ return 0; ++} ++ ++static struct volume_group *_format1_vg_read(struct format_instance *fid, ++ const char *vg_name, ++ struct metadata_area *mda __attribute__((unused)), ++ struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)), ++ unsigned *use_previous_vg __attribute__((unused))) ++{ ++ struct volume_group *vg; ++ struct disk_list *dl; ++ DM_LIST_INIT(pvs); ++ ++ /* Strip dev_dir if present */ ++ if (vg_name) ++ vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir); ++ ++ if (!(vg = alloc_vg("format1_vg_read", fid->fmt->cmd, NULL))) ++ return_NULL; ++ ++ if (!read_pvs_in_vg(fid->fmt, vg_name, fid->fmt->cmd->filter, ++ vg->vgmem, &pvs)) ++ goto_bad; ++ ++ if (dm_list_empty(&pvs)) ++ goto_bad; ++ ++ if (!_check_vgs(&pvs, vg)) ++ goto_bad; ++ ++ dl = dm_list_item(pvs.n, struct disk_list); ++ ++ if (!import_vg(vg->vgmem, vg, dl)) ++ goto_bad; ++ ++ if (!import_pvs(fid->fmt, vg->vgmem, vg, &pvs)) ++ goto_bad; ++ ++ if (!import_lvs(vg->vgmem, vg, &pvs)) ++ goto_bad; ++ ++ if (!import_extents(fid->fmt->cmd, vg, &pvs)) ++ goto_bad; ++ ++ /* FIXME: workaround - temporary assignment of fid */ ++ vg->fid = fid; ++ if (!import_snapshots(vg->vgmem, vg, &pvs)) { ++ vg->fid = NULL; ++ goto_bad; ++ } ++ vg->fid = NULL; ++ ++ /* Fix extents counts by adding missing PV if partial VG */ ++ if ((vg->status & PARTIAL_VG) && !_fix_partial_vg(vg, &pvs)) ++ goto_bad; ++ ++ vg_set_fid(vg, fid); ++ ++ return vg; ++ ++bad: ++ release_vg(vg); ++ ++ return NULL; ++} ++ ++static struct disk_list *_flatten_pv(struct format_instance *fid, ++ struct dm_pool *mem, struct volume_group *vg, ++ struct physical_volume *pv, ++ const char *dev_dir) ++{ ++ struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl)); ++ ++ if (!dl) ++ return_NULL; ++ ++ dl->mem = mem; ++ dl->dev = pv->dev; ++ ++ dm_list_init(&dl->uuids); ++ dm_list_init(&dl->lvds); ++ ++ if (!export_pv(fid->fmt->cmd, mem, vg, &dl->pvd, pv) || ++ !export_vg(&dl->vgd, vg) || ++ !export_uuids(dl, vg) || ++ !export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) { ++ dm_pool_free(mem, dl); ++ return_NULL; ++ } ++ ++ return dl; ++} ++ ++static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem, ++ struct volume_group *vg, ++ struct dm_list *pvds, const char *dev_dir, ++ struct dev_filter *filter) ++{ ++ struct pv_list *pvl; ++ struct disk_list *data; ++ ++ dm_list_iterate_items(pvl, &vg->pvs) { ++ if (!(data = _flatten_pv(fid, mem, vg, pvl->pv, dev_dir))) ++ return_0; ++ ++ dm_list_add(pvds, &data->list); ++ } ++ ++ export_numbers(pvds, vg); ++ export_pv_act(pvds); ++ ++ if (!export_vg_number(fid, pvds, vg->name, filter)) ++ return_0; ++ ++ return 1; ++} ++ ++static int _format1_vg_write(struct format_instance *fid, struct volume_group *vg, ++ struct metadata_area *mda __attribute__((unused))) ++{ ++ struct dm_pool *mem = dm_pool_create("lvm1 vg_write", VG_MEMPOOL_CHUNK); ++ struct dm_list pvds; ++ int r = 0; ++ ++ if (!mem) ++ return_0; ++ ++ dm_list_init(&pvds); ++ ++ r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir, ++ fid->fmt->cmd->filter) && ++ write_disks(fid->fmt, &pvds, 1)); ++ ++ lvmcache_update_vg(vg, 0); ++ dm_pool_destroy(mem); ++ return r; ++} ++ ++static int _format1_pv_read(const struct format_type *fmt, const char *pv_name, ++ 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; ++ struct device *dev; ++ int r = 0; ++ ++ log_very_verbose("Reading physical volume data %s from disk", pv_name); ++ ++ if (!mem) ++ return_0; ++ ++ if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) ++ goto_out; ++ ++ if (!(dl = read_disk(fmt, dev, mem, NULL))) ++ goto_out; ++ ++ if (!import_pv(fmt, fmt->cmd->mem, dl->dev, NULL, pv, &dl->pvd, &dl->vgd)) ++ goto_out; ++ ++ pv->fmt = fmt; ++ ++ r = 1; ++ ++ out: ++ dm_pool_destroy(mem); ++ return r; ++} ++ ++static int _format1_pv_initialise(const struct format_type * fmt, ++ struct pv_create_args *pva, ++ struct physical_volume * pv) ++{ ++ if (pv->size > MAX_PV_SIZE) ++ pv->size--; ++ if (pv->size > MAX_PV_SIZE) { ++ log_error("Physical volumes cannot be bigger than %s", ++ display_size(fmt->cmd, (uint64_t) MAX_PV_SIZE)); ++ return 0; ++ } ++ ++ /* Nothing more to do if extent size isn't provided */ ++ if (!pva->extent_size) ++ return 1; ++ ++ /* ++ * This works out pe_start and pe_count. ++ */ ++ if (!calculate_extent_count(pv, pva->extent_size, pva->extent_count, pva->pe_start)) ++ return_0; ++ ++ /* Retain existing extent locations exactly */ ++ if (((pva->pe_start || pva->extent_count) && (pva->pe_start != pv->pe_start)) || ++ (pva->extent_count && (pva->extent_count != pv->pe_count))) { ++ log_error("Metadata would overwrite physical extents"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int _format1_pv_setup(const struct format_type *fmt, ++ struct physical_volume *pv, ++ struct volume_group *vg) ++{ ++ struct pv_create_args pva = { .id = {{0}}, ++ .idp = NULL, ++ .ba_start = 0, ++ .ba_size = 0, ++ .pe_start = 0, ++ .extent_count = 0, ++ .extent_size = vg->extent_size}; ++ ++ return _format1_pv_initialise(fmt, &pva, pv); ++} ++ ++static int _format1_lv_setup(struct format_instance *fid, struct logical_volume *lv) ++{ ++ uint64_t max_size = UINT_MAX; ++ ++ if (!*lv->lvid.s) ++ lvid_from_lvnum(&lv->lvid, &lv->vg->id, find_free_lvnum(lv)); ++ ++ if (lv->le_count > MAX_LE_TOTAL) { ++ log_error("logical volumes cannot contain more than " ++ "%d extents.", MAX_LE_TOTAL); ++ return 0; ++ } ++ if (lv->size > max_size) { ++ log_error("logical volumes cannot be larger than %s", ++ display_size(fid->fmt->cmd, max_size)); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int _format1_pv_write(const struct format_type *fmt, struct physical_volume *pv) ++{ ++ struct dm_pool *mem; ++ struct disk_list *dl; ++ struct dm_list pvs; ++ struct lvmcache_info *info; ++ int pe_count, pe_size, pe_start; ++ int r = 1; ++ ++ if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev, ++ pv->vg_name, NULL, 0))) ++ return_0; ++ ++ lvmcache_update_pv(info, pv, fmt); ++ lvmcache_del_mdas(info); ++ lvmcache_del_das(info); ++ lvmcache_del_bas(info); ++ ++ dm_list_init(&pvs); ++ ++ pe_count = pv->pe_count; ++ pe_size = pv->pe_size; ++ pe_start = pv->pe_start; ++ ++ /* Ensure any residual PE structure is gone */ ++ pv->pe_size = pv->pe_count = 0; ++ pv->pe_start = LVM1_PE_ALIGN; ++ ++ if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) ++ return_0; ++ ++ if (!(dl = dm_pool_alloc(mem, sizeof(*dl)))) ++ goto_bad; ++ ++ dl->mem = mem; ++ dl->dev = pv->dev; ++ dm_list_init(&dl->uuids); ++ dm_list_init(&dl->lvds); ++ ++ if (!export_pv(fmt->cmd, mem, NULL, &dl->pvd, pv)) ++ goto_bad; ++ ++ /* must be set to be able to zero gap after PV structure in ++ dev_write in order to make other disk tools happy */ ++ dl->pvd.pv_on_disk.base = METADATA_BASE; ++ dl->pvd.pv_on_disk.size = PV_SIZE; ++ dl->pvd.pe_on_disk.base = LVM1_PE_ALIGN << SECTOR_SHIFT; ++ ++ dm_list_add(&pvs, &dl->list); ++ if (!write_disks(fmt, &pvs, 0)) ++ goto_bad; ++ ++ goto out; ++ ++ bad: ++ r = 0; ++ ++ out: ++ pv->pe_size = pe_size; ++ pv->pe_count = pe_count; ++ pv->pe_start = pe_start; ++ ++ dm_pool_destroy(mem); ++ return r; ++} ++ ++static int _format1_vg_setup(struct format_instance *fid, struct volume_group *vg) ++{ ++ /* just check max_pv and max_lv */ ++ if (!vg->max_lv || vg->max_lv >= MAX_LV) ++ vg->max_lv = MAX_LV - 1; ++ ++ if (!vg->max_pv || vg->max_pv >= MAX_PV) ++ vg->max_pv = MAX_PV - 1; ++ ++ if (!vg_check_new_extent_size(vg->fid->fmt, vg->extent_size)) ++ return_0; ++ ++ /* Generate lvm1_system_id if not yet set */ ++ if (!*vg->lvm1_system_id && ++ !generate_lvm1_system_id(vg->cmd, vg->lvm1_system_id, "")) ++ return_0; ++ ++ return 1; ++} ++ ++static int _format1_segtype_supported(struct format_instance *fid __attribute__((unused)), ++ const struct segment_type *segtype) ++{ ++ if (!(segtype->flags & SEG_FORMAT1_SUPPORT)) ++ return_0; ++ ++ return 1; ++} ++ ++static struct metadata_area_ops _metadata_format1_ops = { ++ .vg_read = _format1_vg_read, ++ .vg_write = _format1_vg_write, ++}; ++ ++static struct format_instance *_format1_create_instance(const struct format_type *fmt, ++ const struct format_instance_ctx *fic) ++{ ++ struct format_instance *fid; ++ struct metadata_area *mda; ++ ++ if (!(fid = alloc_fid(fmt, fic))) ++ return_NULL; ++ ++ /* Define a NULL metadata area */ ++ if (!(mda = dm_pool_zalloc(fid->mem, sizeof(*mda)))) { ++ log_error("Unable to allocate metadata area structure " ++ "for lvm1 format"); ++ goto bad; ++ } ++ ++ mda->ops = &_metadata_format1_ops; ++ mda->metadata_locn = NULL; ++ mda->status = 0; ++ dm_list_add(&fid->metadata_areas_in_use, &mda->list); ++ ++ return fid; ++ ++bad: ++ dm_pool_destroy(fid->mem); ++ return NULL; ++} ++ ++static void _format1_destroy_instance(struct format_instance *fid) ++{ ++ if (--fid->ref_count <= 1) ++ dm_pool_destroy(fid->mem); ++} ++ ++static void _format1_destroy(struct format_type *fmt) ++{ ++ if (fmt->orphan_vg) ++ free_orphan_vg(fmt->orphan_vg); ++ ++ dm_free(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, ++ .vg_setup = _format1_vg_setup, ++ .segtype_supported = _format1_segtype_supported, ++ .create_instance = _format1_create_instance, ++ .destroy_instance = _format1_destroy_instance, ++ .destroy = _format1_destroy, ++}; ++ ++#ifdef LVM1_INTERNAL ++struct format_type *init_lvm1_format(struct cmd_context *cmd) ++#else /* Shared */ ++struct format_type *init_format(struct cmd_context *cmd); ++struct format_type *init_format(struct cmd_context *cmd) ++#endif ++{ ++ struct format_type *fmt = dm_malloc(sizeof(*fmt)); ++ struct format_instance_ctx fic; ++ struct format_instance *fid; ++ ++ if (!fmt) { ++ log_error("Failed to allocate format1 format type structure."); ++ return NULL; ++ } ++ ++ fmt->cmd = cmd; ++ fmt->ops = &_format1_ops; ++ fmt->name = FMT_LVM1_NAME; ++ fmt->alias = NULL; ++ fmt->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME; ++ fmt->features = FMT_RESTRICTED_LVIDS | FMT_ORPHAN_ALLOCATABLE | ++ FMT_RESTRICTED_READAHEAD | FMT_OBSOLETE | ++ FMT_SYSTEMID_ON_PVS; ++ fmt->private = NULL; ++ ++ dm_list_init(&fmt->mda_ops); ++ ++ if (!(fmt->labeller = lvm1_labeller_create(fmt))) { ++ log_error("Couldn't create lvm1 label handler."); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ if (!(label_register_handler(fmt->labeller))) { ++ log_error("Couldn't register lvm1 label handler."); ++ fmt->labeller->ops->destroy(fmt->labeller); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ if (!(fmt->orphan_vg = alloc_vg("format1_orphan", cmd, fmt->orphan_vg_name))) { ++ log_error("Couldn't create lvm1 orphan VG."); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ fic.type = FMT_INSTANCE_AUX_MDAS; ++ fic.context.vg_ref.vg_name = fmt->orphan_vg_name; ++ fic.context.vg_ref.vg_id = NULL; ++ ++ if (!(fid = _format1_create_instance(fmt, &fic))) { ++ _format1_destroy(fmt); ++ return_NULL; ++ } ++ ++ vg_set_fid(fmt->orphan_vg, fid); ++ ++ log_very_verbose("Initialised format: %s", fmt->name); ++ ++ return fmt; ++} +diff --git a/lib/format1/format1.h b/lib/format1/format1.h +new file mode 100644 +index 0000000..42ddc66 +--- /dev/null ++++ b/lib/format1/format1.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _LVM_FORMAT1_H ++#define _LVM_FORMAT1_H ++ ++#include "metadata.h" ++#include "lvmcache.h" ++ ++#define FMT_LVM1_NAME "lvm1" ++#define FMT_LVM1_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_LVM1_NAME) ++ ++#ifdef LVM1_INTERNAL ++struct format_type *init_lvm1_format(struct cmd_context *cmd); ++#endif ++ ++#endif +diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c +new file mode 100644 +index 0000000..c29527b +--- /dev/null ++++ b/lib/format1/import-export.c +@@ -0,0 +1,680 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/* ++ * Translates between disk and in-core formats. ++ */ ++ ++#include "lib.h" ++#include "disk-rep.h" ++#include "lvm-string.h" ++#include "toolcontext.h" ++#include "segtype.h" ++#include "pv_alloc.h" ++#include "display.h" ++#include "metadata.h" ++ ++#include ++ ++static int _check_vg_name(const char *name) ++{ ++ return strlen(name) < NAME_LEN; ++} ++ ++/* ++ * Extracts the last part of a path. ++ */ ++static char *_create_lv_name(struct dm_pool *mem, const char *full_name) ++{ ++ const char *ptr = strrchr(full_name, '/'); ++ ++ if (!ptr) ++ ptr = full_name; ++ else ++ ptr++; ++ ++ return dm_pool_strdup(mem, ptr); ++} ++ ++int import_pv(const struct format_type *fmt, struct dm_pool *mem, ++ struct device *dev, struct volume_group *vg, ++ struct physical_volume *pv, struct pv_disk *pvd, ++ struct vg_disk *vgd) ++{ ++ uint64_t size; ++ ++ memset(pv, 0, sizeof(*pv)); ++ memcpy(&pv->id, pvd->pv_uuid, ID_LEN); ++ ++ pv->dev = dev; ++ if (!*pvd->vg_name) ++ pv->vg_name = fmt->orphan_vg_name; ++ else if (!(pv->vg_name = dm_pool_strdup(mem, (char *)pvd->vg_name))) { ++ log_error("Volume Group name allocation failed."); ++ return 0; ++ } ++ ++ memcpy(&pv->vgid, vgd->vg_uuid, sizeof(vg->id)); ++ ++ /* Store system_id from first PV if PV belongs to a VG */ ++ if (vg && !*vg->lvm1_system_id) ++ strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN); ++ ++ if (vg && ++ strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id))) ++ log_very_verbose("System ID %s on %s differs from %s for " ++ "volume group", pvd->system_id, ++ pv_dev_name(pv), vg->lvm1_system_id); ++ ++ /* ++ * If exported, we still need to flag in pv->status too because ++ * we don't always have a struct volume_group when we need this. ++ */ ++ if (pvd->pv_status & VG_EXPORTED) ++ pv->status |= EXPORTED_VG; ++ ++ if (pvd->pv_allocatable) ++ pv->status |= ALLOCATABLE_PV; ++ ++ pv->size = pvd->pv_size; ++ pv->pe_size = pvd->pe_size; ++ pv->pe_start = pvd->pe_start; ++ pv->pe_count = pvd->pe_total; ++ pv->pe_alloc_count = 0; ++ pv->pe_align = 0; ++ pv->is_labelled = 0; /* format1 PVs have no label */ ++ pv->label_sector = 0; ++ ++ /* Fix up pv size if missing or impossibly large */ ++ if (!pv->size || pv->size > (1ULL << 62)) { ++ if (!dev_get_size(dev, &pv->size)) { ++ log_error("%s: Couldn't get size.", pv_dev_name(pv)); ++ return 0; ++ } ++ log_verbose("Fixing up missing format1 size (%s) " ++ "for PV %s", display_size(fmt->cmd, pv->size), ++ pv_dev_name(pv)); ++ if (vg) { ++ size = pv->pe_count * (uint64_t) vg->extent_size + ++ pv->pe_start; ++ if (size > pv->size) ++ log_warn("WARNING: Physical Volume %s is too " ++ "large for underlying device", ++ pv_dev_name(pv)); ++ } ++ } ++ ++ dm_list_init(&pv->tags); ++ dm_list_init(&pv->segments); ++ ++ if (!alloc_pv_segment_whole_pv(mem, pv)) ++ return_0; ++ ++ return 1; ++} ++ ++int generate_lvm1_system_id(struct cmd_context *cmd, char *s, const char *prefix) ++{ ++ ++ if (dm_snprintf(s, NAME_LEN, "%s%s" FMTu64, ++ prefix, cmd->hostname, (uint64_t)time(NULL)) < 0) { ++ log_error("Generated LVM1 format system_id too long"); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused)), ++ struct volume_group *vg, ++ struct pv_disk *pvd, struct physical_volume *pv) ++{ ++ memset(pvd, 0, sizeof(*pvd)); ++ ++ pvd->id[0] = 'H'; ++ pvd->id[1] = 'M'; ++ pvd->version = 1; ++ ++ memcpy(pvd->pv_uuid, pv->id.uuid, ID_LEN); ++ ++ if (pv->vg_name && !is_orphan(pv) && !(pv->status & UNLABELLED_PV)) { ++ if (!_check_vg_name(pv->vg_name)) ++ return_0; ++ strncpy((char *)pvd->vg_name, pv->vg_name, sizeof(pvd->vg_name)); ++ } ++ ++ /* Preserve existing system_id if it exists */ ++ if (vg && vg->lvm1_system_id && *vg->lvm1_system_id) ++ strncpy((char *)pvd->system_id, vg->lvm1_system_id, sizeof(pvd->system_id)); ++ else if (vg && vg->system_id && *vg->system_id) ++ strncpy((char *)pvd->system_id, vg->system_id, sizeof(pvd->system_id)); ++ ++ /* Is VG already exported or being exported? */ ++ if (vg && vg_is_exported(vg)) { ++ /* Does system_id need setting? */ ++ if (!vg->lvm1_system_id || !*vg->lvm1_system_id || ++ strncmp(vg->lvm1_system_id, EXPORTED_TAG, ++ sizeof(EXPORTED_TAG) - 1)) { ++ if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, EXPORTED_TAG)) ++ return_0; ++ } ++ if (strlen((char *)pvd->vg_name) + sizeof(EXPORTED_TAG) > ++ sizeof(pvd->vg_name)) { ++ log_error("Volume group name %s too long to export", ++ pvd->vg_name); ++ return 0; ++ } ++ strcat((char *)pvd->vg_name, EXPORTED_TAG); ++ } ++ ++ /* Is VG being imported? */ ++ if (vg && !vg_is_exported(vg) && vg->lvm1_system_id && *vg->lvm1_system_id && ++ !strncmp(vg->lvm1_system_id, EXPORTED_TAG, sizeof(EXPORTED_TAG) - 1)) { ++ if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, IMPORTED_TAG)) ++ return_0; ++ } ++ ++ /* Generate system_id if PV is in VG */ ++ if (!pvd->system_id[0]) ++ if (!generate_lvm1_system_id(cmd, (char *)pvd->system_id, "")) ++ return_0; ++ ++ /* Update internal system_id if we changed it */ ++ if (vg && vg->lvm1_system_id && ++ (!*vg->lvm1_system_id || ++ strncmp(vg->lvm1_system_id, (char *)pvd->system_id, sizeof(pvd->system_id)))) ++ strncpy(vg->lvm1_system_id, (char *)pvd->system_id, NAME_LEN); ++ ++ //pvd->pv_major = MAJOR(pv->dev); ++ ++ if (pv->status & ALLOCATABLE_PV) ++ pvd->pv_allocatable = PV_ALLOCATABLE; ++ ++ pvd->pv_size = pv->size; ++ pvd->lv_cur = 0; /* this is set when exporting the lv list */ ++ if (vg) ++ pvd->pe_size = vg->extent_size; ++ else ++ pvd->pe_size = pv->pe_size; ++ pvd->pe_total = pv->pe_count; ++ pvd->pe_allocated = pv->pe_alloc_count; ++ pvd->pe_start = pv->pe_start; ++ ++ return 1; ++} ++ ++int import_vg(struct dm_pool *mem, ++ struct volume_group *vg, struct disk_list *dl) ++{ ++ struct vg_disk *vgd = &dl->vgd; ++ memcpy(vg->id.uuid, vgd->vg_uuid, ID_LEN); ++ ++ if (!_check_vg_name((char *)dl->pvd.vg_name)) ++ return_0; ++ ++ if (!(vg->name = dm_pool_strdup(mem, (char *)dl->pvd.vg_name))) ++ return_0; ++ ++ if (!(vg->lvm1_system_id = dm_pool_zalloc(mem, NAME_LEN + 1))) ++ return_0; ++ ++ if (vgd->vg_status & VG_EXPORTED) ++ vg->status |= EXPORTED_VG; ++ ++ if (vgd->vg_status & VG_EXTENDABLE) ++ vg->status |= RESIZEABLE_VG; ++ ++ if (vgd->vg_access & VG_READ) ++ vg->status |= LVM_READ; ++ ++ if (vgd->vg_access & VG_WRITE) ++ vg->status |= LVM_WRITE; ++ ++ if (vgd->vg_access & VG_CLUSTERED) ++ vg->status |= CLUSTERED; ++ ++ if (vgd->vg_access & VG_SHARED) ++ vg->status |= SHARED; ++ ++ vg->extent_size = vgd->pe_size; ++ vg->extent_count = vgd->pe_total; ++ vg->free_count = vgd->pe_total; ++ vg->max_lv = vgd->lv_max; ++ vg->max_pv = vgd->pv_max; ++ vg->alloc = ALLOC_NORMAL; ++ ++ return 1; ++} ++ ++int export_vg(struct vg_disk *vgd, struct volume_group *vg) ++{ ++ memset(vgd, 0, sizeof(*vgd)); ++ memcpy(vgd->vg_uuid, vg->id.uuid, ID_LEN); ++ ++ if (vg->status & LVM_READ) ++ vgd->vg_access |= VG_READ; ++ ++ if (vg->status & LVM_WRITE) ++ vgd->vg_access |= VG_WRITE; ++ ++ if (vg_is_clustered(vg)) ++ vgd->vg_access |= VG_CLUSTERED; ++ ++ if (vg->status & SHARED) ++ vgd->vg_access |= VG_SHARED; ++ ++ if (vg_is_exported(vg)) ++ vgd->vg_status |= VG_EXPORTED; ++ ++ if (vg_is_resizeable(vg)) ++ vgd->vg_status |= VG_EXTENDABLE; ++ ++ vgd->lv_max = vg->max_lv; ++ vgd->lv_cur = vg_visible_lvs(vg) + snapshot_count(vg); ++ ++ vgd->pv_max = vg->max_pv; ++ vgd->pv_cur = vg->pv_count; ++ ++ vgd->pe_size = vg->extent_size; ++ vgd->pe_total = vg->extent_count; ++ vgd->pe_allocated = vg->extent_count - vg->free_count; ++ ++ return 1; ++} ++ ++int import_lv(struct cmd_context *cmd, struct dm_pool *mem, ++ struct logical_volume *lv, struct lv_disk *lvd) ++{ ++ if (!(lv->name = _create_lv_name(mem, (char *)lvd->lv_name))) ++ return_0; ++ ++ lv->status |= VISIBLE_LV; ++ ++ if (lvd->lv_status & LV_SPINDOWN) ++ lv->status |= SPINDOWN_LV; ++ ++ if (lvd->lv_status & LV_PERSISTENT_MINOR) { ++ lv->status |= FIXED_MINOR; ++ lv->minor = MINOR(lvd->lv_dev); ++ lv->major = MAJOR(lvd->lv_dev); ++ } else { ++ lv->major = -1; ++ lv->minor = -1; ++ } ++ ++ if (lvd->lv_access & LV_READ) ++ lv->status |= LVM_READ; ++ ++ if (lvd->lv_access & LV_WRITE) ++ lv->status |= LVM_WRITE; ++ ++ if (lvd->lv_badblock) ++ lv->status |= BADBLOCK_ON; ++ ++ /* Drop the unused LV_STRICT here */ ++ if (lvd->lv_allocation & LV_CONTIGUOUS) ++ lv->alloc = ALLOC_CONTIGUOUS; ++ else ++ lv->alloc = ALLOC_NORMAL; ++ ++ if (!lvd->lv_read_ahead) ++ lv->read_ahead = cmd->default_settings.read_ahead; ++ else ++ lv->read_ahead = lvd->lv_read_ahead; ++ ++ lv->size = lvd->lv_size; ++ lv->le_count = lvd->lv_allocated_le; ++ ++ return 1; ++} ++ ++static void _export_lv(struct lv_disk *lvd, struct volume_group *vg, ++ struct logical_volume *lv, const char *dev_dir) ++{ ++ memset(lvd, 0, sizeof(*lvd)); ++ snprintf((char *)lvd->lv_name, sizeof(lvd->lv_name), "%s%s/%s", ++ dev_dir, vg->name, lv->name); ++ ++ (void) dm_strncpy((char *)lvd->vg_name, vg->name, sizeof(lvd->vg_name)); ++ ++ if (lv->status & LVM_READ) ++ lvd->lv_access |= LV_READ; ++ ++ if (lv->status & LVM_WRITE) ++ lvd->lv_access |= LV_WRITE; ++ ++ if (lv->status & SPINDOWN_LV) ++ lvd->lv_status |= LV_SPINDOWN; ++ ++ if (lv->status & FIXED_MINOR) { ++ lvd->lv_status |= LV_PERSISTENT_MINOR; ++ lvd->lv_dev = MKDEV(lv->major, lv->minor); ++ } else { ++ lvd->lv_dev = MKDEV(LVM_BLK_MAJOR, lvnum_from_lvid(&lv->lvid)); ++ } ++ ++ if (lv->read_ahead == DM_READ_AHEAD_AUTO || ++ lv->read_ahead == DM_READ_AHEAD_NONE) ++ lvd->lv_read_ahead = 0; ++ else ++ lvd->lv_read_ahead = lv->read_ahead; ++ ++ lvd->lv_stripes = ++ dm_list_item(lv->segments.n, struct lv_segment)->area_count; ++ lvd->lv_stripesize = ++ dm_list_item(lv->segments.n, struct lv_segment)->stripe_size; ++ ++ lvd->lv_size = lv->size; ++ lvd->lv_allocated_le = lv->le_count; ++ ++ if (lv->status & BADBLOCK_ON) ++ lvd->lv_badblock = LV_BADBLOCK_ON; ++ ++ if (lv->alloc == ALLOC_CONTIGUOUS) ++ lvd->lv_allocation |= LV_CONTIGUOUS; ++} ++ ++int export_extents(struct disk_list *dl, uint32_t lv_num, ++ struct logical_volume *lv, struct physical_volume *pv) ++{ ++ struct pe_disk *ped; ++ struct lv_segment *seg; ++ uint32_t pe, s; ++ ++ dm_list_iterate_items(seg, &lv->segments) { ++ for (s = 0; s < seg->area_count; s++) { ++ if (!(seg->segtype->flags & SEG_FORMAT1_SUPPORT)) { ++ log_error("Segment type %s in LV %s: " ++ "unsupported by format1", ++ lvseg_name(seg), lv->name); ++ return 0; ++ } ++ if (seg_type(seg, s) != AREA_PV) { ++ log_error("Non-PV stripe found in LV %s: " ++ "unsupported by format1", lv->name); ++ return 0; ++ } ++ if (seg_pv(seg, s) != pv) ++ continue; /* not our pv */ ++ ++ for (pe = 0; pe < (seg->len / seg->area_count); pe++) { ++ ped = &dl->extents[pe + seg_pe(seg, s)]; ++ ped->lv_num = lv_num; ++ ped->le_num = (seg->le / seg->area_count) + pe + ++ s * (lv->le_count / seg->area_count); ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++int import_pvs(const struct format_type *fmt, struct dm_pool *mem, ++ struct volume_group *vg, struct dm_list *pvds) ++{ ++ struct disk_list *dl; ++ struct pv_list *pvl; ++ ++ vg->pv_count = 0; ++ dm_list_iterate_items(dl, pvds) { ++ if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) || ++ !(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) ++ return_0; ++ ++ if (!import_pv(fmt, mem, dl->dev, vg, pvl->pv, &dl->pvd, &dl->vgd)) ++ return_0; ++ ++ pvl->pv->fmt = fmt; ++ add_pvl_to_vgs(vg, pvl); ++ } ++ ++ return 1; ++} ++ ++static struct logical_volume *_add_lv(struct dm_pool *mem, ++ struct volume_group *vg, ++ struct lv_disk *lvd) ++{ ++ struct logical_volume *lv; ++ ++ if (!(lv = alloc_lv(mem))) ++ return_NULL; ++ ++ lvid_from_lvnum(&lv->lvid, &vg->id, lvd->lv_number); ++ ++ if (!import_lv(vg->cmd, mem, lv, lvd)) ++ goto_bad; ++ ++ if (!link_lv_to_vg(vg, lv)) ++ goto_bad; ++ ++ return lv; ++bad: ++ dm_pool_free(mem, lv); ++ return NULL; ++} ++ ++int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct dm_list *pvds) ++{ ++ struct disk_list *dl; ++ struct lvd_list *ll; ++ struct lv_disk *lvd; ++ ++ dm_list_iterate_items(dl, pvds) { ++ dm_list_iterate_items(ll, &dl->lvds) { ++ lvd = &ll->lvd; ++ ++ if (!find_lv(vg, (char *)lvd->lv_name) && ++ !_add_lv(mem, vg, lvd)) ++ return_0; ++ } ++ } ++ ++ return 1; ++} ++ ++/* FIXME: tidy */ ++int export_lvs(struct disk_list *dl, struct volume_group *vg, ++ struct physical_volume *pv, const char *dev_dir) ++{ ++ int r = 0; ++ struct lv_list *ll; ++ struct lvd_list *lvdl; ++ size_t len; ++ uint32_t lv_num; ++ struct dm_hash_table *lvd_hash; ++ ++ if (!_check_vg_name(vg->name)) ++ return_0; ++ ++ if (!(lvd_hash = dm_hash_create(32))) ++ return_0; ++ ++ /* ++ * setup the pv's extents array ++ */ ++ len = sizeof(struct pe_disk) * dl->pvd.pe_total; ++ if (!(dl->extents = dm_pool_zalloc(dl->mem, len))) ++ goto_out; ++ ++ dm_list_iterate_items(ll, &vg->lvs) { ++ if (lv_is_snapshot(ll->lv)) ++ continue; ++ ++ if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) ++ goto_out; ++ ++ _export_lv(&lvdl->lvd, vg, ll->lv, dev_dir); ++ ++ lv_num = lvnum_from_lvid(&ll->lv->lvid); ++ lvdl->lvd.lv_number = lv_num; ++ ++ if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) ++ goto_out; ++ ++ if (!export_extents(dl, lv_num + 1, ll->lv, pv)) ++ goto_out; ++ ++ if (lv_is_origin(ll->lv)) ++ lvdl->lvd.lv_access |= LV_SNAPSHOT_ORG; ++ ++ if (lv_is_cow(ll->lv)) { ++ lvdl->lvd.lv_access |= LV_SNAPSHOT; ++ lvdl->lvd.lv_chunk_size = ll->lv->snapshot->chunk_size; ++ lvdl->lvd.lv_snapshot_minor = ++ lvnum_from_lvid(&ll->lv->snapshot->origin->lvid); ++ } ++ ++ dm_list_add(&dl->lvds, &lvdl->list); ++ dl->pvd.lv_cur++; ++ } ++ ++ r = 1; ++ ++ out: ++ dm_hash_destroy(lvd_hash); ++ return r; ++} ++ ++/* ++ * FIXME: More inefficient code. ++ */ ++int import_snapshots(struct dm_pool *mem __attribute__((unused)), struct volume_group *vg, ++ struct dm_list *pvds) ++{ ++ struct logical_volume *lvs[MAX_LV] = { 0 }; ++ struct disk_list *dl; ++ struct lvd_list *ll; ++ struct lv_disk *lvd; ++ int lvnum; ++ struct logical_volume *org, *cow; ++ ++ /* build an index of lv numbers */ ++ dm_list_iterate_items(dl, pvds) { ++ dm_list_iterate_items(ll, &dl->lvds) { ++ lvd = &ll->lvd; ++ ++ lvnum = lvd->lv_number; ++ ++ if (lvnum >= MAX_LV) { ++ log_error("Logical volume number " ++ "out of bounds."); ++ return 0; ++ } ++ ++ if (!lvs[lvnum] && ++ !(lvs[lvnum] = find_lv(vg, (char *)lvd->lv_name))) { ++ log_error("Couldn't find logical volume '%s'.", ++ lvd->lv_name); ++ return 0; ++ } ++ } ++ } ++ ++ /* ++ * Now iterate through yet again adding the snapshots. ++ */ ++ dm_list_iterate_items(dl, pvds) { ++ dm_list_iterate_items(ll, &dl->lvds) { ++ lvd = &ll->lvd; ++ ++ if (!(lvd->lv_access & LV_SNAPSHOT)) ++ continue; ++ ++ lvnum = lvd->lv_number; ++ cow = lvs[lvnum]; ++ if (!(org = lvs[lvd->lv_snapshot_minor])) { ++ log_error("Couldn't find origin logical volume " ++ "for snapshot '%s'.", lvd->lv_name); ++ return 0; ++ } ++ ++ /* we may have already added this snapshot */ ++ if (lv_is_cow(cow)) ++ continue; ++ ++ /* insert the snapshot */ ++ if (!vg_add_snapshot(org, cow, NULL, ++ org->le_count, ++ lvd->lv_chunk_size)) { ++ log_error("Couldn't add snapshot."); ++ return 0; ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++int export_uuids(struct disk_list *dl, struct volume_group *vg) ++{ ++ struct uuid_list *ul; ++ struct pv_list *pvl; ++ ++ dm_list_iterate_items(pvl, &vg->pvs) { ++ if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) ++ return_0; ++ ++ memset(ul->uuid, 0, sizeof(ul->uuid)); ++ memcpy(ul->uuid, pvl->pv->id.uuid, ID_LEN); ++ ++ dm_list_add(&dl->uuids, &ul->list); ++ } ++ return 1; ++} ++ ++/* ++ * This calculates the nasty pv_number field ++ * used by LVM1. ++ */ ++void export_numbers(struct dm_list *pvds, struct volume_group *vg __attribute__((unused))) ++{ ++ struct disk_list *dl; ++ int pv_num = 1; ++ ++ dm_list_iterate_items(dl, pvds) ++ dl->pvd.pv_number = pv_num++; ++} ++ ++/* ++ * Calculate vg_disk->pv_act. ++ */ ++void export_pv_act(struct dm_list *pvds) ++{ ++ struct disk_list *dl; ++ int act = 0; ++ ++ dm_list_iterate_items(dl, pvds) ++ if (dl->pvd.pv_status & PV_ACTIVE) ++ act++; ++ ++ dm_list_iterate_items(dl, pvds) ++ dl->vgd.pv_act = act; ++} ++ ++int export_vg_number(struct format_instance *fid, struct dm_list *pvds, ++ const char *vg_name, struct dev_filter *filter) ++{ ++ struct disk_list *dl; ++ int vg_num; ++ ++ if (!get_free_vg_number(fid, filter, vg_name, &vg_num)) ++ return_0; ++ ++ dm_list_iterate_items(dl, pvds) ++ dl->vgd.vg_number = vg_num; ++ ++ return 1; ++} +diff --git a/lib/format1/import-extents.c b/lib/format1/import-extents.c +new file mode 100644 +index 0000000..c583741 +--- /dev/null ++++ b/lib/format1/import-extents.c +@@ -0,0 +1,377 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "metadata.h" ++#include "disk-rep.h" ++#include "lv_alloc.h" ++#include "display.h" ++#include "segtype.h" ++ ++/* ++ * After much thought I have decided it is easier, ++ * and probably no less efficient, to convert the ++ * pe->le map to a full le->pe map, and then ++ * process this to get the segments form that ++ * we're after. Any code which goes directly from ++ * the pe->le map to segments would be gladly ++ * accepted, if it is less complicated than this ++ * file. ++ */ ++struct pe_specifier { ++ struct physical_volume *pv; ++ uint32_t pe; ++}; ++ ++struct lv_map { ++ struct logical_volume *lv; ++ uint32_t stripes; ++ uint32_t stripe_size; ++ struct pe_specifier *map; ++}; ++ ++static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem, ++ struct volume_group *vg) ++{ ++ struct dm_hash_table *maps = dm_hash_create(32); ++ struct lv_list *ll; ++ struct lv_map *lvm; ++ ++ if (!maps) { ++ log_error("Unable to create hash table for holding " ++ "extent maps."); ++ return NULL; ++ } ++ ++ dm_list_iterate_items(ll, &vg->lvs) { ++ if (lv_is_snapshot(ll->lv)) ++ continue; ++ ++ if (!(lvm = dm_pool_alloc(mem, sizeof(*lvm)))) ++ goto_bad; ++ ++ lvm->lv = ll->lv; ++ /* ++ * Alloc 1 extra element, so the loop in _area_length() and ++ * _check_stripe() finds the last map member as noncontinuous. ++ */ ++ if (!(lvm->map = dm_pool_zalloc(mem, sizeof(*lvm->map) ++ * (ll->lv->le_count + 1)))) ++ goto_bad; ++ ++ if (!dm_hash_insert(maps, ll->lv->name, lvm)) ++ goto_bad; ++ } ++ ++ return maps; ++ ++ bad: ++ dm_hash_destroy(maps); ++ return NULL; ++} ++ ++static int _fill_lv_array(struct lv_map **lvs, ++ struct dm_hash_table *maps, struct disk_list *dl) ++{ ++ struct lvd_list *ll; ++ struct lv_map *lvm; ++ ++ memset(lvs, 0, sizeof(*lvs) * MAX_LV); ++ ++ dm_list_iterate_items(ll, &dl->lvds) { ++ if (!(lvm = dm_hash_lookup(maps, strrchr((char *)ll->lvd.lv_name, '/') ++ + 1))) { ++ log_error("Physical volume (%s) contains an " ++ "unknown logical volume (%s).", ++ dev_name(dl->dev), ll->lvd.lv_name); ++ return 0; ++ } ++ ++ lvm->stripes = ll->lvd.lv_stripes; ++ lvm->stripe_size = ll->lvd.lv_stripesize; ++ ++ lvs[ll->lvd.lv_number] = lvm; ++ } ++ ++ return 1; ++} ++ ++static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg, ++ struct dm_list *pvds) ++{ ++ struct disk_list *dl; ++ struct physical_volume *pv; ++ struct lv_map *lvms[MAX_LV], *lvm; ++ struct pe_disk *e; ++ uint32_t i, lv_num, le; ++ ++ dm_list_iterate_items(dl, pvds) { ++ if (!(pv = find_pv(vg, dl->dev))) { ++ log_error("PV %s not found.", dl->dev->pvid); ++ return 0; ++ } ++ e = dl->extents; ++ ++ /* build an array of lv's for this pv */ ++ if (!_fill_lv_array(lvms, maps, dl)) ++ return_0; ++ ++ for (i = 0; i < dl->pvd.pe_total; i++) { ++ lv_num = e[i].lv_num; ++ ++ if (lv_num == UNMAPPED_EXTENT) ++ continue; ++ ++ lv_num--; ++ lvm = lvms[lv_num]; ++ ++ if (!lvm) { ++ log_error("Invalid LV in extent map " ++ "(PV %s, PE %" PRIu32 ++ ", LV %" PRIu32 ++ ", LE %" PRIu32 ")", ++ dev_name(pv->dev), i, ++ lv_num, e[i].le_num); ++ return 0; ++ } ++ ++ le = e[i].le_num; ++ ++ if (le >= lvm->lv->le_count) { ++ log_error("logical extent number " ++ "out of bounds"); ++ return 0; ++ } ++ ++ if (lvm->map[le].pv) { ++ log_error("logical extent (%u) " ++ "already mapped.", le); ++ return 0; ++ } ++ ++ lvm->map[le].pv = pv; ++ lvm->map[le].pe = i; ++ } ++ } ++ ++ return 1; ++} ++ ++static int _check_single_map(struct lv_map *lvm) ++{ ++ uint32_t i; ++ ++ for (i = 0; i < lvm->lv->le_count; i++) { ++ if (!lvm->map[i].pv) { ++ log_error("Logical volume (%s) contains an incomplete " ++ "mapping table.", lvm->lv->name); ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++static int _check_maps_are_complete(struct dm_hash_table *maps) ++{ ++ struct dm_hash_node *n; ++ struct lv_map *lvm; ++ ++ for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) { ++ lvm = (struct lv_map *) dm_hash_get_data(maps, n); ++ ++ if (!_check_single_map(lvm)) ++ return_0; ++ } ++ return 1; ++} ++ ++static uint32_t _area_length(struct lv_map *lvm, uint32_t le) ++{ ++ uint32_t len = 0; ++ ++ do ++ len++; ++ while ((lvm->map[le + len].pv == lvm->map[le].pv) && ++ (lvm->map[le].pv && ++ lvm->map[le + len].pe == lvm->map[le].pe + len)); ++ ++ return len; ++} ++ ++static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm) ++{ ++ uint32_t le = 0, len; ++ struct lv_segment *seg; ++ struct segment_type *segtype; ++ ++ if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED))) ++ return_0; ++ ++ while (le < lvm->lv->le_count) { ++ len = _area_length(lvm, le); ++ ++ if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0, 0, ++ NULL, 1, len, 0, 0, 0, 0, NULL))) { ++ log_error("Failed to allocate linear segment."); ++ return 0; ++ } ++ ++ if (!set_lv_segment_area_pv(seg, 0, lvm->map[le].pv, ++ lvm->map[le].pe)) ++ return_0; ++ ++ dm_list_add(&lvm->lv->segments, &seg->list); ++ ++ le += seg->len; ++ } ++ ++ return 1; ++} ++ ++static int _check_stripe(struct lv_map *lvm, uint32_t area_count, ++ uint32_t area_len, uint32_t base_le, ++ uint32_t total_area_len) ++{ ++ uint32_t st; ++ ++ /* ++ * Is the next physical extent in every stripe adjacent to the last? ++ */ ++ for (st = 0; st < area_count; st++) ++ if ((lvm->map[base_le + st * total_area_len + area_len].pv != ++ lvm->map[base_le + st * total_area_len].pv) || ++ (lvm->map[base_le + st * total_area_len].pv && ++ lvm->map[base_le + st * total_area_len + area_len].pe != ++ lvm->map[base_le + st * total_area_len].pe + area_len)) ++ return 0; ++ ++ return 1; ++} ++ ++static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm) ++{ ++ uint32_t st, first_area_le = 0, total_area_len; ++ uint32_t area_len; ++ struct lv_segment *seg; ++ struct segment_type *segtype; ++ ++ /* ++ * Work out overall striped length ++ */ ++ if (lvm->lv->le_count % lvm->stripes) { ++ log_error("Number of stripes (%u) incompatible " ++ "with logical extent count (%u) for %s", ++ lvm->stripes, lvm->lv->le_count, lvm->lv->name); ++ } ++ ++ total_area_len = lvm->lv->le_count / lvm->stripes; ++ ++ if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED))) ++ return_0; ++ ++ while (first_area_le < total_area_len) { ++ area_len = 1; ++ ++ /* ++ * Find how many extents are contiguous in all stripes ++ * and so can form part of this segment ++ */ ++ while (_check_stripe(lvm, lvm->stripes, ++ area_len, first_area_le, total_area_len)) ++ area_len++; ++ ++ if (!(seg = alloc_lv_segment(segtype, lvm->lv, ++ lvm->stripes * first_area_le, ++ lvm->stripes * area_len, 0, ++ 0, lvm->stripe_size, NULL, ++ lvm->stripes, ++ area_len, 0, 0, 0, 0, NULL))) { ++ log_error("Failed to allocate striped segment."); ++ return 0; ++ } ++ ++ /* ++ * Set up start positions of each stripe in this segment ++ */ ++ for (st = 0; st < seg->area_count; st++) ++ if (!set_lv_segment_area_pv(seg, st, ++ lvm->map[first_area_le + st * total_area_len].pv, ++ lvm->map[first_area_le + st * total_area_len].pe)) ++ return_0; ++ ++ dm_list_add(&lvm->lv->segments, &seg->list); ++ ++ first_area_le += area_len; ++ } ++ ++ return 1; ++} ++ ++static int _build_segments(struct cmd_context *cmd, struct lv_map *lvm) ++{ ++ return (lvm->stripes > 1 ? _read_stripes(cmd, lvm) : ++ _read_linear(cmd, lvm)); ++} ++ ++static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *maps) ++{ ++ struct dm_hash_node *n; ++ struct lv_map *lvm; ++ ++ for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) { ++ lvm = (struct lv_map *) dm_hash_get_data(maps, n); ++ if (!_build_segments(cmd, lvm)) ++ return_0; ++ } ++ ++ return 1; ++} ++ ++int import_extents(struct cmd_context *cmd, struct volume_group *vg, ++ struct dm_list *pvds) ++{ ++ int r = 0; ++ struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024); ++ struct dm_hash_table *maps; ++ ++ if (!scratch) ++ return_0; ++ ++ if (!(maps = _create_lv_maps(scratch, vg))) { ++ log_error("Couldn't allocate logical volume maps."); ++ goto out; ++ } ++ ++ if (!_fill_maps(maps, vg, pvds)) { ++ log_error("Couldn't fill logical volume maps."); ++ goto out; ++ } ++ ++ if (!_check_maps_are_complete(maps) && !(vg->status & PARTIAL_VG)) ++ goto_out; ++ ++ if (!_build_all_segments(cmd, maps)) { ++ log_error("Couldn't build extent segments."); ++ goto out; ++ } ++ r = 1; ++ ++ out: ++ if (maps) ++ dm_hash_destroy(maps); ++ dm_pool_destroy(scratch); ++ return r; ++} +diff --git a/lib/format1/layout.c b/lib/format1/layout.c +new file mode 100644 +index 0000000..380a983 +--- /dev/null ++++ b/lib/format1/layout.c +@@ -0,0 +1,172 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "disk-rep.h" ++ ++/* ++ * Only works with powers of 2. ++ */ ++static uint32_t _round_up(uint32_t n, uint32_t size) ++{ ++ size--; ++ return (n + size) & ~size; ++} ++ ++/* Unused. ++static uint32_t _div_up(uint32_t n, uint32_t size) ++{ ++ return _round_up(n, size) / size; ++} ++*/ ++ ++/* ++ * Each chunk of metadata should be aligned to ++ * METADATA_ALIGN. ++ */ ++static uint32_t _next_base(struct data_area *area) ++{ ++ return _round_up(area->base + area->size, METADATA_ALIGN); ++} ++ ++/* ++ * Quick calculation based on pe_start. ++ */ ++static int _adjust_pe_on_disk(struct pv_disk *pvd) ++{ ++ uint32_t pe_start = pvd->pe_start << SECTOR_SHIFT; ++ ++ if (pe_start < pvd->pe_on_disk.base + pvd->pe_on_disk.size) ++ return 0; ++ ++ pvd->pe_on_disk.size = pe_start - pvd->pe_on_disk.base; ++ return 1; ++} ++ ++static void _calc_simple_layout(struct pv_disk *pvd) ++{ ++ pvd->pv_on_disk.base = METADATA_BASE; ++ pvd->pv_on_disk.size = PV_SIZE; ++ ++ pvd->vg_on_disk.base = _next_base(&pvd->pv_on_disk); ++ pvd->vg_on_disk.size = VG_SIZE; ++ ++ pvd->pv_uuidlist_on_disk.base = _next_base(&pvd->vg_on_disk); ++ pvd->pv_uuidlist_on_disk.size = MAX_PV * NAME_LEN; ++ ++ pvd->lv_on_disk.base = _next_base(&pvd->pv_uuidlist_on_disk); ++ pvd->lv_on_disk.size = MAX_LV * sizeof(struct lv_disk); ++ ++ pvd->pe_on_disk.base = _next_base(&pvd->lv_on_disk); ++ pvd->pe_on_disk.size = pvd->pe_total * sizeof(struct pe_disk); ++} ++ ++static int _check_vg_limits(struct disk_list *dl) ++{ ++ if (dl->vgd.lv_max > MAX_LV) { ++ log_error("MaxLogicalVolumes of %d exceeds format limit of %d " ++ "for VG '%s'", dl->vgd.lv_max, MAX_LV - 1, ++ dl->pvd.vg_name); ++ return 0; ++ } ++ ++ if (dl->vgd.pv_max > MAX_PV) { ++ log_error("MaxPhysicalVolumes of %d exceeds format limit of %d " ++ "for VG '%s'", dl->vgd.pv_max, MAX_PV - 1, ++ dl->pvd.vg_name); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* ++ * This assumes pe_count and pe_start have already ++ * been calculated correctly. ++ */ ++int calculate_layout(struct disk_list *dl) ++{ ++ struct pv_disk *pvd = &dl->pvd; ++ ++ _calc_simple_layout(pvd); ++ if (!_adjust_pe_on_disk(pvd)) { ++ log_error("Insufficient space for metadata and PE's."); ++ return 0; ++ } ++ ++ if (!_check_vg_limits(dl)) ++ return 0; ++ ++ return 1; ++} ++ ++/* ++ * The number of extents that can fit on a disk is metadata format dependant. ++ * pe_start is any existing value for pe_start ++ */ ++int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size, ++ uint32_t max_extent_count, uint64_t pe_start) ++{ ++ struct pv_disk *pvd = dm_malloc(sizeof(*pvd)); ++ uint32_t end; ++ ++ if (!pvd) ++ return_0; ++ ++ /* ++ * Guess how many extents will fit, bearing in mind that ++ * one is going to be knocked off at the start of the ++ * next loop. ++ */ ++ if (max_extent_count) ++ pvd->pe_total = max_extent_count + 1; ++ else ++ pvd->pe_total = (pv->size / extent_size); ++ ++ if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) { ++ log_error("Too few extents on %s. Try smaller extent size.", ++ pv_dev_name(pv)); ++ dm_free(pvd); ++ return 0; ++ } ++ ++ do { ++ pvd->pe_total--; ++ _calc_simple_layout(pvd); ++ end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size + ++ SECTOR_SIZE - 1) >> SECTOR_SHIFT); ++ ++ if (pe_start && end < pe_start) ++ end = pe_start; ++ ++ pvd->pe_start = _round_up(end, LVM1_PE_ALIGN); ++ ++ } while ((pvd->pe_start + ((uint64_t)pvd->pe_total * extent_size)) ++ > pv->size); ++ ++ if (pvd->pe_total > MAX_PE_TOTAL) { ++ log_error("Metadata extent limit (%u) exceeded for %s - " ++ "%u required", MAX_PE_TOTAL, pv_dev_name(pv), ++ pvd->pe_total); ++ dm_free(pvd); ++ return 0; ++ } ++ ++ pv->pe_count = pvd->pe_total; ++ pv->pe_start = pvd->pe_start; ++ /* We can't set pe_size here without breaking LVM1 compatibility */ ++ dm_free(pvd); ++ return 1; ++} +diff --git a/lib/format1/lvm1-label.c b/lib/format1/lvm1-label.c +new file mode 100644 +index 0000000..691a05a +--- /dev/null ++++ b/lib/format1/lvm1-label.c +@@ -0,0 +1,129 @@ ++/* ++ * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "lvm1-label.h" ++#include "disk-rep.h" ++#include "label.h" ++#include "metadata.h" ++#include "xlate.h" ++#include "format1.h" ++ ++#include ++#include ++ ++static void _not_supported(const char *op) ++{ ++ log_error("The '%s' operation is not supported for the lvm1 labeller.", ++ op); ++} ++ ++static int _lvm1_can_handle(struct labeller *l __attribute__((unused)), void *buf, uint64_t sector) ++{ ++ struct pv_disk *pvd = (struct pv_disk *) buf; ++ uint32_t version; ++ ++ /* LVM1 label must always be in first sector */ ++ if (sector) ++ return 0; ++ ++ version = xlate16(pvd->version); ++ ++ if (pvd->id[0] == 'H' && pvd->id[1] == 'M' && ++ (version == 1 || version == 2)) ++ return 1; ++ ++ return 0; ++} ++ ++static int _lvm1_write(struct label *label __attribute__((unused)), void *buf __attribute__((unused))) ++{ ++ _not_supported("write"); ++ return 0; ++} ++ ++static int _lvm1_read(struct labeller *l, struct device *dev, void *buf, ++ struct label **label) ++{ ++ struct pv_disk *pvd = (struct pv_disk *) buf; ++ struct vg_disk vgd; ++ struct lvmcache_info *info; ++ const char *vgid = FMT_LVM1_ORPHAN_VG_NAME; ++ const char *vgname = FMT_LVM1_ORPHAN_VG_NAME; ++ unsigned exported = 0; ++ ++ munge_pvd(dev, pvd); ++ ++ if (*pvd->vg_name) { ++ if (!read_vgd(dev, &vgd, pvd)) ++ return_0; ++ vgid = (char *) vgd.vg_uuid; ++ vgname = (char *) pvd->vg_name; ++ exported = pvd->pv_status & VG_EXPORTED; ++ } ++ ++ if (!(info = lvmcache_add(l, (char *)pvd->pv_uuid, dev, vgname, vgid, ++ exported))) ++ return_0; ++ *label = lvmcache_get_label(info); ++ ++ lvmcache_set_device_size(info, ((uint64_t)xlate32(pvd->pv_size)) << SECTOR_SHIFT); ++ lvmcache_set_ext_version(info, 0); ++ lvmcache_set_ext_flags(info, 0); ++ lvmcache_del_mdas(info); ++ lvmcache_del_bas(info); ++ ++ return 1; ++} ++ ++static int _lvm1_initialise_label(struct labeller *l __attribute__((unused)), struct label *label) ++{ ++ strcpy(label->type, "LVM1"); ++ ++ return 1; ++} ++ ++static void _lvm1_destroy_label(struct labeller *l __attribute__((unused)), struct label *label __attribute__((unused))) ++{ ++} ++ ++static void _lvm1_destroy(struct labeller *l) ++{ ++ dm_free(l); ++} ++ ++struct label_ops _lvm1_ops = { ++ .can_handle = _lvm1_can_handle, ++ .write = _lvm1_write, ++ .read = _lvm1_read, ++ .initialise_label = _lvm1_initialise_label, ++ .destroy_label = _lvm1_destroy_label, ++ .destroy = _lvm1_destroy, ++}; ++ ++struct labeller *lvm1_labeller_create(struct format_type *fmt) ++{ ++ struct labeller *l; ++ ++ if (!(l = dm_malloc(sizeof(*l)))) { ++ log_error("Couldn't allocate labeller object."); ++ return NULL; ++ } ++ ++ l->ops = &_lvm1_ops; ++ l->fmt = fmt; ++ ++ return l; ++} +diff --git a/lib/format1/lvm1-label.h b/lib/format1/lvm1-label.h +new file mode 100644 +index 0000000..27f2f51 +--- /dev/null ++++ b/lib/format1/lvm1-label.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _LVM_LVM1_LABEL_H ++#define _LVM_LVM1_LABEL_H ++ ++#include "metadata.h" ++ ++struct labeller *lvm1_labeller_create(struct format_type *fmt); ++ ++#endif +diff --git a/lib/format1/vg_number.c b/lib/format1/vg_number.c +new file mode 100644 +index 0000000..8b1a803 +--- /dev/null ++++ b/lib/format1/vg_number.c +@@ -0,0 +1,60 @@ ++/* ++ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "disk-rep.h" ++ ++/* ++ * FIXME: Quick hack. We can use caching to ++ * prevent a total re-read, even so vg_number ++ * causes the tools to check *every* pv. Yuck. ++ * Put in separate file so it wouldn't contaminate ++ * other code. ++ */ ++int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter, ++ const char *candidate_vg, int *result) ++{ ++ struct dm_list all_pvs; ++ struct disk_list *dl; ++ struct dm_pool *mem = dm_pool_create("lvm1 vg_number", 10 * 1024); ++ int i, r = 0, numbers[MAX_VG] = { 0 }; ++ ++ dm_list_init(&all_pvs); ++ ++ if (!mem) ++ return_0; ++ ++ if (!read_pvs_in_vg(fid->fmt, NULL, filter, mem, &all_pvs)) ++ goto_out; ++ ++ dm_list_iterate_items(dl, &all_pvs) { ++ if (!*dl->pvd.vg_name || !strcmp((char *)dl->pvd.vg_name, candidate_vg)) ++ continue; ++ ++ numbers[dl->vgd.vg_number] = 1; ++ } ++ ++ for (i = 0; i < MAX_VG; i++) { ++ if (!numbers[i]) { ++ r = 1; ++ *result = i; ++ break; ++ } ++ } ++ ++ out: ++ dm_pool_destroy(mem); ++ return r; ++} +diff --git a/lib/format_pool/.exported_symbols b/lib/format_pool/.exported_symbols +new file mode 100644 +index 0000000..e9fac2e +--- /dev/null ++++ b/lib/format_pool/.exported_symbols +@@ -0,0 +1 @@ ++init_format +diff --git a/lib/format_pool/Makefile.in b/lib/format_pool/Makefile.in +new file mode 100644 +index 0000000..05d1b0c +--- /dev/null ++++ b/lib/format_pool/Makefile.in +@@ -0,0 +1,30 @@ ++# ++# Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved. ++# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved. ++# ++# This file is part of LVM2. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++srcdir = @srcdir@ ++top_srcdir = @top_srcdir@ ++top_builddir = @top_builddir@ ++ ++SOURCES =\ ++ disk_rep.c \ ++ format_pool.c \ ++ import_export.c \ ++ pool_label.c ++ ++LIB_SHARED = liblvm2formatpool.$(LIB_SUFFIX) ++LIB_VERSION = $(LIB_VERSION_LVM) ++ ++include $(top_builddir)/make.tmpl ++ ++install: install_lvm2_plugin +diff --git a/lib/format_pool/disk_rep.c b/lib/format_pool/disk_rep.c +new file mode 100644 +index 0000000..fe9b03e +--- /dev/null ++++ b/lib/format_pool/disk_rep.c +@@ -0,0 +1,409 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "label.h" ++#include "metadata.h" ++#include "lvmcache.h" ++#include "xlate.h" ++#include "disk_rep.h" ++#include "toolcontext.h" ++ ++#include ++ ++/* FIXME: memcpy might not be portable */ ++#define CPIN_8(x, y, z) {memcpy((x), (y), (z));} ++#define CPOUT_8(x, y, z) {memcpy((y), (x), (z));} ++#define CPIN_16(x, y) {(x) = xlate16_be((y));} ++#define CPOUT_16(x, y) {(y) = xlate16_be((x));} ++#define CPIN_32(x, y) {(x) = xlate32_be((y));} ++#define CPOUT_32(x, y) {(y) = xlate32_be((x));} ++#define CPIN_64(x, y) {(x) = xlate64_be((y));} ++#define CPOUT_64(x, y) {(y) = xlate64_be((x));} ++ ++static int __read_pool_disk(const struct format_type *fmt, struct device *dev, ++ struct dm_pool *mem __attribute__((unused)), struct pool_list *pl, ++ const char *vg_name __attribute__((unused))) ++{ ++ char buf[512] __attribute__((aligned(8))); ++ ++ /* FIXME: Need to check the cache here first */ ++ if (!dev_read(dev, UINT64_C(0), 512, DEV_IO_POOL, buf)) { ++ log_very_verbose("Failed to read PV data from %s", ++ dev_name(dev)); ++ return 0; ++ } ++ ++ if (!read_pool_label(pl, fmt->labeller, dev, buf, NULL)) ++ return_0; ++ ++ return 1; ++} ++ ++static void _add_pl_to_list(struct cmd_context *cmd, struct dm_list *head, struct pool_list *data) ++{ ++ struct pool_list *pl; ++ ++ dm_list_iterate_items(pl, head) { ++ if (id_equal(&data->pv_uuid, &pl->pv_uuid)) { ++ char uuid[ID_LEN + 7] __attribute__((aligned(8))); ++ ++ if (!id_write_format(&pl->pv_uuid, uuid, ID_LEN + 7)) ++ stack; ++ ++ if (!dev_subsystem_part_major(cmd->dev_types, data->dev)) { ++ log_very_verbose("Ignoring duplicate PV %s on " ++ "%s", uuid, ++ dev_name(data->dev)); ++ return; ++ } ++ log_very_verbose("Duplicate PV %s - using %s %s", ++ uuid, dev_subsystem_name(cmd->dev_types, data->dev), ++ dev_name(data->dev)); ++ dm_list_del(&pl->list); ++ break; ++ } ++ } ++ dm_list_add(head, &data->list); ++} ++ ++int read_pool_label(struct pool_list *pl, struct labeller *l, ++ struct device *dev, char *buf, struct label **label) ++{ ++ struct lvmcache_info *info; ++ struct id pvid; ++ struct id vgid; ++ char uuid[ID_LEN + 7] __attribute__((aligned(8))); ++ struct pool_disk *pd = &pl->pd; ++ ++ pool_label_in(pd, buf); ++ ++ get_pool_pv_uuid(&pvid, pd); ++ if (!id_write_format(&pvid, uuid, ID_LEN + 7)) ++ stack; ++ log_debug_metadata("Calculated uuid %s for %s", uuid, dev_name(dev)); ++ ++ get_pool_vg_uuid(&vgid, pd); ++ if (!id_write_format(&vgid, uuid, ID_LEN + 7)) ++ stack; ++ log_debug_metadata("Calculated uuid %s for %s", uuid, pd->pl_pool_name); ++ ++ if (!(info = lvmcache_add(l, (char *) &pvid, dev, pd->pl_pool_name, ++ (char *) &vgid, 0))) ++ return_0; ++ if (label) ++ *label = lvmcache_get_label(info); ++ ++ lvmcache_set_device_size(info, ((uint64_t)xlate32_be(pd->pl_blocks)) << SECTOR_SHIFT); ++ lvmcache_set_ext_version(info, 0); ++ lvmcache_set_ext_flags(info, 0); ++ lvmcache_del_mdas(info); ++ lvmcache_del_bas(info); ++ ++ pl->dev = dev; ++ pl->pv = NULL; ++ memcpy(&pl->pv_uuid, &pvid, sizeof(pvid)); ++ ++ return 1; ++} ++ ++/** ++ * pool_label_out - copies a pool_label_t into a char buffer ++ * @pl: ptr to a pool_label_t struct ++ * @buf: ptr to raw space where label info will be copied ++ * ++ * This function is important because it takes care of all of ++ * the endian issues when copying to disk. This way, when ++ * machines of different architectures are used, they will ++ * be able to interpret ondisk labels correctly. Always use ++ * this function before writing to disk. ++ */ ++void pool_label_out(struct pool_disk *pl, void *buf) ++{ ++ struct pool_disk *bufpl = (struct pool_disk *) buf; ++ ++ CPOUT_64(pl->pl_magic, bufpl->pl_magic); ++ CPOUT_64(pl->pl_pool_id, bufpl->pl_pool_id); ++ CPOUT_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE); ++ CPOUT_32(pl->pl_version, bufpl->pl_version); ++ CPOUT_32(pl->pl_subpools, bufpl->pl_subpools); ++ CPOUT_32(pl->pl_sp_id, bufpl->pl_sp_id); ++ CPOUT_32(pl->pl_sp_devs, bufpl->pl_sp_devs); ++ CPOUT_32(pl->pl_sp_devid, bufpl->pl_sp_devid); ++ CPOUT_32(pl->pl_sp_type, bufpl->pl_sp_type); ++ CPOUT_64(pl->pl_blocks, bufpl->pl_blocks); ++ CPOUT_32(pl->pl_striping, bufpl->pl_striping); ++ CPOUT_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs); ++ CPOUT_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid); ++ CPOUT_32(pl->pl_sp_weight, bufpl->pl_sp_weight); ++ CPOUT_32(pl->pl_minor, bufpl->pl_minor); ++ CPOUT_32(pl->pl_padding, bufpl->pl_padding); ++ CPOUT_8(pl->pl_reserve, bufpl->pl_reserve, 184); ++} ++ ++/** ++ * pool_label_in - copies a char buffer into a pool_label_t ++ * @pl: ptr to a pool_label_t struct ++ * @buf: ptr to raw space where label info is copied from ++ * ++ * This function is important because it takes care of all of ++ * the endian issues when information from disk is about to be ++ * used. This way, when machines of different architectures ++ * are used, they will be able to interpret ondisk labels ++ * correctly. Always use this function before using labels that ++ * were read from disk. ++ */ ++void pool_label_in(struct pool_disk *pl, void *buf) ++{ ++ struct pool_disk *bufpl = (struct pool_disk *) buf; ++ ++ CPIN_64(pl->pl_magic, bufpl->pl_magic); ++ CPIN_64(pl->pl_pool_id, bufpl->pl_pool_id); ++ CPIN_8(pl->pl_pool_name, bufpl->pl_pool_name, POOL_NAME_SIZE); ++ CPIN_32(pl->pl_version, bufpl->pl_version); ++ CPIN_32(pl->pl_subpools, bufpl->pl_subpools); ++ CPIN_32(pl->pl_sp_id, bufpl->pl_sp_id); ++ CPIN_32(pl->pl_sp_devs, bufpl->pl_sp_devs); ++ CPIN_32(pl->pl_sp_devid, bufpl->pl_sp_devid); ++ CPIN_32(pl->pl_sp_type, bufpl->pl_sp_type); ++ CPIN_64(pl->pl_blocks, bufpl->pl_blocks); ++ CPIN_32(pl->pl_striping, bufpl->pl_striping); ++ CPIN_32(pl->pl_sp_dmepdevs, bufpl->pl_sp_dmepdevs); ++ CPIN_32(pl->pl_sp_dmepid, bufpl->pl_sp_dmepid); ++ CPIN_32(pl->pl_sp_weight, bufpl->pl_sp_weight); ++ CPIN_32(pl->pl_minor, bufpl->pl_minor); ++ CPIN_32(pl->pl_padding, bufpl->pl_padding); ++ CPIN_8(pl->pl_reserve, bufpl->pl_reserve, 184); ++} ++ ++static char _calc_char(unsigned int id) ++{ ++ /* ++ * [0-9A-Za-z!#] - 64 printable chars (6-bits) ++ */ ++ ++ if (id < 10) ++ return id + 48; ++ if (id < 36) ++ return (id - 10) + 65; ++ if (id < 62) ++ return (id - 36) + 97; ++ if (id == 62) ++ return '!'; ++ if (id == 63) ++ return '#'; ++ ++ return '%'; ++} ++ ++void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid) ++{ ++ int i; ++ unsigned shifter = 0x003F; ++ ++ assert(ID_LEN == 32); ++ memset(uuid, 0, ID_LEN); ++ strcat(uuid, "POOL0000000000"); ++ ++ /* We grab the entire 64 bits (+2 that get shifted in) */ ++ for (i = 13; i < 24; i++) { ++ uuid[i] = _calc_char(((unsigned) poolid) & shifter); ++ poolid = poolid >> 6; ++ } ++ ++ /* We grab the entire 32 bits (+4 that get shifted in) */ ++ for (i = 24; i < 30; i++) { ++ uuid[i] = _calc_char((unsigned) (spid & shifter)); ++ spid = spid >> 6; ++ } ++ ++ /* ++ * Since we can only have 128 devices, we only worry about the ++ * last 12 bits ++ */ ++ for (i = 30; i < 32; i++) { ++ uuid[i] = _calc_char((unsigned) (devid & shifter)); ++ devid = devid >> 6; ++ } ++ ++} ++ ++struct _read_pool_pv_baton { ++ const struct format_type *fmt; ++ struct dm_pool *mem, *tmpmem; ++ struct pool_list *pl; ++ struct dm_list *head; ++ const char *vgname; ++ uint32_t *sp_devs; ++ uint32_t sp_count; ++ int failed; ++ int empty; ++}; ++ ++static int _read_pool_pv(struct lvmcache_info *info, void *baton) ++{ ++ struct _read_pool_pv_baton *b = baton; ++ ++ b->empty = 0; ++ ++ if (lvmcache_device(info) && ++ !(b->pl = read_pool_disk(b->fmt, lvmcache_device(info), b->mem, b->vgname))) ++ return 0; ++ ++ /* ++ * We need to keep track of the total expected number ++ * of devices per subpool ++ */ ++ if (!b->sp_count) { ++ /* FIXME pl left uninitialised if !info->dev */ ++ if (!b->pl) { ++ log_error(INTERNAL_ERROR "device is missing"); ++ dm_pool_destroy(b->tmpmem); ++ b->failed = 1; ++ return 0; ++ } ++ b->sp_count = b->pl->pd.pl_subpools; ++ if (!(b->sp_devs = ++ dm_pool_zalloc(b->tmpmem, ++ sizeof(uint32_t) * b->sp_count))) { ++ log_error("Unable to allocate %d 32-bit uints", ++ b->sp_count); ++ dm_pool_destroy(b->tmpmem); ++ b->failed = 1; ++ return 0; ++ } ++ } ++ ++ /* ++ * watch out for a pool label with a different subpool ++ * count than the original - give up if it does ++ */ ++ if (b->sp_count != b->pl->pd.pl_subpools) ++ return 0; ++ ++ _add_pl_to_list(lvmcache_fmt(info)->cmd, b->head, b->pl); ++ ++ if (b->sp_count > b->pl->pd.pl_sp_id && b->sp_devs[b->pl->pd.pl_sp_id] == 0) ++ b->sp_devs[b->pl->pd.pl_sp_id] = b->pl->pd.pl_sp_devs; ++ ++ return 1; ++} ++ ++static int _read_vg_pds(struct _read_pool_pv_baton *b, ++ struct lvmcache_vginfo *vginfo, ++ uint32_t *devcount) ++{ ++ uint32_t i; ++ ++ b->sp_count = 0; ++ b->sp_devs = NULL; ++ b->failed = 0; ++ b->pl = NULL; ++ ++ /* FIXME: maybe should return a different error in memory ++ * allocation failure */ ++ if (!(b->tmpmem = dm_pool_create("pool read_vg", 512))) ++ return_0; ++ ++ lvmcache_foreach_pv(vginfo, _read_pool_pv, b); ++ ++ *devcount = 0; ++ for (i = 0; i < b->sp_count; i++) ++ *devcount += b->sp_devs[i]; ++ ++ dm_pool_destroy(b->tmpmem); ++ ++ if (b->pl && *b->pl->pd.pl_pool_name) ++ return 1; ++ ++ return 0; ++ ++} ++ ++int read_pool_pds(const struct format_type *fmt, const char *vg_name, ++ struct dm_pool *mem, struct dm_list *pdhead) ++{ ++ struct lvmcache_vginfo *vginfo; ++ uint32_t totaldevs; ++ int full_scan = -1; ++ ++ struct _read_pool_pv_baton baton; ++ ++ baton.vgname = vg_name; ++ baton.mem = mem; ++ baton.fmt = fmt; ++ baton.head = pdhead; ++ baton.empty = 1; ++ ++ do { ++ /* ++ * If the cache scanning doesn't work, this will never work ++ */ ++ if (vg_name && (vginfo = lvmcache_vginfo_from_vgname(vg_name, NULL)) && ++ _read_vg_pds(&baton, vginfo, &totaldevs) && !baton.empty) ++ { ++ /* ++ * If we found all the devices we were expecting, return ++ * success ++ */ ++ if (dm_list_size(pdhead) == totaldevs) ++ return 1; ++ ++ /* ++ * accept partial pool if we've done a full rescan of ++ * the cache ++ */ ++ if (full_scan > 0) ++ return 1; ++ } ++ ++ /* Failed */ ++ dm_list_init(pdhead); ++ ++ full_scan++; ++ if (full_scan > 1) { ++ log_debug_metadata("No devices for vg %s found in cache", ++ vg_name); ++ return 0; ++ } ++ lvmcache_label_scan(fmt->cmd); ++ ++ } while (1); ++ ++} ++ ++struct pool_list *read_pool_disk(const struct format_type *fmt, ++ struct device *dev, struct dm_pool *mem, ++ const char *vg_name) ++{ ++ struct pool_list *pl; ++ ++ if (!dev_open_readonly(dev)) ++ return_NULL; ++ ++ if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) { ++ log_error("Unable to allocate pool list structure"); ++ return 0; ++ } ++ ++ if (!__read_pool_disk(fmt, dev, mem, pl, vg_name)) ++ return_NULL; ++ ++ if (!dev_close(dev)) ++ stack; ++ ++ return pl; ++ ++} +diff --git a/lib/format_pool/disk_rep.h b/lib/format_pool/disk_rep.h +new file mode 100644 +index 0000000..37e942e +--- /dev/null ++++ b/lib/format_pool/disk_rep.h +@@ -0,0 +1,156 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef DISK_REP_FORMAT_POOL_H ++#define DISK_REP_FORMAT_POOL_H ++ ++#include "label.h" ++#include "metadata.h" ++ ++#define MINOR_OFFSET 65536 ++ ++/* From NSP.cf */ ++#define NSPMajorVersion 4 ++#define NSPMinorVersion 1 ++#define NSPUpdateLevel 3 ++ ++/* From pool_std.h */ ++#define POOL_NAME_SIZE (256) ++#define POOL_MAGIC 0x011670 ++#define POOL_MAJOR (121) ++#define POOL_MAX_DEVICES 128 ++ ++/* When checking for version matching, the first two numbers ** ++** are important for metadata formats, a.k.a pool labels. ** ++** All the numbers are important when checking if the user ** ++** space tools match up with the kernel module............. */ ++#define POOL_VERSION (NSPMajorVersion << 16 | \ ++ NSPMinorVersion << 8 | \ ++ NSPUpdateLevel) ++ ++/* Pool label is at the head of every pool disk partition */ ++#define SIZEOF_POOL_LABEL (8192) ++ ++/* in sectors */ ++#define POOL_PE_SIZE (SIZEOF_POOL_LABEL >> SECTOR_SHIFT) ++#define POOL_PE_START (SIZEOF_POOL_LABEL >> SECTOR_SHIFT) ++ ++/* Helper fxns */ ++#define get_pool_vg_uuid(id, pd) do { get_pool_uuid((char *)(id), \ ++ (pd)->pl_pool_id, 0, 0); \ ++ } while(0) ++#define get_pool_pv_uuid(id, pd) do { get_pool_uuid((char *)(id), \ ++ (pd)->pl_pool_id, \ ++ (pd)->pl_sp_id, \ ++ (pd)->pl_sp_devid); \ ++ } while(0) ++#define get_pool_lv_uuid(id, pd) do { get_pool_uuid((char *)&(id)[0], \ ++ (pd)->pl_pool_id, 0, 0); \ ++ get_pool_uuid((char*)&(id)[1], \ ++ (pd)->pl_pool_id, 0, 0); \ ++ } while(0) ++ ++struct pool_disk; ++struct pool_list; ++struct user_subpool; ++struct user_device; ++ ++struct pool_disk { ++ uint64_t pl_magic; /* Pool magic number */ ++ uint64_t pl_pool_id; /* Unique pool identifier */ ++ char pl_pool_name[POOL_NAME_SIZE]; /* Name of pool */ ++ uint32_t pl_version; /* Pool version */ ++ uint32_t pl_subpools; /* Number of subpools in this pool */ ++ uint32_t pl_sp_id; /* Subpool number within pool */ ++ uint32_t pl_sp_devs; /* Number of data partitions in this subpool */ ++ uint32_t pl_sp_devid; /* Partition number within subpool */ ++ uint32_t pl_sp_type; /* Partition type */ ++ uint64_t pl_blocks; /* Number of blocks in this partition */ ++ uint32_t pl_striping; /* Striping size within subpool */ ++ /* ++ * If the number of DMEP devices is zero, then the next field ** ++ * ** (pl_sp_dmepid) becomes the subpool ID for redirection. In ** ++ * ** other words, if this subpool does not have the capability ** ++ * ** to do DMEP, then it must specify which subpool will do it ** ++ * ** in it's place ++ */ ++ ++ /* ++ * While the next 3 field are no longer used, they must stay to keep ** ++ * ** backward compatibility........................................... ++ */ ++ uint32_t pl_sp_dmepdevs;/* Number of dmep devices in this subpool */ ++ uint32_t pl_sp_dmepid; /* Dmep device number within subpool */ ++ uint32_t pl_sp_weight; /* if dmep dev, pref to using it */ ++ ++ uint32_t pl_minor; /* the pool minor number */ ++ uint32_t pl_padding; /* reminder - think about alignment */ ++ ++ /* ++ * Even though we're zeroing out 8k at the front of the disk before ++ * writing the label, putting this in ++ */ ++ char pl_reserve[184]; /* bump the structure size out to 512 bytes */ ++}; ++ ++struct pool_list { ++ struct dm_list list; ++ struct pool_disk pd; ++ struct physical_volume *pv; ++ struct id pv_uuid; ++ struct device *dev; ++}; ++ ++struct user_subpool { ++ uint32_t initialized; ++ uint32_t id; ++ uint32_t striping; ++ uint32_t num_devs; ++ uint32_t type; ++ uint32_t dummy; ++ struct user_device *devs; ++}; ++ ++struct user_device { ++ uint32_t initialized; ++ uint32_t sp_id; ++ uint32_t devid; ++ uint32_t dummy; ++ uint64_t blocks; ++ struct physical_volume *pv; ++}; ++ ++int read_pool_label(struct pool_list *pl, struct labeller *l, ++ struct device *dev, char *buf, struct label **label); ++void pool_label_out(struct pool_disk *pl, void *buf); ++void pool_label_in(struct pool_disk *pl, void *buf); ++void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid); ++int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls); ++int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, ++ struct dm_list *pls); ++int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg, ++ struct dm_pool *mem, struct dm_list *pls); ++int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem, ++ struct volume_group *vg, struct physical_volume *pv, ++ struct pool_list *pl); ++int import_pool_segments(struct dm_list *lvs, struct dm_pool *mem, ++ struct user_subpool *usp, int sp_count); ++int read_pool_pds(const struct format_type *fmt, const char *vgname, ++ struct dm_pool *mem, struct dm_list *head); ++struct pool_list *read_pool_disk(const struct format_type *fmt, ++ struct device *dev, struct dm_pool *mem, ++ const char *vg_name); ++ ++#endif /* DISK_REP_POOL_FORMAT_H */ +diff --git a/lib/format_pool/format_pool.c b/lib/format_pool/format_pool.c +new file mode 100644 +index 0000000..f8223a3 +--- /dev/null ++++ b/lib/format_pool/format_pool.c +@@ -0,0 +1,337 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "label.h" ++#include "metadata.h" ++#include "limits.h" ++#include "display.h" ++#include "toolcontext.h" ++#include "lvmcache.h" ++#include "disk_rep.h" ++#include "format_pool.h" ++#include "pool_label.h" ++ ++/* Must be called after pvs are imported */ ++static struct user_subpool *_build_usp(struct dm_list *pls, struct dm_pool *mem, ++ int *sps) ++{ ++ struct pool_list *pl; ++ struct user_subpool *usp = NULL, *cur_sp = NULL; ++ struct user_device *cur_dev = NULL; ++ ++ /* ++ * FIXME: Need to do some checks here - I'm tempted to add a ++ * user_pool structure and build the entire thing to check against. ++ */ ++ dm_list_iterate_items(pl, pls) { ++ *sps = pl->pd.pl_subpools; ++ if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) { ++ log_error("Unable to allocate %d subpool structures", ++ *sps); ++ return 0; ++ } ++ ++ if (cur_sp != &usp[pl->pd.pl_sp_id]) { ++ cur_sp = &usp[pl->pd.pl_sp_id]; ++ ++ cur_sp->id = pl->pd.pl_sp_id; ++ cur_sp->striping = pl->pd.pl_striping; ++ cur_sp->num_devs = pl->pd.pl_sp_devs; ++ cur_sp->type = pl->pd.pl_sp_type; ++ cur_sp->initialized = 1; ++ } ++ ++ if (!cur_sp->devs && ++ (!(cur_sp->devs = ++ dm_pool_zalloc(mem, ++ sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) { ++ ++ log_error("Unable to allocate %d pool_device " ++ "structures", pl->pd.pl_sp_devs); ++ return 0; ++ } ++ ++ cur_dev = &cur_sp->devs[pl->pd.pl_sp_devid]; ++ cur_dev->sp_id = cur_sp->id; ++ cur_dev->devid = pl->pd.pl_sp_id; ++ cur_dev->blocks = pl->pd.pl_blocks; ++ cur_dev->pv = pl->pv; ++ cur_dev->initialized = 1; ++ } ++ ++ return usp; ++} ++ ++static int _check_usp(const char *vgname, struct user_subpool *usp, int sp_count) ++{ ++ int i; ++ unsigned j; ++ ++ for (i = 0; i < sp_count; i++) { ++ if (!usp[i].initialized) { ++ log_error("Missing subpool %d in pool %s", i, vgname); ++ return 0; ++ } ++ for (j = 0; j < usp[i].num_devs; j++) { ++ if (!usp[i].devs[j].initialized) { ++ log_error("Missing device %u for subpool %d" ++ " in pool %s", j, i, vgname); ++ return 0; ++ } ++ ++ } ++ } ++ ++ return 1; ++} ++ ++static struct volume_group *_pool_vg_read(struct format_instance *fid, ++ const char *vg_name, ++ struct metadata_area *mda __attribute__((unused)), ++ struct cached_vg_fmtdata **vg_fmtdata __attribute__((unused)), ++ unsigned *use_previous_vg __attribute__((unused))) ++{ ++ struct volume_group *vg; ++ struct user_subpool *usp; ++ int sp_count; ++ DM_LIST_INIT(pds); ++ ++ /* We can safely ignore the mda passed in */ ++ ++ /* Strip dev_dir if present */ ++ if (vg_name) ++ vg_name = strip_dir(vg_name, fid->fmt->cmd->dev_dir); ++ ++ /* Set vg_name through read_pool_pds() */ ++ if (!(vg = alloc_vg("pool_vg_read", fid->fmt->cmd, NULL))) ++ return_NULL; ++ ++ /* Read all the pvs in the vg */ ++ if (!read_pool_pds(fid->fmt, vg_name, vg->vgmem, &pds)) ++ goto_bad; ++ ++ /* Setting pool seqno to 1 because the code always did this, ++ * although we don't think it's needed. */ ++ vg->seqno = 1; ++ ++ if (!import_pool_vg(vg, vg->vgmem, &pds)) ++ goto_bad; ++ ++ if (!import_pool_pvs(fid->fmt, vg, vg->vgmem, &pds)) ++ goto_bad; ++ ++ if (!import_pool_lvs(vg, vg->vgmem, &pds)) ++ goto_bad; ++ ++ /* ++ * I need an intermediate subpool structure that contains all the ++ * relevant info for this. Then i can iterate through the subpool ++ * structures for checking, and create the segments ++ */ ++ if (!(usp = _build_usp(&pds, vg->vgmem, &sp_count))) ++ goto_bad; ++ ++ /* ++ * check the subpool structures - we can't handle partial VGs in ++ * the pool format, so this will error out if we're missing PVs ++ */ ++ if (!_check_usp(vg->name, usp, sp_count)) ++ goto_bad; ++ ++ if (!import_pool_segments(&vg->lvs, vg->vgmem, usp, sp_count)) ++ goto_bad; ++ ++ vg_set_fid(vg, fid); ++ ++ return vg; ++ ++bad: ++ release_vg(vg); ++ ++ return NULL; ++} ++ ++static int _pool_pv_initialise(const struct format_type *fmt __attribute__((unused)), ++ struct pv_create_args *pva __attribute__((unused)), ++ struct physical_volume *pv __attribute__((unused))) ++{ ++ return 1; ++} ++ ++static int _pool_pv_setup(const struct format_type *fmt __attribute__((unused)), ++ struct physical_volume *pv __attribute__((unused)), ++ struct volume_group *vg __attribute__((unused))) ++{ ++ return 1; ++} ++ ++static int _pool_pv_read(const struct format_type *fmt, const char *pv_name, ++ struct physical_volume *pv, ++ int scan_label_only __attribute__((unused))) ++{ ++ struct dm_pool *mem = dm_pool_create("pool pv_read", 1024); ++ struct pool_list *pl; ++ struct device *dev; ++ int r = 0; ++ ++ log_very_verbose("Reading physical volume data %s from disk", pv_name); ++ ++ if (!mem) ++ return_0; ++ ++ if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) ++ goto_out; ++ ++ /* ++ * I need to read the disk and populate a pv structure here ++ * I'll probably need to abstract some of this later for the ++ * vg_read code ++ */ ++ if (!(pl = read_pool_disk(fmt, dev, mem, NULL))) ++ goto_out; ++ ++ if (!import_pool_pv(fmt, fmt->cmd->mem, NULL, pv, pl)) ++ goto_out; ++ ++ pv->fmt = fmt; ++ ++ r = 1; ++ ++ out: ++ dm_pool_destroy(mem); ++ return r; ++} ++ ++/* *INDENT-OFF* */ ++static struct metadata_area_ops _metadata_format_pool_ops = { ++ .vg_read = _pool_vg_read, ++}; ++/* *INDENT-ON* */ ++ ++static struct format_instance *_pool_create_instance(const struct format_type *fmt, ++ const struct format_instance_ctx *fic) ++{ ++ struct format_instance *fid; ++ struct metadata_area *mda; ++ ++ if (!(fid = alloc_fid(fmt, fic))) ++ return_NULL; ++ ++ /* Define a NULL metadata area */ ++ if (!(mda = dm_pool_zalloc(fid->mem, sizeof(*mda)))) { ++ log_error("Unable to allocate metadata area structure " ++ "for pool format"); ++ goto bad; ++ } ++ ++ mda->ops = &_metadata_format_pool_ops; ++ mda->metadata_locn = NULL; ++ mda->status = 0; ++ dm_list_add(&fid->metadata_areas_in_use, &mda->list); ++ ++ return fid; ++ ++bad: ++ dm_pool_destroy(fid->mem); ++ return NULL; ++} ++ ++static void _pool_destroy_instance(struct format_instance *fid) ++{ ++ if (--fid->ref_count <= 1) ++ dm_pool_destroy(fid->mem); ++} ++ ++static void _pool_destroy(struct format_type *fmt) ++{ ++ if (fmt->orphan_vg) ++ free_orphan_vg(fmt->orphan_vg); ++ ++ dm_free(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, ++ .destroy = _pool_destroy, ++}; ++/* *INDENT-ON */ ++ ++#ifdef POOL_INTERNAL ++struct format_type *init_pool_format(struct cmd_context *cmd) ++#else /* Shared */ ++struct format_type *init_format(struct cmd_context *cmd); ++struct format_type *init_format(struct cmd_context *cmd) ++#endif ++{ ++ struct format_type *fmt = dm_malloc(sizeof(*fmt)); ++ struct format_instance_ctx fic; ++ struct format_instance *fid; ++ ++ if (!fmt) { ++ log_error("Unable to allocate format type structure for pool " ++ "format"); ++ return NULL; ++ } ++ ++ fmt->cmd = cmd; ++ fmt->ops = &_format_pool_ops; ++ fmt->name = FMT_POOL_NAME; ++ fmt->alias = NULL; ++ fmt->orphan_vg_name = FMT_POOL_ORPHAN_VG_NAME; ++ fmt->features = FMT_OBSOLETE; ++ fmt->private = NULL; ++ ++ dm_list_init(&fmt->mda_ops); ++ ++ if (!(fmt->labeller = pool_labeller_create(fmt))) { ++ log_error("Couldn't create pool label handler."); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ if (!(label_register_handler(fmt->labeller))) { ++ log_error("Couldn't register pool label handler."); ++ fmt->labeller->ops->destroy(fmt->labeller); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ if (!(fmt->orphan_vg = alloc_vg("pool_orphan", cmd, fmt->orphan_vg_name))) { ++ log_error("Couldn't create pool orphan VG."); ++ dm_free(fmt); ++ return NULL; ++ } ++ ++ fic.type = FMT_INSTANCE_AUX_MDAS; ++ fic.context.vg_ref.vg_name = fmt->orphan_vg_name; ++ fic.context.vg_ref.vg_id = NULL; ++ ++ if (!(fid = _pool_create_instance(fmt, &fic))) { ++ _pool_destroy(fmt); ++ return NULL; ++ } ++ ++ vg_set_fid(fmt->orphan_vg, fid); ++ ++ log_very_verbose("Initialised format: %s", fmt->name); ++ ++ return fmt; ++} +diff --git a/lib/format_pool/format_pool.h b/lib/format_pool/format_pool.h +new file mode 100644 +index 0000000..8ad7eb5 +--- /dev/null ++++ b/lib/format_pool/format_pool.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _LVM_FORMAT_POOL_H ++#define _LVM_FORMAT_POOL_H ++ ++#include "metadata.h" ++ ++#define FMT_POOL_NAME "pool" ++#define FMT_POOL_ORPHAN_VG_NAME ORPHAN_VG_NAME(FMT_POOL_NAME) ++ ++#ifdef POOL_INTERNAL ++struct format_type *init_pool_format(struct cmd_context *cmd); ++#endif ++ ++#endif +diff --git a/lib/format_pool/import_export.c b/lib/format_pool/import_export.c +new file mode 100644 +index 0000000..f4097a7 +--- /dev/null ++++ b/lib/format_pool/import_export.c +@@ -0,0 +1,285 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "label.h" ++#include "metadata.h" ++#include "disk_rep.h" ++#include "sptype_names.h" ++#include "lv_alloc.h" ++#include "pv_alloc.h" ++#include "str_list.h" ++#include "display.h" ++#include "segtype.h" ++#include "toolcontext.h" ++ ++/* This file contains only imports at the moment... */ ++ ++int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls) ++{ ++ struct pool_list *pl; ++ ++ dm_list_iterate_items(pl, pls) { ++ vg->extent_count += ++ ((pl->pd.pl_blocks) / POOL_PE_SIZE); ++ ++ vg->free_count = vg->extent_count; ++ ++ if (vg->name) ++ continue; ++ ++ vg->name = dm_pool_strdup(mem, pl->pd.pl_pool_name); ++ get_pool_vg_uuid(&vg->id, &pl->pd); ++ vg->extent_size = POOL_PE_SIZE; ++ vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED; ++ vg->max_lv = 1; ++ vg->max_pv = POOL_MAX_DEVICES; ++ vg->alloc = ALLOC_NORMAL; ++ } ++ ++ return 1; ++} ++ ++int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct dm_list *pls) ++{ ++ struct pool_list *pl; ++ struct logical_volume *lv; ++ ++ if (!(lv = alloc_lv(mem))) ++ return_0; ++ ++ lv->status = 0; ++ lv->alloc = ALLOC_NORMAL; ++ lv->size = 0; ++ lv->name = NULL; ++ lv->le_count = 0; ++ lv->read_ahead = vg->cmd->default_settings.read_ahead; ++ ++ dm_list_iterate_items(pl, pls) { ++ lv->size += pl->pd.pl_blocks; ++ ++ if (lv->name) ++ continue; ++ ++ if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) ++ return_0; ++ ++ get_pool_lv_uuid(lv->lvid.id, &pl->pd); ++ log_debug_metadata("Calculated lv uuid for lv %s: %s", lv->name, ++ lv->lvid.s); ++ ++ lv->status |= VISIBLE_LV | LVM_READ | LVM_WRITE; ++ lv->major = POOL_MAJOR; ++ ++ /* for pool a minor of 0 is dynamic */ ++ if (pl->pd.pl_minor) { ++ lv->status |= FIXED_MINOR; ++ lv->minor = pl->pd.pl_minor + MINOR_OFFSET; ++ } else { ++ lv->minor = -1; ++ } ++ } ++ ++ lv->le_count = lv->size / POOL_PE_SIZE; ++ ++ return link_lv_to_vg(vg, lv); ++} ++ ++int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg, ++ struct dm_pool *mem, struct dm_list *pls) ++{ ++ struct pv_list *pvl; ++ struct pool_list *pl; ++ ++ dm_list_iterate_items(pl, pls) { ++ if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) { ++ log_error("Unable to allocate pv list structure"); ++ return 0; ++ } ++ if (!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) { ++ log_error("Unable to allocate pv structure"); ++ return 0; ++ } ++ if (!import_pool_pv(fmt, mem, vg, pvl->pv, pl)) { ++ return 0; ++ } ++ pl->pv = pvl->pv; ++ pvl->mdas = NULL; ++ pvl->pe_ranges = NULL; ++ add_pvl_to_vgs(vg, pvl); ++ } ++ ++ return 1; ++} ++ ++int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem, ++ struct volume_group *vg, struct physical_volume *pv, ++ struct pool_list *pl) ++{ ++ struct pool_disk *pd = &pl->pd; ++ ++ memset(pv, 0, sizeof(*pv)); ++ ++ get_pool_pv_uuid(&pv->id, pd); ++ pv->fmt = fmt; ++ ++ pv->dev = pl->dev; ++ if (!(pv->vg_name = dm_pool_strdup(mem, pd->pl_pool_name))) { ++ log_error("Unable to duplicate vg_name string"); ++ return 0; ++ } ++ if (vg != NULL) ++ memcpy(&pv->vgid, &vg->id, sizeof(vg->id)); ++ pv->status = 0; ++ pv->size = pd->pl_blocks; ++ pv->pe_size = POOL_PE_SIZE; ++ pv->pe_start = POOL_PE_START; ++ pv->pe_count = pv->size / POOL_PE_SIZE; ++ pv->pe_alloc_count = 0; ++ pv->pe_align = 0; ++ ++ dm_list_init(&pv->tags); ++ dm_list_init(&pv->segments); ++ ++ if (!alloc_pv_segment_whole_pv(mem, pv)) ++ return_0; ++ ++ return 1; ++} ++ ++static const char *_cvt_sptype(uint32_t sptype) ++{ ++ int i; ++ for (i = 0; sptype_names[i].name[0]; i++) { ++ if (sptype == sptype_names[i].label) { ++ break; ++ } ++ } ++ log_debug_metadata("Found sptype %X and converted it to %s", ++ sptype, sptype_names[i].name); ++ return sptype_names[i].name; ++} ++ ++static int _add_stripe_seg(struct dm_pool *mem, ++ struct user_subpool *usp, struct logical_volume *lv, ++ uint32_t *le_cur) ++{ ++ struct lv_segment *seg; ++ struct segment_type *segtype; ++ unsigned j; ++ uint32_t area_len; ++ ++ if (!is_power_of_2(usp->striping)) { ++ log_error("Stripe size must be a power of 2"); ++ return 0; ++ } ++ ++ area_len = (usp->devs[0].blocks) / POOL_PE_SIZE; ++ ++ if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED))) ++ return_0; ++ ++ if (!(seg = alloc_lv_segment(segtype, lv, *le_cur, ++ area_len * usp->num_devs, 0, 0, ++ usp->striping, NULL, usp->num_devs, ++ area_len, 0, 0, 0, 0, NULL))) { ++ log_error("Unable to allocate striped lv_segment structure"); ++ return 0; ++ } ++ ++ for (j = 0; j < usp->num_devs; j++) ++ if (!set_lv_segment_area_pv(seg, j, usp->devs[j].pv, 0)) ++ return_0; ++ ++ /* add the subpool type to the segment tag list */ ++ if (!str_list_add(mem, &seg->tags, _cvt_sptype(usp->type))) { ++ log_error("Allocation failed for str_list."); ++ return 0; ++ } ++ ++ dm_list_add(&lv->segments, &seg->list); ++ ++ *le_cur += seg->len; ++ ++ return 1; ++} ++ ++static int _add_linear_seg(struct dm_pool *mem, ++ struct user_subpool *usp, struct logical_volume *lv, ++ uint32_t *le_cur) ++{ ++ struct lv_segment *seg; ++ struct segment_type *segtype; ++ unsigned j; ++ uint32_t area_len; ++ ++ if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED))) ++ return_0; ++ ++ for (j = 0; j < usp->num_devs; j++) { ++ area_len = (usp->devs[j].blocks) / POOL_PE_SIZE; ++ ++ if (!(seg = alloc_lv_segment(segtype, lv, *le_cur, ++ area_len, 0, 0, usp->striping, ++ NULL, 1, area_len, 0, ++ POOL_PE_SIZE, 0, 0, NULL))) { ++ log_error("Unable to allocate linear lv_segment " ++ "structure"); ++ return 0; ++ } ++ ++ /* add the subpool type to the segment tag list */ ++ if (!str_list_add(mem, &seg->tags, _cvt_sptype(usp->type))) { ++ log_error("Allocation failed for str_list."); ++ return 0; ++ } ++ ++ if (!set_lv_segment_area_pv(seg, 0, usp->devs[j].pv, 0)) ++ return_0; ++ dm_list_add(&lv->segments, &seg->list); ++ ++ *le_cur += seg->len; ++ } ++ ++ return 1; ++} ++ ++int import_pool_segments(struct dm_list *lvs, struct dm_pool *mem, ++ struct user_subpool *usp, int subpools) ++{ ++ struct lv_list *lvl; ++ struct logical_volume *lv; ++ uint32_t le_cur = 0; ++ int i; ++ ++ dm_list_iterate_items(lvl, lvs) { ++ lv = lvl->lv; ++ ++ if (lv_is_snapshot(lv)) ++ continue; ++ ++ for (i = 0; i < subpools; i++) { ++ if (usp[i].striping) { ++ if (!_add_stripe_seg(mem, &usp[i], lv, &le_cur)) ++ return_0; ++ } else { ++ if (!_add_linear_seg(mem, &usp[i], lv, &le_cur)) ++ return_0; ++ } ++ } ++ } ++ ++ return 1; ++} +diff --git a/lib/format_pool/pool_label.c b/lib/format_pool/pool_label.c +new file mode 100644 +index 0000000..2e30a7b +--- /dev/null ++++ b/lib/format_pool/pool_label.c +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "lib.h" ++#include "label.h" ++#include "metadata.h" ++#include "disk_rep.h" ++#include "pool_label.h" ++ ++#include ++#include ++ ++static void _pool_not_supported(const char *op) ++{ ++ log_error("The '%s' operation is not supported for the pool labeller.", ++ op); ++} ++ ++static int _pool_can_handle(struct labeller *l __attribute__((unused)), void *buf, uint64_t sector) ++{ ++ ++ struct pool_disk pd; ++ ++ /* ++ * POOL label must always be in first sector ++ */ ++ if (sector) ++ return 0; ++ ++ pool_label_in(&pd, buf); ++ ++ /* can ignore 8 rightmost bits for ondisk format check */ ++ if ((pd.pl_magic == POOL_MAGIC) && ++ (pd.pl_version >> 8 == POOL_VERSION >> 8)) ++ return 1; ++ ++ return 0; ++} ++ ++static int _pool_write(struct label *label __attribute__((unused)), void *buf __attribute__((unused))) ++{ ++ _pool_not_supported("write"); ++ return 0; ++} ++ ++static int _pool_read(struct labeller *l, struct device *dev, void *buf, ++ struct label **label) ++{ ++ struct pool_list pl; ++ ++ return read_pool_label(&pl, l, dev, buf, label); ++} ++ ++static int _pool_initialise_label(struct labeller *l __attribute__((unused)), struct label *label) ++{ ++ strcpy(label->type, "POOL"); ++ ++ return 1; ++} ++ ++static void _pool_destroy_label(struct labeller *l __attribute__((unused)), struct label *label __attribute__((unused))) ++{ ++} ++ ++static void _label_pool_destroy(struct labeller *l) ++{ ++ dm_free(l); ++} ++ ++struct label_ops _pool_ops = { ++ .can_handle = _pool_can_handle, ++ .write = _pool_write, ++ .read = _pool_read, ++ .initialise_label = _pool_initialise_label, ++ .destroy_label = _pool_destroy_label, ++ .destroy = _label_pool_destroy, ++}; ++ ++struct labeller *pool_labeller_create(struct format_type *fmt) ++{ ++ struct labeller *l; ++ ++ if (!(l = dm_malloc(sizeof(*l)))) { ++ log_error("Couldn't allocate labeller object."); ++ return NULL; ++ } ++ ++ l->ops = &_pool_ops; ++ l->fmt = fmt; ++ ++ return l; ++} +diff --git a/lib/format_pool/pool_label.h b/lib/format_pool/pool_label.h +new file mode 100644 +index 0000000..1a529a4 +--- /dev/null ++++ b/lib/format_pool/pool_label.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef _LVM_POOL_LABEL_H ++#define _LVM_POOL_LABEL_H ++ ++#include "metadata.h" ++ ++struct labeller *pool_labeller_create(struct format_type *fmt); ++ ++#endif +diff --git a/lib/format_pool/sptype_names.h b/lib/format_pool/sptype_names.h +new file mode 100644 +index 0000000..5812adb +--- /dev/null ++++ b/lib/format_pool/sptype_names.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 1997-2004 Sistina Software, Inc. All rights reserved. ++ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. ++ * ++ * This file is part of LVM2. ++ * ++ * This copyrighted material is made available to anyone wishing to use, ++ * modify, copy, or redistribute it subject to the terms and conditions ++ * of the GNU Lesser General Public License v.2.1. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#ifndef SPTYPE_NAMES_H ++#define SPTYPE_NAMES_H ++ ++/* This must be kept up to date with sistina/pool/module/pool_sptypes.h */ ++ ++/* Generic Labels */ ++#define SPTYPE_DATA (0x00000000) ++ ++/* GFS specific labels */ ++#define SPTYPE_GFS_DATA (0x68011670) ++#define SPTYPE_GFS_JOURNAL (0x69011670) ++ ++struct sptype_name { ++ const char *name; ++ uint32_t label; ++}; ++ ++static const struct sptype_name sptype_names[] = { ++ {"data", SPTYPE_DATA}, ++ ++ {"gfs_data", SPTYPE_GFS_DATA}, ++ {"gfs_journal", SPTYPE_GFS_JOURNAL}, ++ ++ {"", 0x0} /* This must be the last flag. */ ++}; ++ ++#endif +diff --git a/lib/format_text/export.c b/lib/format_text/export.c +index 7866d56..e535237 100644 +--- a/lib/format_text/export.c ++++ b/lib/format_text/export.c +@@ -467,6 +467,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg) + + if (vg->system_id && *vg->system_id) + outf(f, "system_id = \"%s\"", vg->system_id); ++ else if (vg->lvm1_system_id && *vg->lvm1_system_id) ++ outf(f, "system_id = \"%s\"", vg->lvm1_system_id); + + if (vg->lock_type) { + outf(f, "lock_type = \"%s\"", vg->lock_type); +diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c +index f39051c..4d0f6d5 100644 +--- a/lib/format_text/format-text.c ++++ b/lib/format_text/format-text.c +@@ -2568,9 +2568,9 @@ struct format_type *create_text_format(struct cmd_context *cmd) + fmt->name = FMT_TEXT_NAME; + fmt->alias = FMT_TEXT_ALIAS; + fmt->orphan_vg_name = ORPHAN_VG_NAME(FMT_TEXT_NAME); +- fmt->features = FMT_SEGMENTS | FMT_TAGS | FMT_PRECOMMIT | ++ fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT | + FMT_UNLIMITED_VOLS | FMT_RESIZE_PV | +- FMT_UNLIMITED_STRIPESIZE | FMT_CONFIG_PROFILE | ++ FMT_UNLIMITED_STRIPESIZE | FMT_BAS | FMT_CONFIG_PROFILE | + FMT_NON_POWER2_EXTENTS | FMT_PV_FLAGS; + + if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) { +diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c +index 58f517e..e038a27 100644 +--- a/lib/format_text/import_vsn1.c ++++ b/lib/format_text/import_vsn1.c +@@ -1084,8 +1084,15 @@ static struct volume_group *_read_vg(struct format_instance *fid, + goto bad; + } + ++ /* ++ * A system id without WRITE_LOCKED is an old lvm1 system id. ++ */ + if (dm_config_get_str(vgn, "system_id", &system_id)) { +- if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) { ++ if (!(vgstatus & LVM_WRITE_LOCKED)) { ++ if (!(vg->lvm1_system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1))) ++ goto_bad; ++ strncpy(vg->lvm1_system_id, system_id, NAME_LEN); ++ } else if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) { + log_error("Failed to allocate memory for system_id in _read_vg."); + goto bad; + } +diff --git a/lib/locking/locking.c b/lib/locking/locking.c +index 2584227..2b53553 100644 +--- a/lib/locking/locking.c ++++ b/lib/locking/locking.c +@@ -221,6 +221,42 @@ void fin_locking(void) + } + + /* ++ * Does the LVM1 driver know of this VG name? ++ */ ++int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname) ++{ ++ struct stat info; ++ char path[PATH_MAX]; ++ ++ /* We'll allow operations on orphans */ ++ if (!is_real_vg(vgname)) ++ return 1; ++ ++ /* LVM1 is only present in 2.4 kernels. */ ++ if (strncmp(cmd->kernel_vsn, "2.4.", 4)) ++ return 1; ++ ++ if (dm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir, ++ vgname) < 0) { ++ log_error("LVM1 proc VG pathname too long for %s", vgname); ++ return 0; ++ } ++ ++ if (stat(path, &info) == 0) { ++ log_error("%s exists: Is the original LVM driver using " ++ "this volume group?", path); ++ return 0; ++ } ++ ++ if (errno != ENOENT && errno != ENOTDIR) { ++ log_sys_error("stat", path); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* + * VG locking is by VG name. + * FIXME This should become VG uuid. + */ +@@ -332,6 +368,10 @@ int lock_vol(struct cmd_context *cmd, const char *vol, uint32_t flags, const str + lvmcache_drop_metadata(vol, 0); + } + ++ /* Lock VG to change on-disk metadata. */ ++ /* If LVM1 driver knows about the VG, it can't be accessed. */ ++ if (!check_lvm1_vg_inactive(cmd, vol)) ++ return_0; + break; + case LCK_LV: + /* All LV locks are non-blocking. */ +diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c +index 76451ea..9af90f9 100644 +--- a/lib/metadata/lv_manip.c ++++ b/lib/metadata/lv_manip.c +@@ -6011,6 +6011,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, + force_t force, int suppress_remove_message) + { + struct volume_group *vg; ++ struct logical_volume *format1_origin = NULL; ++ int format1_reload_required = 0; + int visible, historical; + struct logical_volume *pool_lv = NULL; + struct logical_volume *lock_lv = lv; +@@ -6163,6 +6165,10 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, + } + + if (lv_is_cow(lv)) { ++ /* Old format1 code */ ++ if (!(lv->vg->fid->fmt->features & FMT_MDAS)) ++ format1_origin = origin_from_cow(lv); ++ + log_verbose("Removing snapshot volume %s.", display_lvname(lv)); + /* vg_remove_snapshot() will preload origin/former snapshots */ + if (!vg_remove_snapshot(lv)) +@@ -6218,10 +6224,30 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, + } + } + ++ /* ++ * Old format1 code: If no snapshots left reload without -real. ++ */ ++ if (format1_origin && !lv_is_origin(format1_origin)) { ++ log_warn("WARNING: Support for snapshots with old LVM1-style metadata is deprecated."); ++ log_warn("WARNING: Please use lvconvert to update to lvm2 metadata at your convenience."); ++ format1_reload_required = 1; ++ } ++ + /* store it on disks */ + if (!vg_write(vg) || !vg_commit(vg)) + return_0; + ++ /* format1 */ ++ if (format1_reload_required) { ++ if (!suspend_lv(cmd, format1_origin)) ++ log_error("Failed to refresh %s without snapshot.", format1_origin->name); ++ ++ if (!resume_lv(cmd, format1_origin)) { ++ log_error("Failed to resume %s.", format1_origin->name); ++ return 0; ++ } ++ } ++ + /* Release unneeded blocks in thin pool */ + /* TODO: defer when multiple LVs relased at once */ + if (pool_lv && !update_pool_lv(pool_lv, 1)) { +diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h +index 75caba1..2245c29 100644 +--- a/lib/metadata/metadata-exported.h ++++ b/lib/metadata/metadata-exported.h +@@ -149,7 +149,7 @@ + + /* Format features flags */ + #define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */ +-// #define FMT_MDAS 0x00000002U /* Proper metadata areas? */ ++#define FMT_MDAS 0x00000002U /* Proper metadata areas? */ + #define FMT_TAGS 0x00000004U /* Tagging? */ + #define FMT_UNLIMITED_VOLS 0x00000008U /* Unlimited PVs/LVs? */ + #define FMT_RESTRICTED_LVIDS 0x00000010U /* LVID <= 255 */ +@@ -158,13 +158,15 @@ + #define FMT_RESIZE_PV 0x00000080U /* Supports pvresize? */ + #define FMT_UNLIMITED_STRIPESIZE 0x00000100U /* Unlimited stripe size? */ + #define FMT_RESTRICTED_READAHEAD 0x00000200U /* Readahead restricted to 2-120? */ +-// #define FMT_BAS 0x000000400U /* Supports bootloader areas? */ ++#define FMT_BAS 0x000000400U /* Supports bootloader areas? */ + #define FMT_CONFIG_PROFILE 0x000000800U /* Supports configuration profiles? */ +-// #define FMT_OBSOLETE 0x000001000U /* Obsolete format? */ ++#define FMT_OBSOLETE 0x000001000U /* Obsolete format? */ + #define FMT_NON_POWER2_EXTENTS 0x000002000U /* Non-power-of-2 extent sizes? */ +-// #define FMT_SYSTEMID_ON_PVS 0x000004000U /* System ID is stored on PVs not VG */ ++#define FMT_SYSTEMID_ON_PVS 0x000004000U /* System ID is stored on PVs not VG */ + #define FMT_PV_FLAGS 0x000008000U /* Supports PV flags */ + ++#define systemid_on_pvs(vg) ((vg)->fid->fmt->features & FMT_SYSTEMID_ON_PVS) ++ + /* Mirror conversion type flags */ + #define MIRROR_BY_SEG 0x00000001U /* segment-by-segment mirror */ + #define MIRROR_BY_LV 0x00000002U /* mirror using whole mimage LVs */ +diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c +index cb38f66..3620240 100644 +--- a/lib/metadata/metadata.c ++++ b/lib/metadata/metadata.c +@@ -1011,6 +1011,8 @@ struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name) + + vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE); + vg->system_id = NULL; ++ if (!(vg->lvm1_system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1))) ++ goto_bad; + + vg->extent_size = DEFAULT_EXTENT_SIZE * 2; + vg->max_lv = DEFAULT_MAX_LV; +@@ -2969,7 +2971,7 @@ int vg_write(struct volume_group *vg) + return 0; + } + +- if (!_vg_adjust_ignored_mdas(vg)) ++ if ((vg->fid->fmt->features & FMT_MDAS) && !_vg_adjust_ignored_mdas(vg)) + return_0; + + if (!vg_mda_used_count(vg)) { +@@ -5373,6 +5375,15 @@ int is_system_id_allowed(struct cmd_context *cmd, const char *system_id) + static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg) + { + /* ++ * LVM1 VGs must not be accessed if a new-style LVM2 system ID is set. ++ */ ++ if (cmd->system_id && systemid_on_pvs(vg)) { ++ log_error("Cannot access VG %s with LVM1 system ID %s when host system ID is set.", ++ vg->name, vg->lvm1_system_id); ++ return 0; ++ } ++ ++ /* + * A few commands allow read-only access to foreign VGs. + */ + if (cmd->include_foreign_vgs) +@@ -5424,6 +5435,11 @@ static int _vg_access_permitted(struct cmd_context *cmd, struct volume_group *vg + uint32_t lockd_state, uint32_t *failure) + { + if (!is_real_vg(vg->name)) { ++ /* Disallow use of LVM1 orphans when a host system ID is set. */ ++ if (cmd->system_id && *cmd->system_id && systemid_on_pvs(vg)) { ++ *failure |= FAILED_SYSTEMID; ++ return_0; ++ } + return 1; + } + +diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h +index 9c05836..309a246 100644 +--- a/lib/metadata/segtype.h ++++ b/lib/metadata/segtype.h +@@ -32,7 +32,7 @@ struct dev_manager; + #define SEG_AREAS_STRIPED (1ULL << 1) + #define SEG_AREAS_MIRRORED (1ULL << 2) + #define SEG_SNAPSHOT (1ULL << 3) +-/* #define SEG_FORMAT1_SUPPORT (1ULL << 4) */ ++#define SEG_FORMAT1_SUPPORT (1ULL << 4) + #define SEG_VIRTUAL (1ULL << 5) + #define SEG_CANNOT_BE_ZEROED (1ULL << 6) + #define SEG_MONITORED (1ULL << 7) +diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c +index aeb739c..156b4c8 100644 +--- a/lib/metadata/snapshot_manip.c ++++ b/lib/metadata/snapshot_manip.c +@@ -337,6 +337,17 @@ int vg_remove_snapshot(struct logical_volume *cow) + cow->snapshot = NULL; + lv_set_visible(cow); + ++ /* format1 must do the change in one step, with the commit last. */ ++ if (!(origin->vg->fid->fmt->features & FMT_MDAS)) { ++ /* Get the lock for COW volume */ ++ if (is_origin_active && !activate_lv(cow->vg->cmd, cow)) { ++ log_error("Unable to activate logical volume \"%s\"", ++ cow->name); ++ return 0; ++ } ++ return 1; ++ } ++ + if (!vg_write(origin->vg)) + return_0; + +diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c +index 42801b9..8585013 100644 +--- a/lib/metadata/vg.c ++++ b/lib/metadata/vg.c +@@ -41,6 +41,12 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd, + return NULL; + } + ++ if (!(vg->lvm1_system_id = dm_pool_zalloc(vgmem, NAME_LEN + 1))) { ++ log_error("Failed to allocate VG systemd id."); ++ dm_pool_destroy(vgmem); ++ return NULL; ++ } ++ + vg->system_id = ""; + + vg->cmd = cmd; +@@ -171,7 +177,7 @@ char *vg_name_dup(const struct volume_group *vg) + + char *vg_system_id_dup(const struct volume_group *vg) + { +- return dm_pool_strdup(vg->vgmem, vg->system_id ? : ""); ++ return dm_pool_strdup(vg->vgmem, vg->system_id ? : vg->lvm1_system_id ? : ""); + } + + char *vg_lock_type_dup(const struct volume_group *vg) +@@ -670,11 +676,20 @@ int vg_set_system_id(struct volume_group *vg, const char *system_id) + return 1; + } + ++ if (systemid_on_pvs(vg)) { ++ log_error("Metadata format %s does not support this type of system ID.", ++ vg->fid->fmt->name); ++ return 0; ++ } ++ + if (!(vg->system_id = dm_pool_strdup(vg->vgmem, system_id))) { + log_error("Failed to allocate memory for system_id in vg_set_system_id."); + return 0; + } + ++ if (vg->lvm1_system_id) ++ *vg->lvm1_system_id = '\0'; ++ + return 1; + } + +diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h +index 7ecfafe..29d88f8 100644 +--- a/lib/metadata/vg.h ++++ b/lib/metadata/vg.h +@@ -70,6 +70,7 @@ struct volume_group { + const char *name; + const char *old_name; /* Set during vgrename and vgcfgrestore */ + const char *system_id; ++ char *lvm1_system_id; + const char *lock_type; + const char *lock_args; + +diff --git a/lib/report/report.c b/lib/report/report.c +index 19f0f5c..8905d26 100644 +--- a/lib/report/report.c ++++ b/lib/report/report.c +@@ -2845,7 +2845,7 @@ static int _vgsystemid_disp(struct dm_report *rh, struct dm_pool *mem, + const void *data, void *private) + { + const struct volume_group *vg = (const struct volume_group *) data; +- const char *repstr = (vg->system_id && *vg->system_id) ? vg->system_id : ""; ++ const char *repstr = (vg->system_id && *vg->system_id) ? vg->system_id : vg->lvm1_system_id ? : ""; + + return _field_string(rh, field, repstr); + } +@@ -3830,6 +3830,7 @@ static struct volume_group _dummy_vg = { + .fid = &_dummy_fid, + .name = "", + .system_id = (char *) "", ++ .lvm1_system_id = (char *) "", + .pvs = DM_LIST_HEAD_INIT(_dummy_vg.pvs), + .lvs = DM_LIST_HEAD_INIT(_dummy_vg.lvs), + .historical_lvs = DM_LIST_HEAD_INIT(_dummy_vg.historical_lvs), +@@ -3840,6 +3841,7 @@ static struct volume_group _unknown_vg = { + .fid = &_dummy_fid, + .name = "[unknown]", + .system_id = (char *) "", ++ .lvm1_system_id = (char *) "", + .pvs = DM_LIST_HEAD_INIT(_unknown_vg.pvs), + .lvs = DM_LIST_HEAD_INIT(_unknown_vg.lvs), + .historical_lvs = DM_LIST_HEAD_INIT(_unknown_vg.historical_lvs), +diff --git a/lib/striped/striped.c b/lib/striped/striped.c +index 498b202..a2eaf80 100644 +--- a/lib/striped/striped.c ++++ b/lib/striped/striped.c +@@ -239,7 +239,8 @@ static struct segment_type *_init_segtype(struct cmd_context *cmd, const char *n + + segtype->ops = &_striped_ops; + segtype->name = name; +- segtype->flags = target | SEG_CAN_SPLIT | SEG_AREAS_STRIPED; ++ segtype->flags = target | SEG_CAN_SPLIT | SEG_AREAS_STRIPED | ++ SEG_FORMAT1_SUPPORT; + + log_very_verbose("Initialised segtype: %s", segtype->name); + return segtype; +diff --git a/man/vgconvert.8_des b/man/vgconvert.8_des +index 8519063..a0d34fd 100644 +--- a/man/vgconvert.8_des ++++ b/man/vgconvert.8_des +@@ -1,3 +1,6 @@ +-vgconvert converts VG metadata from one format to another. This command +-is no longer used because this version of lvm no longer supports the LVM1 ++vgconvert converts VG metadata from one format to another. The new ++metadata format must be able to fit into the space provided by the old + format. ++ ++Because the LVM1 format should no longer be used, this command is no ++longer needed in general. +diff --git a/test/shell/format-lvm1.sh b/test/shell/format-lvm1.sh +new file mode 100644 +index 0000000..b88579f +--- /dev/null ++++ b/test/shell/format-lvm1.sh +@@ -0,0 +1,38 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2008 Red Hat, Inc. All rights reserved. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++test_description='Test lvm1 format' ++ ++SKIP_WITH_LVMPOLLD=1 ++ ++. lib/inittest ++ ++aux prepare_devs 1 ++ ++if test -n "$LVM_TEST_LVM1" ; then ++pvcreate -M1 "$dev1" ++vgcreate -M1 $vg "$dev1" ++check vg_field $vg fmt "lvm1" ++fi ++ ++# TODO: if we decide to make using lvm1 with lvmetad an error, ++# then if lvmetad is being used, then verify: ++# not pvcreate -M1 "$dev1" ++# not vgcreate -M1 $vg "$dev1" ++# ++# TODO: if we decide to allow using lvm1 with lvmetad, but disable lvmetad ++# when it happens, then verify: ++# pvcreate -M1 "$dev1" | tee err ++# grep "disabled" err ++# vgcreate -M1 $vg "$dev1" | tee err ++# grep "disabled" err ++ +diff --git a/test/shell/lvm1-basic.sh b/test/shell/lvm1-basic.sh +new file mode 100644 +index 0000000..93509c4 +--- /dev/null ++++ b/test/shell/lvm1-basic.sh +@@ -0,0 +1,36 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2012 Red Hat, Inc. All rights reserved. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++SKIP_WITH_LVMLOCKD=1 ++SKIP_WITHOUT_LVMETAD=1 ++SKIP_WITH_LVMPOLLD=1 ++ ++. lib/inittest ++ ++aux prepare_devs 2 ++pvcreate --metadatatype 1 "$dev1" ++pvs | tee out ++grep "$dev1" out ++vgcreate --metadatatype 1 $vg1 "$dev1" ++vgs | tee out ++grep $vg1 out ++pvs | tee out ++grep "$dev1" out ++ ++# check for RHBZ 1080189 -- SEGV in lvremove/vgremove ++pvcreate -ff -y --metadatatype 1 "$dev1" "$dev2" ++vgcreate --metadatatype 1 $vg1 "$dev1" "$dev2" ++lvcreate -l1 $vg1 "$dev1" ++pvremove -ff -y "$dev2" ++vgchange -an $vg1 ++not lvremove $vg1 ++not vgremove -ff -y $vg1 +diff --git a/test/shell/snapshot-lvm1.sh b/test/shell/snapshot-lvm1.sh +new file mode 100644 +index 0000000..75c97cb +--- /dev/null ++++ b/test/shell/snapshot-lvm1.sh +@@ -0,0 +1,35 @@ ++#!/usr/bin/env bash ++ ++# Copyright (C) 2013 Red Hat, Inc. All rights reserved. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ ++# regression test for lvmetad reporting error: ++# Internal error: LV snap_with_lvm1_meta (00000000000000000000000000000001) missing from preload metadata ++ ++SKIP_WITH_LVMLOCKD=1 ++SKIP_WITH_LVMPOLLD=1 ++ ++. lib/inittest ++ ++aux prepare_devs 2 ++get_devs ++ ++vgcreate --metadatatype 1 "$vg" "${DEVICES[@]}" ++ ++# Make origin volume ++lvcreate -ae -l5 $vg -n origin ++ ++# Create a snap of origin ++lvcreate -s $vg/origin -n snap_with_lvm1_meta -l4 ++ ++# Remove volume snapper/snap_with_lvm1_meta ++lvremove -f $vg/snap_with_lvm1_meta ++ ++vgremove -ff $vg +diff --git a/tools/args.h b/tools/args.h +index c2fbac6..abe193c 100644 +--- a/tools/args.h ++++ b/tools/args.h +@@ -1211,7 +1211,8 @@ arg(mirrors_ARG, 'm', "mirrors", number_VAL, 0, 0, + arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_VAL, 0, 0, + "Specifies the type of on-disk metadata to use.\n" + "\\fBlvm2\\fP (or just \\fB2\\fP) is the current, standard format.\n" +- "\\fBlvm1\\fP (or just \\fB1\\fP) is no longer used.\n") ++ "\\fBlvm1\\fP (or just \\fB1\\fP) is a historical format that\n" ++ "can be used for accessing old data.\n") + + arg(name_ARG, 'n', "name", string_VAL, 0, 0, + "#lvcreate\n" +diff --git a/tools/lvconvert.c b/tools/lvconvert.c +index 8a07a84..e66f063 100644 +--- a/tools/lvconvert.c ++++ b/tools/lvconvert.c +@@ -1816,6 +1816,11 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu + return 0; + } + ++ if (!(vg->fid->fmt->features & FMT_MDAS)) { ++ log_error("Unable to split off snapshot %s using old LVM1-style metadata.", cow_name); ++ return 0; ++ } ++ + if (is_lockd_type(vg->lock_type)) { + /* FIXME: we need to create a lock for the new LV. */ + log_error("Unable to split snapshots in VG with lock_type %s.", vg->lock_type); +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index 0840c65..f238b64 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -19,9 +19,11 @@ + #include "label.h" + #include "lvm-version.h" + #include "lvmlockd.h" ++#include "lvmetad-client.h" + + #include "stub.h" + #include "last-path-component.h" ++#include "format1.h" + + #include + #include +@@ -2912,6 +2914,13 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + goto out; + } + ++ if (!strcmp(cmd->fmt->name, FMT_LVM1_NAME) && lvmetad_used()) { ++ log_warn("WARNING: Disabling lvmetad cache which does not support obsolete metadata."); ++ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_LVM1); ++ log_warn("WARNING: Not using lvmetad because lvm1 format is used."); ++ lvmetad_make_unused(cmd); ++ } ++ + if (cmd->command->command_enum == lvconvert_repair_CMD) { + log_warn("WARNING: Not using lvmetad because of repair."); + lvmetad_make_unused(cmd); +@@ -2974,7 +2983,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + * by different token values.) + * + * lvmetad may have been previously disabled (or disabled during the +- * rescan done here) because duplicate devices were seen. ++ * rescan done here) because duplicate devices or lvm1 metadata were seen. + * In this case, disable the *use* of lvmetad by this command, reverting to + * disk scanning. + */ +@@ -3399,6 +3408,41 @@ static int _run_script(struct cmd_context *cmd, int argc, char **argv) + return ret; + } + ++/* ++ * Determine whether we should fall back and exec the equivalent LVM1 tool ++ */ ++static int _lvm1_fallback(struct cmd_context *cmd) ++{ ++ char vsn[80]; ++ int dm_present; ++ ++ if (!find_config_tree_bool(cmd, global_fallback_to_lvm1_CFG, NULL) || ++ strncmp(cmd->kernel_vsn, "2.4.", 4)) ++ return 0; ++ ++ log_suppress(1); ++ dm_present = driver_version(vsn, sizeof(vsn)); ++ log_suppress(0); ++ ++ if (dm_present || !lvm1_present(cmd)) ++ return 0; ++ ++ return 1; ++} ++ ++static void _exec_lvm1_command(char **argv) ++{ ++ char path[PATH_MAX]; ++ ++ if (dm_snprintf(path, sizeof(path), "%s.lvm1", argv[0]) < 0) { ++ log_error("Failed to create LVM1 tool pathname"); ++ return; ++ } ++ ++ execvp(path, argv); ++ log_sys_error("execvp", path); ++} ++ + static void _nonroot_warning(void) + { + if (getuid() || geteuid()) +@@ -3488,6 +3532,19 @@ int lvm2_main(int argc, char **argv) + } else + run_name = dm_basename(argv[0]); + ++ if (_lvm1_fallback(cmd)) { ++ /* Attempt to run equivalent LVM1 tool instead */ ++ if (!argc) { ++ log_error("Falling back to LVM1 tools, but no " ++ "command specified."); ++ ret = ECMD_FAILED; ++ goto out; ++ } ++ _exec_lvm1_command(argv); ++ ret = ECMD_FAILED; ++ goto_out; ++ } ++ + /* + * Decide if we are running a shell or a command or a script. When + * there is no run_name, it's a shell, when run_name is a recognized +diff --git a/tools/pvscan.c b/tools/pvscan.c +index c21845c..e5afe0c 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -748,7 +748,7 @@ out: + * display the PV info. + * + * iii. If lvmetad is being used, but has been disabled (because of +- * duplicate devs), or has a non-matching token ++ * duplicate devs or lvm1 metadata), or has a non-matching token + * (because the device filter is different from the device filter last + * used to populate lvmetad), then 'pvscan' will begin by rescanning + * devices to repopulate lvmetad. If lvmetad is enabled after the +@@ -761,7 +761,8 @@ out: + * attempt to repopulate the lvmetad cache by rescanning all devs + * (regardless of whether lvmetad was previously disabled or had an + * unmatching token.) lvmetad may be enabled or disabled after the +- * rescan (depending on whether duplicate devs). ++ * rescan (depending on whether duplicate devs or lvm1 metadata was ++ * found). + * + * 3. The 'pvscan --cache ' command will attempt to repopulate the + * lvmetad cache by rescanning all devs if lvmetad has a non-matching +diff --git a/tools/stub.h b/tools/stub.h +index 1d58387..f03e5d3 100644 +--- a/tools/stub.h ++++ b/tools/stub.h +@@ -37,6 +37,7 @@ int pvdata(struct cmd_context *cmd __attribute__((unused)), + { + log_error("There's no 'pvdata' command in LVM2."); + log_error("Use lvs, pvs, vgs instead; or use vgcfgbackup and read the text file backup."); ++ log_error("Metadata in LVM1 format can still be displayed using LVM1's pvdata command."); + return ECMD_FAILED; + } + +diff --git a/tools/toollib.c b/tools/toollib.c +index 1b01ccc..81953ee 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -14,6 +14,7 @@ + */ + + #include "tools.h" ++#include "format1.h" + #include "format-text.h" + + #include +@@ -4168,6 +4169,7 @@ static int _process_duplicate_pvs(struct cmd_context *cmd, + .fid = &dummy_fid, + .name = "", + .system_id = (char *) "", ++ .lvm1_system_id = (char *) "", + .pvs = DM_LIST_HEAD_INIT(dummy_vg.pvs), + .lvs = DM_LIST_HEAD_INIT(dummy_vg.lvs), + .historical_lvs = DM_LIST_HEAD_INIT(dummy_vg.historical_lvs), +@@ -4805,6 +4807,23 @@ int pvcreate_params_from_args(struct cmd_context *cmd, struct pvcreate_params *p + pp->pva.label_sector = arg_int64_value(cmd, labelsector_ARG, + DEFAULT_LABELSECTOR); + ++ if (!(cmd->fmt->features & FMT_MDAS) && ++ (arg_is_set(cmd, pvmetadatacopies_ARG) || ++ arg_is_set(cmd, metadatasize_ARG) || ++ arg_is_set(cmd, dataalignment_ARG) || ++ arg_is_set(cmd, dataalignmentoffset_ARG))) { ++ log_error("Metadata and data alignment parameters only " ++ "apply to text format."); ++ return 0; ++ } ++ ++ if (!(cmd->fmt->features & FMT_BAS) && ++ arg_is_set(cmd, bootloaderareasize_ARG)) { ++ log_error("Bootloader area parameters only " ++ "apply to text format."); ++ return 0; ++ } ++ + if (arg_is_set(cmd, metadataignore_ARG)) + pp->pva.metadataignore = arg_int_value(cmd, metadataignore_ARG, + DEFAULT_PVMETADATAIGNORE); +@@ -5164,7 +5183,10 @@ static int _pvcreate_check_single(struct cmd_context *cmd, + pd->is_orphan_pv = 1; + } + +- pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME; ++ if (!strcmp(vg->name, FMT_LVM1_ORPHAN_VG_NAME)) ++ pp->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME; ++ else ++ pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME; + } else { + log_debug("Found pvcreate arg %s: device is not a PV.", pd->name); + /* Device is not a PV. */ +@@ -5393,7 +5415,10 @@ static int _pvremove_check_single(struct cmd_context *cmd, + pd->is_orphan_pv = 1; + } + +- pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME; ++ if (!strcmp(vg->name, FMT_LVM1_ORPHAN_VG_NAME)) ++ pp->orphan_vg_name = FMT_LVM1_ORPHAN_VG_NAME; ++ else ++ pp->orphan_vg_name = FMT_TEXT_ORPHAN_VG_NAME; + } else { + /* FIXME: is it possible to reach here? */ + log_debug("Found pvremove arg %s: device is not a PV.", pd->name); +diff --git a/tools/vals.h b/tools/vals.h +index 79c48b5..95dc8b2 100644 +--- a/tools/vals.h ++++ b/tools/vals.h +@@ -77,7 +77,7 @@ + * + * FIXME: are there some specialized or irrelevant + * options included in the usage text below that should +- * be removed? ++ * be removed? Should "lvm1" be removed? + * + * Size is a Number that takes an optional unit. + * A full usage could be "Size[b|B|s|S|k|K|m|M|g|G|t|T|p|P|e|E]" +@@ -126,7 +126,7 @@ val(sextents_VAL, sextents_arg, "SExtents", "[+|-]Number[PERCENT]") + val(pextents_VAL, pextents_arg, "PExtents", "[+]Number[PERCENT]") + val(nextents_VAL, nextents_arg, "NExtents", "[-]Number[PERCENT]") + val(permission_VAL, permission_arg, "Permission", "rw|r") +-val(metadatatype_VAL, metadatatype_arg, "MetadataType", "lvm2") ++val(metadatatype_VAL, metadatatype_arg, "MetadataType", "lvm2|lvm1") + val(units_VAL, string_arg, "Units", "r|R|h|H|b|B|s|S|k|K|m|M|g|G|t|T|p|P|e|E") + val(segtype_VAL, segtype_arg, "SegType", "linear|striped|snapshot|mirror|raid|thin|cache|thin-pool|cache-pool") + val(alloc_VAL, alloc_arg, "Alloc", "contiguous|cling|cling_by_tags|normal|anywhere|inherit") +diff --git a/tools/vgchange.c b/tools/vgchange.c +index 52abc11..1736faf 100644 +--- a/tools/vgchange.c ++++ b/tools/vgchange.c +@@ -558,6 +558,13 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg) + const char *system_id; + const char *system_id_arg_str = arg_str_value(cmd, systemid_ARG, NULL); + ++ /* FIXME Merge with vg_set_system_id() */ ++ if (systemid_on_pvs(vg)) { ++ log_error("Metadata format %s does not support this type of system ID.", ++ vg->fid->fmt->name); ++ return 0; ++ } ++ + if (!(system_id = system_id_from_string(cmd, system_id_arg_str))) { + log_error("Unable to set system ID."); + return 0; +@@ -607,6 +614,9 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg) + + vg->system_id = system_id; + ++ if (vg->lvm1_system_id) ++ *vg->lvm1_system_id = '\0'; ++ + return 1; + } + +diff --git a/tools/vgconvert.c b/tools/vgconvert.c +index ca9615c..8bdf8be 100644 +--- a/tools/vgconvert.c ++++ b/tools/vgconvert.c +@@ -34,25 +34,29 @@ static int _vgconvert_single(struct cmd_context *cmd, const char *vg_name, + return ECMD_FAILED; + } + +- if (arg_sign_value(cmd, metadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { +- log_error("Metadata size may not be negative"); +- return EINVALID_CMD_LINE; +- } +- +- pva.pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0)); +- if (!pva.pvmetadatasize) +- pva.pvmetadatasize = find_config_tree_int(cmd, metadata_pvmetadatasize_CFG, NULL); ++ if (cmd->fmt->features & FMT_MDAS) { ++ if (arg_sign_value(cmd, metadatasize_ARG, SIGN_NONE) == SIGN_MINUS) { ++ log_error("Metadata size may not be negative"); ++ return EINVALID_CMD_LINE; ++ } + +- pva.pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1); +- if (pva.pvmetadatacopies < 0) +- pva.pvmetadatacopies = find_config_tree_int(cmd, metadata_pvmetadatacopies_CFG, NULL); ++ pva.pvmetadatasize = arg_uint64_value(cmd, metadatasize_ARG, UINT64_C(0)); ++ if (!pva.pvmetadatasize) ++ pva.pvmetadatasize = find_config_tree_int(cmd, metadata_pvmetadatasize_CFG, NULL); + +- if (arg_sign_value(cmd, bootloaderareasize_ARG, SIGN_NONE) == SIGN_MINUS) { +- log_error("Bootloader area size may not be negative"); +- return EINVALID_CMD_LINE; ++ pva.pvmetadatacopies = arg_int_value(cmd, pvmetadatacopies_ARG, -1); ++ if (pva.pvmetadatacopies < 0) ++ pva.pvmetadatacopies = find_config_tree_int(cmd, metadata_pvmetadatacopies_CFG, NULL); + } + +- pva.ba_size = arg_uint64_value(cmd, bootloaderareasize_ARG, UINT64_C(0)); ++ if (cmd->fmt->features & FMT_BAS) { ++ if (arg_sign_value(cmd, bootloaderareasize_ARG, SIGN_NONE) == SIGN_MINUS) { ++ log_error("Bootloader area size may not be negative"); ++ return EINVALID_CMD_LINE; ++ } ++ ++ pva.ba_size = arg_uint64_value(cmd, bootloaderareasize_ARG, UINT64_C(0)); ++ } + + if (!vg_check_new_extent_size(cmd->fmt, vg->extent_size)) + return_ECMD_FAILED; +@@ -82,6 +86,13 @@ static int _vgconvert_single(struct cmd_context *cmd, const char *vg_name, + return ECMD_FAILED; + } + ++ /* New-style system ID supported? */ ++ if (vg->system_id && *vg->system_id && (cmd->fmt->features & FMT_SYSTEMID_ON_PVS)) { ++ log_error("Unable to convert VG %s while it has a system ID set (%s).", vg->name, ++ vg->system_id); ++ return ECMD_FAILED; ++ } ++ + /* Attempt to change any LVIDs that are too big */ + if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) { + dm_list_iterate_items(lvl, &vg->lvs) { +@@ -146,6 +157,18 @@ int vgconvert(struct cmd_context *cmd, int argc, char **argv) + return EINVALID_CMD_LINE; + } + ++ if (!(cmd->fmt->features & FMT_MDAS) && ++ arg_is_set(cmd, pvmetadatacopies_ARG)) { ++ log_error("Metadata parameters only apply to text format"); ++ return EINVALID_CMD_LINE; ++ } ++ ++ if (!(cmd->fmt->features & FMT_BAS) && ++ arg_is_set(cmd, bootloaderareasize_ARG)) { ++ log_error("Bootloader area parameters only apply to text format"); ++ return EINVALID_CMD_LINE; ++ } ++ + return process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, 0, NULL, + &_vgconvert_single); + } +diff --git a/tools/vgscan.c b/tools/vgscan.c +index f9fa382..1ec9083 100644 +--- a/tools/vgscan.c ++++ b/tools/vgscan.c +@@ -44,7 +44,7 @@ static int _vgscan_single(struct cmd_context *cmd, const char *vg_name, + * display the VG info. + * + * iii. If lvmetad is being used, but has been disabled (because of +- * duplicate devs), or has a non-matching token ++ * duplicate devs or lvm1 metadata), or has a non-matching token + * (because the device filter is different from the device filter last + * used to populate lvmetad), then 'vgscan' will begin by rescanning + * devices to repopulate lvmetad. If lvmetad is enabled after the +@@ -57,7 +57,7 @@ static int _vgscan_single(struct cmd_context *cmd, const char *vg_name, + * the lvmetad cache by rescanning all devs (regardless of whether + * lvmetad was previously disabled or had an unmatching token.) + * lvmetad may be enabled or disabled after the rescan (depending +- * on whether duplicate devs were found). ++ * on whether duplicate devs or lvm1 metadata was found). + * If enabled, then it will simply read and display VG info from the + * lvmetad cache (like case 1.i.). If disabled, then it will + * read all devices to display VG info (like case 1.ii.) diff --git a/SOURCES/lvm2-rhel7.patch b/SOURCES/lvm2-rhel7.patch new file mode 100644 index 0000000..b7df03d --- /dev/null +++ b/SOURCES/lvm2-rhel7.patch @@ -0,0 +1,18 @@ + VERSION | 2 +- + VERSION_DM | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/VERSION b/VERSION +index 7f0e456..0c3bfac 100644 +--- a/VERSION ++++ b/VERSION +@@ -1 +1 @@ +-2.02.186(2) (2019-08-27) ++2.02.186(2)-RHEL7 (2019-08-27) +diff --git a/VERSION_DM b/VERSION_DM +index 864ceb8..5093e13 100644 +--- a/VERSION_DM ++++ b/VERSION_DM +@@ -1 +1 @@ +-1.02.164 (2019-08-27) ++1.02.164-RHEL7 (2019-08-27) diff --git a/SOURCES/lvm2-set-default-preferred_names.patch b/SOURCES/lvm2-set-default-preferred_names.patch new file mode 100644 index 0000000..205dd10 --- /dev/null +++ b/SOURCES/lvm2-set-default-preferred_names.patch @@ -0,0 +1,30 @@ + conf/example.conf.in | 2 +- + lib/config/config_settings.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/conf/example.conf.in b/conf/example.conf.in +index 38855e9..7ccf928 100644 +--- a/conf/example.conf.in ++++ b/conf/example.conf.in +@@ -106,7 +106,7 @@ devices { + # Example + # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] + # +- # This configuration option does not have a default value defined. ++ preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] + + # Configuration option devices/filter. + # Limit the block devices that are used by LVM commands. +diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h +index 0e81252..02e2b29 100644 +--- a/lib/config/config_settings.h ++++ b/lib/config/config_settings.h +@@ -255,7 +255,7 @@ cfg(devices_external_device_info_source_CFG, "external_device_info_source", devi + " compiled with udev support.\n" + "#\n") + +-cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED , CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL, 0, NULL, ++cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#S^/dev/mpath/#S^/dev/mapper/mpath#S^/dev/[hs]d", vsn(1, 2, 19), NULL, 0, NULL, + "Select which path name to display for a block device.\n" + "If multiple path names exist for a block device, and LVM needs to\n" + "display a name for the device, the path names are matched against\n" diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec new file mode 100644 index 0000000..11056b7 --- /dev/null +++ b/SPECS/lvm2.spec @@ -0,0 +1,4090 @@ +%global device_mapper_version 1.02.164 + +%global enable_cache 1 +%global enable_cluster 1 +%global enable_cmirror 1 +%global enable_lvmetad 1 +%global enable_lvmlockd 1 +%global enable_lvmpolld 1 +%global enable_python 1 +%global enable_thin 1 +%global enable_dmfilemapd 1 + +%global systemd_version 189-3 +%global dracut_version 002-18 +%global util_linux_version 2.23 +%global bash_version 4.0 +%global corosync_version 1.99.9-1 +%global resource_agents_version 3.9.5-25 +%global dlm_version 4.0.6-2 +%global libselinux_version 1.30.19-4 +%global persistent_data_version 0.7.0-0.1.rc6 +%global sanlock_version 3.3.0-1 +%global boom_version 0.9 + +%global enable_lockd_sanlock %{enable_lvmlockd} +%global enable_lockd_dlm %{enable_lvmlockd} + +%global boom_pkgname lvm2-python-boom +%global boom_version 0.9 +%global boom_release 20 +%global boom_summary A set of libraries and tools for managing boot loader entries +%global boom_dir boom-%{boom_version} + +#%%global scratch .bz1628529_4 + +%if 0%{?rhel} + %ifnarch i686 x86_64 ppc64le s390x + %global enable_cluster 0 + %global enable_cmirror 0 + %global enable_lockd_dlm 0 + %endif + + %ifnarch x86_64 ppc64 aarch64 + %global enable_lockd_sanlock 0 + %endif +%endif + +%ifnarch s390x s390 + %global enable_boom 1 +%else + %global enable_boom 0 +%endif + +%if %{enable_cluster} + %global configure_cluster --with-cluster=internal --with-clvmd=corosync + %if %{enable_cmirror} + %global configure_cmirror --enable-cmirrord + %endif +%else + %global configure_cluster --with-cluster=internal --with-clvmd=none +%endif + +# Do not reset Release to 1 unless both lvm2 and device-mapper +# versions are increased together. + +Summary: Userland logical volume management tools +Name: lvm2 +Epoch: 7 +Version: 2.02.186 +Release: 2%{?dist}%{?scratch} +License: GPLv2 +Group: System Environment/Base +URL: http://sources.redhat.com/lvm2 +Source0: ftp://sources.redhat.com/pub/lvm2/releases/LVM2.%{version}.tgz +Source1: https://github.com/bmr-cymru/boom/archive/%{boom_version}/boom-%{boom_version}.tar.gz +Patch0: lvm2-rhel7.patch +Patch1: lvm2-set-default-preferred_names.patch +Patch2: lvm2-fix-libdm-versioning-for-dm_tree_node_size_changed-symbol.patch +Patch3: lvm2-drop-unavailable-libblkid-2_24-BLKID_SUBLKS_BADCSUM-for-signature-detection.patch +Patch4: lvm2-default-allow-changes-with-duplicate-pvs.patch +#Patch5: lvm2-rhel7-fix-StartLimitInterval.patch +Patch6: lvm2-rhel7-add-lvm1-and-pool-back.patch +Patch7: lvm2-make-generate.patch +Patch8: lvm2-2_02_187-cov-Fix-memory-leak.patch +# BZ 1669751: +Patch9: lvm2-2_02_187-vgcreate-vgextend-restrict-PVs-with-mixed-block-size.patch +Patch10: lvm2-2_02_187-WHATS_NEW-vgcreate-vgextend-logical-block-size.patch +# BZ 1622813: +Patch11: lvm2-2_02_187-pvmove-check-if-participating-LV-is-already-exlcusiv.patch +# BZ 1697823: +Patch12: lvm2-2_02_187-lvconvert-improve-validation-thin-and-cache-pool-con.patch +Patch13: lvm2-2_02_187-thin-activate-layer-pool-aas-read-only-LV.patch + + +BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel +BuildRequires: libblkid-devel >= %{util_linux_version} +BuildRequires: ncurses-devel +BuildRequires: readline-devel +BuildRequires: libaio-devel +%if %{enable_cluster} +BuildRequires: corosynclib-devel >= %{corosync_version} +%endif +%if %{enable_cluster} || %{enable_lockd_dlm} +BuildRequires: dlm-devel >= %{dlm_version} +%endif +BuildRequires: module-init-tools +BuildRequires: pkgconfig +BuildRequires: systemd-devel +BuildRequires: systemd-units +%if %{enable_python} || %{enable_boom} +BuildRequires: python2-devel +BuildRequires: python-setuptools +%endif +%if %{enable_thin} || %{enable_cache} +BuildRequires: device-mapper-persistent-data >= %{persistent_data_version} +%endif +%if %{enable_lockd_sanlock} +BuildRequires: sanlock-devel >= %{sanlock_version} +%endif + +Requires: %{name}-libs = %{epoch}:%{version}-%{release} +Requires: bash >= %{bash_version} +Requires(post): systemd-units >= %{systemd_version} +Requires(preun): systemd-units >= %{systemd_version} +Requires(postun): systemd-units >= %{systemd_version} +Requires: module-init-tools +%if %{enable_thin} || %{enable_cache} +Requires: device-mapper-persistent-data >= %{persistent_data_version} +%endif +# BZ https://bugzilla.redhat.com/show_bug.cgi?id=1523288 + +%description +LVM2 includes all of the support for handling read/write operations on +physical volumes (hard disks, RAID-Systems, magneto optical, etc., +multiple devices (MD), see mdadm(8) or even loop devices, see +losetup(8)), creating volume groups (kind of virtual disks) from one +or more physical volumes and creating one or more logical volumes +(kind of logical partitions) in volume groups. + +%prep +%if %{enable_boom} +%setup -q -b 1 -n %{boom_dir} +%endif + +%setup -q -n LVM2.%{version} +%patch0 -p1 -b .rhel7 +%patch1 -p1 -b .preferred_names +%patch2 -p1 -b .libdm_symbol_versioning +%patch3 -p1 -b .blkid_sublks_badcsum +%patch4 -p1 -b .default_allow_dup +#%%patch5 -p1 -b .startlimitinterval +%patch6 -p1 -b .add_lvm1_and_pool +%patch7 -p1 -b .generate +%patch8 -p1 -b .cov_Fix_memory_leak +%patch9 -p1 -b .vgcreate_vgextend_restrict_PVs_with_mixed_block_size +%patch10 -p1 -b .WHATS_NEW_vgcreate_vgextend_logical_block_size +%patch11 -p1 -b .pvmove_check_if_participating_LV_is_already_exlcusiv +%patch12 -p1 -b .lvconvert_improve_validation_thin_and_cache_pool_con +%patch13 -p1 -b .thin_activate_layer_pool_aas_read_only_LV + +%build +%global _default_pid_dir /run +%global _default_dm_run_dir /run +%global _default_run_dir /run/lvm +%global _default_locking_dir /run/lock/lvm + +%global _udevdir %{_prefix}/lib/udev/rules.d +%global _tmpfilesdir %{_prefix}/lib/tmpfiles.d + +%global configure_udev --with-udevdir=%{_udevdir} --enable-udev_sync + +%if %{enable_cache} +%global configure_cache --with-cache=internal +%endif + +%if %{enable_thin} +%global configure_thin --with-thin=internal +%endif + +%if %{enable_lvmetad} +%global configure_lvmetad --enable-lvmetad +%endif + +%if %{enable_lockd_dlm} +%global configure_lockd_dlm --enable-lvmlockd-dlm +%endif + +%if %{enable_lockd_sanlock} +%global configure_lockd_sanlock --enable-lvmlockd-sanlock +%endif + +%if %{enable_lvmpolld} +%global configure_lvmpolld --enable-lvmpolld +%endif + +%if %{enable_python} +%global configure_python --enable-python2-bindings +%endif + +%if %{enable_dmfilemapd} +%global configure_dmfilemapd --enable-dmfilemapd +%endif + +%configure --with-default-dm-run-dir=%{_default_dm_run_dir} --with-default-run-dir=%{_default_run_dir} --with-default-pid-dir=%{_default_pid_dir} --with-default-locking-dir=%{_default_locking_dir} --with-usrlibdir=%{_libdir} --enable-lvm1_fallback --enable-fsadm --with-pool=internal --enable-write_install --with-user= --with-group= --with-device-uid=0 --with-device-gid=6 --with-device-mode=0660 --enable-pkgconfig --enable-applib --enable-cmdlib --enable-dmeventd --enable-blkid_wiping %{?configure_python} %{?configure_cluster} %{?configure_cmirror} %{?configure_udev} %{?configure_thin} %{?configure_lvmetad} %{?configure_cache} %{?configure_lvmpolld} %{?configure_lockd_dlm} %{?configure_lockd_sanlock} %{?configure_dmfilemapd} + +make %{?_smp_mflags} + +%if %{enable_boom} +( +cd ../%{boom_dir} +%py2_build +) +%endif + +%install +make install DESTDIR=$RPM_BUILD_ROOT +make install_system_dirs DESTDIR=$RPM_BUILD_ROOT +make install_initscripts DESTDIR=$RPM_BUILD_ROOT +make install_systemd_units DESTDIR=$RPM_BUILD_ROOT +make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT +make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT + +%if %{enable_boom} +( +cd ../%{boom_dir} +%py2_install + +# Install Grub2 integration scripts +install -d -m 700 ${RPM_BUILD_ROOT}/etc/grub.d +install -d -m 755 ${RPM_BUILD_ROOT}/etc/default +install -m 755 etc/grub.d/42_boom ${RPM_BUILD_ROOT}/etc/grub.d +install -m 644 etc/default/boom ${RPM_BUILD_ROOT}/etc/default + +# Make configuration directories +install -d -m 700 ${RPM_BUILD_ROOT}/boot/boom/profiles +install -d -m 700 ${RPM_BUILD_ROOT}/boot/loader/entries +install -m 644 examples/profiles/*.profile ${RPM_BUILD_ROOT}/boot/boom/profiles + +install -d -m 755 ${RPM_BUILD_ROOT}/%{_mandir}/man8 +install -m 644 man/man8/boom.8 ${RPM_BUILD_ROOT}/%{_mandir}/man8 +) +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/ldconfig +%systemd_post lvm2-monitor.service +if [ "$1" = "1" ] ; then + # enable and start lvm2-monitor.service on completely new installation only, not on upgrades + systemctl enable lvm2-monitor.service + systemctl start lvm2-monitor.service +fi +%if %{enable_lvmetad} +%systemd_post lvm2-lvmetad.socket +# lvm2-lvmetad.socket is always enabled and started and ready to serve if lvmetad is used +# replace direct systemctl calls with systemd rpm macro once this is provided in the macro: +# http://cgit.freedesktop.org/systemd/systemd/commit/?id=57ab2eabb8f92fad5239c7d4492e9c6e23ee0678 +systemctl enable lvm2-lvmetad.socket +systemctl start lvm2-lvmetad.socket +%endif + +%if %{enable_lvmpolld} +%systemd_post lvm2-lvmpolld.socket +# lvm2-lvmpolld socket is always enabled and started and ready to serve if lvmpolld is used +# replace direct systemctl calls with systemd rpm macro once this is provided in the macro: +# http://cgit.freedesktop.org/systemd/systemd/commit/?id=57ab2eabb8f92fad5239c7d4492e9c6e23ee0678 +systemctl enable lvm2-lvmpolld.socket +systemctl start lvm2-lvmpolld.socket +%endif + +%preun +%systemd_preun lvm2-monitor.service +%if %{enable_lvmetad} +%systemd_preun lvm2-lvmetad.service lvm2-lvmetad.socket +%endif + +%if %{enable_lvmpolld} +%systemd_preun lvm2-lvmpolld.service lvm2-lvmpolld.socket +%endif + +%postun +%systemd_postun lvm2-monitor.service +%if %{enable_lvmetad} +%systemd_postun_with_restart lvm2-lvmetad.service +%endif + +%if %{enable_lvmpolld} +%systemd_postun_with_restart lvm2-lvmpolld.service +%endif + +%triggerun -- %{name} < 2.02.86-2 +%{_bindir}/systemd-sysv-convert --save lvm2-monitor >/dev/null 2>&1 || : +/bin/systemctl --no-reload enable lvm2-monitor.service > /dev/null 2>&1 || : +/sbin/chkconfig --del lvm2-monitor > /dev/null 2>&1 || : +/bin/systemctl try-restart lvm2-monitor.service > /dev/null 2>&1 || : + +%files +%defattr(-,root,root,755) +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB +%doc README VERSION WHATS_NEW +%doc doc/lvm_fault_handling.txt + +# Main binaries +%defattr(555,root,root,-) +%{_sbindir}/fsadm +%{_sbindir}/lvm +%{_sbindir}/lvmconf +%{_sbindir}/lvmconfig +%{_sbindir}/lvmdump +%if %{enable_lvmetad} +%{_sbindir}/lvmetad +%endif +%if %{enable_lvmpolld} +%{_sbindir}/lvmpolld +%endif + +# Other files +%defattr(444,root,root,-) +%{_sbindir}/lvchange +%{_sbindir}/lvconvert +%{_sbindir}/lvcreate +%{_sbindir}/lvdisplay +%{_sbindir}/lvextend +%{_sbindir}/lvmdiskscan +%{_sbindir}/lvmsadc +%{_sbindir}/lvmsar +%{_sbindir}/lvreduce +%{_sbindir}/lvremove +%{_sbindir}/lvrename +%{_sbindir}/lvresize +%{_sbindir}/lvs +%{_sbindir}/lvscan +%{_sbindir}/pvchange +%{_sbindir}/pvck +%{_sbindir}/pvcreate +%{_sbindir}/pvdisplay +%{_sbindir}/pvmove +%{_sbindir}/pvremove +%{_sbindir}/pvresize +%{_sbindir}/pvs +%{_sbindir}/pvscan +%{_sbindir}/vgcfgbackup +%{_sbindir}/vgcfgrestore +%{_sbindir}/vgchange +%{_sbindir}/vgck +%{_sbindir}/vgconvert +%{_sbindir}/vgcreate +%{_sbindir}/vgdisplay +%{_sbindir}/vgexport +%{_sbindir}/vgextend +%{_sbindir}/vgimport +%{_sbindir}/vgimportclone +%{_sbindir}/vgmerge +%{_sbindir}/vgmknodes +%{_sbindir}/vgreduce +%{_sbindir}/vgremove +%{_sbindir}/vgrename +%{_sbindir}/vgs +%{_sbindir}/vgscan +%{_sbindir}/vgsplit +%{_mandir}/man5/lvm.conf.5.gz +%{_mandir}/man7/lvmcache.7.gz +%{_mandir}/man7/lvmraid.7.gz +%{_mandir}/man7/lvmreport.7.gz +%{_mandir}/man7/lvmthin.7.gz +%{_mandir}/man7/lvmsystemid.7.gz +%{_mandir}/man8/fsadm.8.gz +%{_mandir}/man8/lvchange.8.gz +%{_mandir}/man8/lvconvert.8.gz +%{_mandir}/man8/lvcreate.8.gz +%{_mandir}/man8/lvdisplay.8.gz +%{_mandir}/man8/lvextend.8.gz +%{_mandir}/man8/lvm.8.gz +%{_mandir}/man8/lvm2-activation-generator.8.gz +%{_mandir}/man8/lvm-config.8.gz +%{_mandir}/man8/lvmconfig.8.gz +%{_mandir}/man8/lvm-dumpconfig.8.gz +%{_mandir}/man8/lvmconf.8.gz +%{_mandir}/man8/lvmdiskscan.8.gz +%{_mandir}/man8/lvmdump.8.gz +%{_mandir}/man8/lvm-fullreport.8.gz +%{_mandir}/man8/lvmsadc.8.gz +%{_mandir}/man8/lvmsar.8.gz +%{_mandir}/man8/lvreduce.8.gz +%{_mandir}/man8/lvremove.8.gz +%{_mandir}/man8/lvrename.8.gz +%{_mandir}/man8/lvresize.8.gz +%{_mandir}/man8/lvs.8.gz +%{_mandir}/man8/lvscan.8.gz +%{_mandir}/man8/pvchange.8.gz +%{_mandir}/man8/pvck.8.gz +%{_mandir}/man8/pvcreate.8.gz +%{_mandir}/man8/pvdisplay.8.gz +%{_mandir}/man8/pvmove.8.gz +%{_mandir}/man8/pvremove.8.gz +%{_mandir}/man8/pvresize.8.gz +%{_mandir}/man8/pvs.8.gz +%{_mandir}/man8/pvscan.8.gz +%{_mandir}/man8/vgcfgbackup.8.gz +%{_mandir}/man8/vgcfgrestore.8.gz +%{_mandir}/man8/vgchange.8.gz +%{_mandir}/man8/vgck.8.gz +%{_mandir}/man8/vgconvert.8.gz +%{_mandir}/man8/vgcreate.8.gz +%{_mandir}/man8/vgdisplay.8.gz +%{_mandir}/man8/vgexport.8.gz +%{_mandir}/man8/vgextend.8.gz +%{_mandir}/man8/vgimport.8.gz +%{_mandir}/man8/vgimportclone.8.gz +%{_mandir}/man8/vgmerge.8.gz +%{_mandir}/man8/vgmknodes.8.gz +%{_mandir}/man8/vgreduce.8.gz +%{_mandir}/man8/vgremove.8.gz +%{_mandir}/man8/vgrename.8.gz +%{_mandir}/man8/vgs.8.gz +%{_mandir}/man8/vgscan.8.gz +%{_mandir}/man8/vgsplit.8.gz +%{_udevdir}/11-dm-lvm.rules +%if %{enable_lvmetad} +%{_mandir}/man8/lvmetad.8.gz +%{_udevdir}/69-dm-lvm-metad.rules +%endif +%if %{enable_lvmpolld} +%{_mandir}/man8/lvmpolld.8.gz +%{_mandir}/man8/lvm-lvpoll.8.gz +%endif +%attr(755, -, -) %dir %{_sysconfdir}/lvm +%ghost %{_sysconfdir}/lvm/cache/.cache +%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf +%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvmlocal.conf +%attr(755, -, -) %dir %{_sysconfdir}/lvm/profile +%{_sysconfdir}/lvm/profile/command_profile_template.profile +%{_sysconfdir}/lvm/profile/metadata_profile_template.profile +%{_sysconfdir}/lvm/profile/thin-generic.profile +%{_sysconfdir}/lvm/profile/thin-performance.profile +%{_sysconfdir}/lvm/profile/cache-mq.profile +%{_sysconfdir}/lvm/profile/cache-smq.profile +%{_sysconfdir}/lvm/profile/lvmdbusd.profile +%attr(700, -, -) %dir %{_sysconfdir}/lvm/backup +%attr(700, -, -) %dir %{_sysconfdir}/lvm/cache +%attr(700, -, -) %dir %{_sysconfdir}/lvm/archive +%ghost %attr(700, -, -) %dir %{_default_locking_dir} +%ghost %attr(700, -, -) %dir %{_default_run_dir} +%{_tmpfilesdir}/%{name}.conf +%{_unitdir}/lvm2-monitor.service +%attr(555, -, -) %{_prefix}/lib/systemd/system-generators/lvm2-activation-generator +%if %{enable_lvmetad} +%{_unitdir}/lvm2-lvmetad.socket +%{_unitdir}/lvm2-lvmetad.service +%{_unitdir}/lvm2-pvscan@.service +%endif +%if %{enable_lvmpolld} +%{_unitdir}/lvm2-lvmpolld.socket +%{_unitdir}/lvm2-lvmpolld.service +%endif + +############################################################################## +# Library and Development subpackages +############################################################################## +%package devel +Summary: Development libraries and headers +Group: Development/Libraries +License: LGPLv2 +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: device-mapper-devel = %{epoch}:%{device_mapper_version}-%{release} +Requires: device-mapper-event-devel = %{epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description devel +This package contains files needed to develop applications that use +the lvm2 libraries. + +%files devel +%defattr(444,root,root,-) +%{_libdir}/liblvm2app.so +%{_libdir}/liblvm2cmd.so +%{_libdir}/libdevmapper-event-lvm2.so +%{_includedir}/lvm2app.h +%{_includedir}/lvm2cmd.h +%{_libdir}/pkgconfig/lvm2app.pc + +%package libs +Summary: Shared libraries for lvm2 +License: LGPLv2 +Group: System Environment/Libraries +Requires: device-mapper-event = %{epoch}:%{device_mapper_version}-%{release} + +%description libs +This package contains shared lvm2 libraries for applications. + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%files libs +%defattr(555,root,root,555) +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%{_libdir}/liblvm2app.so.* +%{_libdir}/liblvm2cmd.so.* +%{_libdir}/libdevmapper-event-lvm2.so.* +%dir %{_libdir}/device-mapper +%{_libdir}/device-mapper/libdevmapper-event-lvm2mirror.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2snapshot.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2raid.so +%{_libdir}/libdevmapper-event-lvm2mirror.so +%{_libdir}/libdevmapper-event-lvm2snapshot.so +%{_libdir}/libdevmapper-event-lvm2raid.so + +%if %{enable_thin} +%{_libdir}/libdevmapper-event-lvm2thin.so +%{_libdir}/device-mapper/libdevmapper-event-lvm2thin.so +%endif + +%{_libdir}/device-mapper/libdevmapper-event-lvm2vdo.so +%{_libdir}/libdevmapper-event-lvm2vdo.so + + +%if %{enable_python} + +%package python-libs +Summary: Python module to access LVM +License: LGPLv2 +Group: Development/Libraries +Provides: python-lvm = %{epoch}:%{version}-%{release} +Obsoletes: python-lvm < 2.02.98-3 +Requires: %{name}-libs = %{epoch}:%{version}-%{release} + +%description python-libs +Python module to allow the creation and use of LVM +logical volumes, physical volumes, and volume groups. + +%files python-libs +%{python_sitearch}/lvm* + +%endif + +############################################################################## +# LVM locking daemon +############################################################################## +%if %{enable_lockd_dlm} || %{enable_lockd_sanlock} +%package lockd +Summary: LVM locking daemon +Group: System Environment/Base +Requires: lvm2 = %{epoch}:%{version}-%{release} +%if %{enable_lockd_sanlock} +Requires: sanlock-lib >= %{sanlock_version} +%endif +%if %{enable_lockd_dlm} +Requires: dlm-lib >= %{dlm_version} +%endif +Requires(post): systemd-units >= %{systemd_version} +Requires(preun): systemd-units >= %{systemd_version} +Requires(postun): systemd-units >= %{systemd_version} + +%description lockd + +LVM commands use lvmlockd to coordinate access to shared storage. + +%post lockd +%systemd_post lvm2-lvmlockd.service lvm2-lvmlocking.service + +%preun lockd +%systemd_preun lvm2-lvmlockd.service lvm2-lvmlocking.service + +%postun lockd +%systemd_postun lvm2-lvmlockd.service lvm2-lvmlocking.service + +%files lockd +%defattr(444,root,root,-) +%%attr(555, -, -) %{_sbindir}/lvmlockd +%%attr(555, -, -) %{_sbindir}/lvmlockctl +%{_mandir}/man8/lvmlockd.8.gz +%{_mandir}/man8/lvmlockctl.8.gz +%{_unitdir}/lvm2-lvmlockd.service +%{_unitdir}/lvm2-lvmlocking.service + +%endif + +############################################################################## +# Cluster subpackage +# The 'clvm' OCF script to manage clvmd instance is part of resource-agents. +############################################################################## +%if %{enable_cluster} + +%package cluster +Summary: Cluster extensions for userland logical volume management tools +License: GPLv2 +Group: System Environment/Base +Requires: lvm2 = %{epoch}:%{version}-%{release} +Requires(preun): device-mapper = %{epoch}:%{device_mapper_version} +Requires(preun): lvm2 >= 2.02 +Requires: corosync >= %{corosync_version} +Requires: dlm >= %{dlm_version} +Requires: resource-agents >= %{resource_agents_version} + +%description cluster + +Extensions to LVM2 to support clusters. + +%post cluster +if [ -e %{_default_pid_dir}/clvmd.pid ]; then + /usr/sbin/clvmd -S || echo "Failed to restart clvmd daemon. Please, try manual restart." +fi + +%preun cluster +if [ "$1" = "0" ]; then + /sbin/lvmconf --disable-cluster +fi + +%files cluster +%defattr(555,root,root,-) +%{_sbindir}/clvmd +%attr(444, -, -) %{_mandir}/man8/clvmd.8.gz + +############################################################################## +# Cluster-standalone subpackage +############################################################################## +%package cluster-standalone +Summary: Additional files to support clustered LVM2 in standalone mode +License: GPLv2 +Group: System Environment/Base +Requires: lvm2-cluster = %{epoch}:%{version}-%{release} + +%description cluster-standalone + +Additional files needed to run clustered LVM2 daemon and clustered volume +activation in standalone mode as services without cluster resource manager +involvement (e.g. pacemaker). + +%post cluster-standalone +%systemd_post lvm2-clvmd.service lvm2-cluster-activation.service + +%preun cluster-standalone +%systemd_preun lvm2-clvmd.service lvm2-cluster-activation.service + +%postun cluster-standalone +%systemd_postun lvm2-clvmd.service lvm2-cluster-activation.service + +%files cluster-standalone +%defattr(555,root,root,-) +%{_prefix}/lib/systemd/lvm2-cluster-activation +%defattr(444,root,root,-) +%{_unitdir}/lvm2-clvmd.service +%{_unitdir}/lvm2-cluster-activation.service + +%endif + +############################################################################### +# Cluster mirror subpackage +# The 'clvm' OCF script to manage cmirrord instance is part of resource-agents. +############################################################################### +%if %{enable_cluster} +%if %{enable_cmirror} + +%package -n cmirror +Summary: Daemon for device-mapper-based clustered mirrors +Group: System Environment/Base +Requires: corosync >= %{corosync_version} +Requires: device-mapper = %{epoch}:%{device_mapper_version}-%{release} +Requires: resource-agents >= %{resource_agents_version} + +%description -n cmirror +Daemon providing device-mapper-based mirrors in a shared-storage cluster. + +%files -n cmirror +%defattr(555,root,root,-) +%{_sbindir}/cmirrord +%attr(444, -, -) %{_mandir}/man8/cmirrord.8.gz + +############################################################################## +# Cmirror-standalone subpackage +############################################################################## +%package -n cmirror-standalone +Summary: Additional files to support device-mapper-based clustered mirrors in standalone mode +License: GPLv2 +Group: System Environment/Base +Requires: cmirror >= %{epoch}:%{version}-%{release} + +%description -n cmirror-standalone + +Additional files needed to run daemon for device-mapper-based clustered +mirrors in standalone mode as a service without cluster resource manager +involvement (e.g. pacemaker). + +%post -n cmirror-standalone +%systemd_post lvm2-cmirrord.service + +%preun -n cmirror-standalone +%systemd_preun lvm2-cmirrord.service + +%postun -n cmirror-standalone +%systemd_postun lvm2-cmirrord.service + +%files -n cmirror-standalone +%defattr(444,root,root,-) +%{_unitdir}/lvm2-cmirrord.service + +%endif +%endif + +############################################################################## +# Legacy SysV init subpackage +############################################################################## +%package sysvinit +Summary: SysV style init script for LVM2. +Group: System Environment/Base +Requires: %{name} = %{epoch}:%{version}-%{release} +Requires: initscripts + +%description sysvinit +SysV style init script for LVM2. It needs to be installed only if systemd +is not used as the system init process. + +%files sysvinit +%defattr(555,root,root,-) +%{_sysconfdir}/rc.d/init.d/blk-availability +%{_sysconfdir}/rc.d/init.d/lvm2-monitor +%if %{enable_cluster} +%{_sysconfdir}/rc.d/init.d/clvmd +%if %{enable_cmirror} +%{_sysconfdir}/rc.d/init.d/cmirrord +%endif +%endif +%if %{enable_lvmetad} +%{_sysconfdir}/rc.d/init.d/lvm2-lvmetad +%endif +%if %{enable_lvmpolld} +%{_sysconfdir}/rc.d/init.d/lvm2-lvmpolld +%endif + +############################################################################## +# Device-mapper subpackages +############################################################################## +%package -n device-mapper +Summary: Device mapper utility +Version: %{device_mapper_version} +License: GPLv2 +Group: System Environment/Base +URL: http://sources.redhat.com/dm +Requires: device-mapper-libs = %{epoch}:%{device_mapper_version}-%{release} +Requires: util-linux >= %{util_linux_version} +Requires: systemd >= %{systemd_version} +# We need dracut to install required udev rules if udev_sync +# feature is turned on so we don't lose required notifications. +Conflicts: dracut < %{dracut_version} + +%description -n device-mapper +This package contains the supporting userspace utility, dmsetup, +for the kernel device-mapper. + +%post -n device-mapper +%systemd_post blk-availability.service + +%preun -n device-mapper +%systemd_preun blk-availability.service + +%files -n device-mapper +%defattr(-,root,root,-) +%doc COPYING COPYING.LIB WHATS_NEW_DM VERSION_DM README INSTALL +%doc udev/12-dm-permissions.rules +%defattr(444,root,root,-) +%attr(555, -, -) %{_sbindir}/dmsetup +%attr(555, -, -) %{_sbindir}/blkdeactivate +# dmstats is a symlink +%{_sbindir}/dmstats +%{_mandir}/man8/dmsetup.8.gz +%{_mandir}/man8/dmstats.8.gz +%{_mandir}/man8/blkdeactivate.8.gz +%if %{enable_dmfilemapd} +%attr(555, -, -) %{_sbindir}/dmfilemapd +%{_mandir}/man8/dmfilemapd.8.gz +%endif +%{_udevdir}/10-dm.rules +%{_udevdir}/13-dm-disk.rules +%{_udevdir}/95-dm-notify.rules +%{_unitdir}/blk-availability.service + +%package -n device-mapper-devel +Summary: Development libraries and headers for device-mapper +Version: %{device_mapper_version} +License: LGPLv2 +Group: Development/Libraries +Requires: device-mapper = %{epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description -n device-mapper-devel +This package contains files needed to develop applications that use +the device-mapper libraries. + +%files -n device-mapper-devel +%defattr(444,root,root,-) +%{_libdir}/libdevmapper.so +%{_includedir}/libdevmapper.h +%{_libdir}/pkgconfig/devmapper.pc + +%package -n device-mapper-libs +Summary: Device-mapper shared library +Version: %{device_mapper_version} +License: LGPLv2 +Group: System Environment/Libraries +Requires: device-mapper = %{epoch}:%{device_mapper_version}-%{release} + +%description -n device-mapper-libs +This package contains the device-mapper shared library, libdevmapper. + +%post -n device-mapper-libs -p /sbin/ldconfig + +%postun -n device-mapper-libs -p /sbin/ldconfig + +%files -n device-mapper-libs +%defattr(555,root,root,555) +%{!?_licensedir:%global license %%doc} +%license COPYING COPYING.LIB +%{_libdir}/libdevmapper.so.* + +%package -n device-mapper-event +Summary: Device-mapper event daemon +Group: System Environment/Base +Version: %{device_mapper_version} +# Older lvm2 versions had incorrect dependency on device-mapper-event +# package where lvm2-libs had "Requires: device-mapper-event >=" +# instead of "Requires: device-mapper-event =". This was fixed in +# lvm2-2.02.111-1 and later. +Conflicts: lvm2-libs < 7:2.02.111 +Requires: device-mapper = %{epoch}:%{device_mapper_version}-%{release} +Requires: device-mapper-event-libs = %{epoch}:%{device_mapper_version}-%{release} +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +%description -n device-mapper-event +This package contains the dmeventd daemon for monitoring the state +of device-mapper devices. + +%post -n device-mapper-event +%systemd_post dm-event.socket +# dm-event.socket is always enabled and started and ready to serve if dmeventd is used +# replace direct systemctl calls with systemd rpm macro once this is provided in the macro: +# http://cgit.freedesktop.org/systemd/systemd/commit/?id=57ab2eabb8f92fad5239c7d4492e9c6e23ee0678 +systemctl enable dm-event.socket +systemctl start dm-event.socket + +%preun -n device-mapper-event +%systemd_preun dm-event.service dm-event.socket + +%posttrans -n device-mapper-event +if [ -e %{_default_pid_dir}/dmeventd.pid ]; then + %{_sbindir}/dmeventd -R || echo "Failed to restart dmeventd daemon. Please, try manual restart." +fi + +%files -n device-mapper-event +%defattr(444,root,root,-) +%attr(555, -, -) %{_sbindir}/dmeventd +%{_mandir}/man8/dmeventd.8.gz +%{_unitdir}/dm-event.socket +%{_unitdir}/dm-event.service + +%package -n device-mapper-event-libs +Summary: Device-mapper event daemon shared library +Version: %{device_mapper_version} +License: LGPLv2 +Group: System Environment/Libraries + +%description -n device-mapper-event-libs +This package contains the device-mapper event daemon shared library, +libdevmapper-event. + +%post -n device-mapper-event-libs -p /sbin/ldconfig + +%postun -n device-mapper-event-libs -p /sbin/ldconfig + +%files -n device-mapper-event-libs +%defattr(555,root,root,555) +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%{_libdir}/libdevmapper-event.so.* + +%package -n device-mapper-event-devel +Summary: Development libraries and headers for the device-mapper event daemon +Version: %{device_mapper_version} +License: LGPLv2 +Group: Development/Libraries +Requires: device-mapper-event = %{epoch}:%{device_mapper_version}-%{release} +Requires: pkgconfig + +%description -n device-mapper-event-devel +This package contains files needed to develop applications that use +the device-mapper event library. + +%files -n device-mapper-event-devel +%defattr(444,root,root,-) +%{_libdir}/libdevmapper-event.so +%{_includedir}/libdevmapper-event.h +%{_libdir}/pkgconfig/devmapper-event.pc + +%if %{enable_boom} +############################################################################## +# boom subpackages +############################################################################## +%package -n %{boom_pkgname} +Summary: %{boom_summary} +Version: %{boom_version} +Release: %{boom_release}%{?dist}%{?scratch} +License: GPLv2 +Group: System Environment/Base +BuildArch: noarch +%{?python_provide:%python_provide python2-boom} +Requires: grub2 + +%description -n %{boom_pkgname} +Boom is a boot manager for Linux systems using boot loaders that support +the BootLoader Specification for boot entry configuration. + +Boom requires a BLS compatible boot loader to function: either the +systemd-boot project, or Grub2 with the bls patch (Red Hat Grub2 builds +include this support in both Red Hat Enterprise Linux 7 and Fedora). + +This package provides the python2 version of boom. + +%files -n %{boom_pkgname} +%license COPYING +%{_mandir}/man8/boom.* +%{python2_sitelib}/boom* +%{_bindir}/boom +/etc/grub.d/42_boom +%config(noreplace) /etc/default/boom +/boot/* +%doc ../%{boom_dir}/README.md +%doc ../%{boom_dir}/examples/ +%doc ../%{boom_dir}/tests/ +%endif + +%changelog +* Tue Sep 24 2019 Marian Csontos - 7:2.02.186-2 +- Prevent creating VGs with PVs with different logical block sizes. +- Pvmove runs in exlusively activating mode for exclusively active LVs. +- Activate thin-pool layered volume as 'read-only' device. +- Enhance validation for thin and cache pool conversion and swapping. + +* Tue Aug 27 2019 Marian Csontos - 7:2.02.186-1 +- Improve removal of cached devices. +- Synchronize with udev when dropping snapshot. +- Add missing device synchronization point before removing pvmove node. +- Correctly set read_ahead for LVs when pvmove is finished. +- Fix metadata writes from corrupting with large physical block size. + +* Fri Jun 21 2019 Marian Csontos - 7:2.02.185-2 +- Fix cluster conversions from linear to mirror. +- Report no_discard_passdown for cache LVs with lvs -o+kernel_discards. +- Prevent shared active mirror LVs with lvmlockd. +- Parsing of cache status understand no_discard_passdown. + +* Mon May 13 2019 Marian Csontos - 7:2.02.185-1 +- Fix change of monitoring in clustered volumes. +- Improve -lXXX%VG modifier which improves cache segment estimation. +- Add synchronization with udev before removing cached devices. +- Fix missing growth of _pmspare volume when extending _tmeta volume. +- Automatically grow thin metadata, when thin data gets too big. + +* Mon Apr 29 2019 Marian Csontos - 7:2.02.184-3 +- Fix shutdown of deamons. + +* Wed Apr 17 2019 Marian Csontos - 7:2.02.184-2 +- Add support for vgsplit with cached devices. +- Fix conversion of cache pool to RAID1 (2.02.184). +- Fix signal delivery checking race in libdaemon (lvmetad). +- Add missing Before=shutdown.target to LVM2 services to fix shutdown ordering. + +* Fri Mar 22 2019 Marian Csontos - 7:2.02.184-1 +- See WHATS_NEW and WHATS_NEW_DM in the documentation directory for details. + +* Mon Mar 18 2019 Marian Csontos - 7:2.02.180-10.el7_6.5 +- boom: Bump release. + +* Mon Mar 18 2019 Marian Csontos - 7:2.02.180-10.el7_6.4 +- Apply obtain_device_list_from_udev to all libudev calls. + +* Mon Dec 17 2018 Marian Csontos - 7:2.02.180-10.el7_6.3 +- Fix component detection for MD RAID version 1.0 and 0.90. +- Use sync io if async io_setup fails, or when use_aio=0 is set in config. +- Fix dmstats report printing no output. + +* Wed Oct 31 2018 Marian Csontos - 7:2.02.180-10.el7_6.2 +- Fix possible write beyond metadata area. + +* Wed Oct 10 2018 Marian Csontos - 7:2.02.180-10.el7_6.1 +- Fix clustered mirror repair. + +* Mon Sep 10 2018 Marian Csontos - 7:2.02.180-8 +- Fix lvconvert striped/raid0/raid0_meta to raid6 regression. + +* Wed Sep 05 2018 Marian Csontos - 7:2.02.180-7 +- Fix ordering of lvm2 activation and rbdmap services. +- Fix to avoid locking collisions when monitoring thin-pools. + +* Fri Aug 24 2018 Marian Csontos - 7:2.02.180-6 +- Fix direct RAID0 to striped conversion. + +* Tue Aug 21 2018 Marian Csontos - 7:2.02.180-5 +- Fix direct RAID0 to striped conversion. + +* Tue Aug 21 2018 Marian Csontos - 7:2.02.180-3 +- Fix lvconvert --splitmirror for mirror type (2.02.178). +- Do not pair cache policy and cache metadata format. +- Fix mirrors honoring read_only_volume_list. +- Fix vgcreate with sanlock when PVs are created automatically. + +* Tue Jul 31 2018 Marian Csontos - 7:2.02.180-2 +- Add vdo plugin for monitoring VDO devices. +- Reject conversions on raid1 LVs with split tracked SubLVs. +- Reject conversions on raid1 split tracked SubLVs. +- Fix dmstats list failing when no regions exist. +- Reject conversions of LVs under snapshot. +- Limit suggested options on incorrect option for lvconvert subcommand. + +* Fri Jul 20 2018 Marian Csontos - 7:2.02.180-1 +- Never send any discard ioctl with test mode. +- Fix thin-pool alloc which needs same PV for data and metadata. +- Enhance vgcfgrestore to check for active LVs in restored VG. +- Cache can use metadata format 2 with cleaner policy. +- Fix lvmetad hanging on shutdown. +- Fix check if resized PV can also fit metadata area. + +* Tue Jun 26 2018 Marian Csontos - 7:2.02.179-4 +- Rebuild man pages and config file (make generate.) + +* Tue Jun 26 2018 Marian Csontos - 7:2.02.179-3 +- Add convenient conversions between stripe and linear. +- Fix snapshot hanging on shutdown. +- Fix internal error in lvs while pvmove in progress. +- Fix more coverity issues. +- Improve message for pvresize. + +* Thu Jun 21 2018 Marian Csontos - 7:2.02.179-2 +- Fix issue caused by udev considering device open in RW mode a change. +- Fix leaks and buffer overflow. +- boom: Update to new minor release. + +* Mon Jun 18 2018 Marian Csontos - 7:2.02.179-1 +- Fixing known problems with cache and lvmlockd. + +* Thu Jun 14 2018 Marian Csontos - 7:2.02.178-1 +- Rework disk scanning and when it is used. +- Add new io layer using libaio for faster scanning. +- Support activation of component LVs in read-only mode. +- Avoid non-exclusive activation of exclusive segment types. +- Restore pvmove support for clusterwide active volumes (2.02.177). +- Add prioritized_section() to restore cookie boundaries (2.02.177). +- Again accept striped LV as COW LV with lvconvert -s (2.02.169). +- Restore usability of thin LV to be again external origin for another thin (2.02.169). +- See WHATS_NEW and WHATS_NEW_DM in the documentation directory for more. + +* Fri Feb 16 2018 Marian Csontos - 7:2.02.177-4 +- pvmove enhance accepted states of active LVs. +- boom: Remove debug output. + +* Wed Feb 14 2018 Marian Csontos - 7:2.02.177-3 +- boom: Handle LVs passed in --root-device. +- boom: Allow /dev/VG/LV notation for --root-lv. +- boom: Detection of invalid root devices. +- boom: Support long options without dash separator. +- Add deprecation warning for mirrored mirror log. + +* Wed Feb 07 2018 Marian Csontos - 7:2.02.177-2 +- boom: Better error handling. +- boom: Warn user when grub2 integration is missing. +- Reenable clustered pvmove. + +* Tue Jan 23 2018 Marian Csontos - 7:2.02.177-1 +- boom: Add missing profiles +- Avoid non-exclusive activation of exclusive segment types. +- Fix trimming sibling PVs when doing a pvmove of raid subLVs. +- Preserve exclusive activation during thin snaphost merge. +- Check array boundaries in allocation tag processing. +- When writing metadata, consistently skip mdas marked as failed. +- Reduce checks for active LVs in vgchange before background polling. +- Ensure _node_send_message always uses clean status of thin pool. +- Activation tree of thin pool skips duplicated check of pool status. + +* Wed Dec 06 2017 Marian Csontos - 7:2.02.176-5 +- boom: Update man page. +- boom: Allow users to disable grub2 configuration. +- boom: Do not add snapshots submenu unless entries exist. +- boom: Use fdatasync() for profile and entry files. +- Fix lvmlockd to use pool lock when accessing _tmeta volume. +- Report expected sanlock_convert errors only when retries fail. +- Avoid blocking in sanlock_convert on SH to EX lock conversion. +- Deactivate missing raid LV legs (_rimage_X-missing_Y_Z) on decativation. +- Allow extending of raid LVs created with --nosync after a failed repair. +- Merge adjacent segments when pvmove is finished. +- Ensure very large numbers used as arguments are not casted to lower values. +- Enhance reading and validation of options stripes and stripes_size. +- Fix printing of default stripe size when user is not using stripes. +- Activation code for pvmove automatically discovers holding LVs for resume. +- Make a pvmove LV locking holder. +- Enhance activation code to automatically suspend pvmove participants. +- Prevent conversion of thin volumes to snapshot origin when lvmlockd is used. +- Correct the steps to change lock type in lvmlockd man page. +- Retry lock acquisition on recognized sanlock errors. +- Fix lock manager error codes in lvmlockd. +- Check raid reshape flags in vg_validate(). +- Add support for pvmove of cache and snapshot origins. +- Ehnance pvmove locking. +- Deactivate activated LVs on error path when pvmove activation fails. + +* Wed Nov 15 2017 Marian Csontos - 7:2.02.176-4 +- Avoid importing persistent filter in vgscan/pvscan/vgrename. +- Fix memleak of string buffer when vgcfgbackup runs in secure mode. +- Do not print error when clvmd cannot find running clvmd. +- Prevent start of new merge of snapshot if origin is already being merged. +- Suppress integrity encryption keys in 'table' output unless --showkeys supplied. +- Fix offered type for raid6_n_6 to raid5 conversion (raid5_n). +- Deactivate sub LVs when removing unused cache-pool. +- Do not take backup with suspended devices. +- Avoid RAID4 activation on incompatible kernels under all circumstances. +- Reject conversion request to striped/raid0 on 2-legged raid4/5. + +* Thu Nov 09 2017 Bryn M. Reeves - 7:2.02.176-3 +- Disable boom package build on s390x. + +* Fri Nov 03 2017 Marian Csontos - 7:2.02.176-2 +- Add "boom" boot manager. + +* Fri Nov 03 2017 Marian Csontos - 7:2.02.176-1 +- Fix segfault in lvm_pv_remove in liblvm. (2.02.173) +- Do not allow storing VG metadata with LV without any segment. +- Fix printed message when thin snapshot was already merged. +- Remove created spare LV when creation of thin-pool failed. +- Avoid reading ignored metadata when MDA gets used again. +- Fix detection of moved PVs in vgsplit. (2.02.175) +- Ignore --stripes/--stripesize on RAID takeover +- Disallow creation of snapshot of mirror/raid subLV (was never supported). +- Keep Install section only in *.socket systemd units. +- Improve used paths for generated systemd units and init shells. + +* Wed Oct 25 2017 Marian Csontos - 7:2.02.175-3 +- Fix regression in more advanced vgname extraction in lvconvert (2.02.169). +- Allow lvcreate to be used for caching of _tdata LV. +- Avoid internal error when resizing cache type _tdata LV (not yet supported). +- Show original converted names when lvconverting LV to pool volume. +- Distinguish between device not found and excluded by filter. +- Monitor external origin LVs. +- Remove unused replicator code, including configure --with-replicators. + +* Fri Oct 13 2017 Marian Csontos - 7:2.02.175-2 +- Allow lvcreate --type mirror to work with 100%%FREE. +- Improve selection of resource name for complex volume activation lock. +- Avoid cutting first character of resource name for activation lock. +- Support for encrypted devices in fsadm. +- Improve thin pool overprovisioning and repair warning messages. +- Fix incorrect adjustment of region size on striped RaidLVs. + +* Mon Oct 09 2017 Marian Csontos - 7:2.02.175-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed Jun 28 2017 Marian Csontos - 7:2.02.171-8 +- Fix reusing of dm_task structure for status reading (used by dmeventd). + +* Thu Jun 22 2017 Marian Csontos - 7:2.02.171-7 +- Fix a segfault in RAID. + +* Wed Jun 21 2017 Marian Csontos - 7:2.02.171-6 +- Reenable conversion of data and metadata thin-pool volumes to raid. +- Improve handling of RAID status in lvs. +- Disable RAID reshape/take-over in a cluster or when snapshot exists. + +* Wed Jun 14 2017 Marian Csontos - 7:2.02.171-5 +- Improve lvcreate --cachepool arg validation. +- Limit maximal size of thin-pool for specific chunk size. +- Accept truncated files in calls to dm_stats_update_regions_from_fd(). + +* Wed Jun 07 2017 Marian Csontos - 7:2.02.171-4 +- Converting linear to raid1 using "recover" not "resync". +- Print a warning about in-use PVs with no VG using them. +- Disable automatic clearing of PVs that look like in-use orphans. + +* Wed Jun 07 2017 Marian Csontos - 7:2.02.171-4 +- Converting linear to raid1 using "recover" not "resync". +- Print a warning about in-use PVs with no VG using them. +- Disable automatic clearing of PVs that look like in-use orphans. + +* Wed May 31 2017 Marian Csontos - 7:2.02.171-3 +- Cache format2 flag is now using segment name type field compatible with + previous versions. + +* Wed May 24 2017 Marian Csontos - 7:2.02.171-2 +- Stop using '--yes' mode when fsadm runs without terminal. +- Extend validation of filesystems resized by fsadm. +- Enhance lvconvert automatic settings of possible (raid) LV types. +- Allow lvchange to change properties on a thin pool data sub LV. +- Fix lvcreate extent percentage calculation for mirrors. +- Don't reinstate still-missing devices when correcting inconsistent metadata. +- Properly handle subshell return codes in fsadm. +- Disallow cachepool creation with policy cleaner and mode writeback. + +* Wed May 03 2017 Marian Csontos - 7:2.02.171-1 +- Fix dmstats and dmfilemapd permissions. +- Fix memory warnings by using mempools for command definition processing. +- Fix running commands from a script file. +- Adjust pvresize/pvcreate messages and prompt if underlying device size + differs. +- Preserve region size on raid1 image count changes. +- Handle insufficient space on RAID takeover. +- Raise mirror/raid default regionsize to 2MiB. + +* Thu Apr 13 2017 Marian Csontos - 7:2.02.170-2 +- Fix RPM build - missing upstrem and sources. + +* Thu Apr 13 2017 Marian Csontos - 7:2.02.170-1 +- Introduce global/fsadm_executable to make fsadm path configurable. +- Look for limited thin pool metadata size when using 16G metadata. +- Fix missing lvmlockd LV locks in lvchange and lvconvert. +- Allow valid lvconvert --regionsize change. +- Handle insufficient PVs on lvconvert takeover. +- Fix SIGINT blocking to prevent corrupted metadata. +- Fix systemd unit existence check for lvmconf --services --startstopservices. + +* Wed Mar 29 2017 Marian Csontos - 7:2.02.169-3 +- Fix dmfilemapd's Makefile. +- Update dependencies. + +* Wed Mar 29 2017 Marian Csontos - 7:2.02.169-2 +- Enable dmfilemapd. + +* Tue Mar 28 2017 Marian Csontos - 7:2.02.169-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Thu Mar 23 2017 Alasdair Kergon - 7:2.02.166-2 +- Add clustered ppc64le support to build. + +* Thu Feb 09 2017 Peter Rajnoha - 7:2.02.166-1.el7_3.3 +- Fix segfault in lvmetad from missing NULL in daemon_reply_simple. + +* Wed Nov 16 2016 Peter Rajnoha - 7:2.02.166-1.el7_3.2 +- Prevent raid4 creation/conversion on non-supporting kernels +- Add direct striped -> raid4 conversion +- Fix raid4 parity image pair position on conversions from striped/raid0* + +* Wed Oct 12 2016 Peter Rajnoha - 7:2.02.166-1.el7_3.1 +- Fix lvconvert to allow repair for cache raid LVs. +- Fix time when dmeventd is reloaded on package upgrade to start using new code. +- Fix libdm versioning for dm_tree_node_size_changed symbol. + +* Wed Sep 28 2016 Peter Rajnoha - 7:2.02.166-1 +- Disable lvconvert of thin pool to raid while active. +- Use dm_config_parse_without_dup_node_check() to speedup metadata reading. +- Fix lvm2-activation-generator to read all LVM2 config sources. (2.02.155) +- Fix man entry for dmsetup status. +- Introduce new dm_config_parse_without_dup_node_check(). + +* Thu Sep 22 2016 Peter Rajnoha - 7:2.02.165-4 +- Revert lvconvert --repair fix for RAID LVs. + +* Wed Sep 21 2016 Peter Rajnoha - 7:2.02.165-3 +- Fix lvchange --discard|--zero for active thin-pool. +- Fix lvconvert --repair regression for RAID LVs. +- Always specify snapshot cow LV for monitoring not internal LV. (2.02.165) +- Ensure memory allocated internally for --filemap histogram bounds are freed. +- Fix missing display of last created dmstats file map. +- Use --alloc normal for mirror logs even if the mimages were stricter. +- Fix reported origin lv field for cache volumes. (2.02.133) +- Fix lock-holder device for thin pool with inactive thin volumes. +- Enforce 4MiB or 25% metadata free space for thin pool operations. +- Fix lvmetad metadata validation when rescanning VG. + +* Wed Sep 14 2016 Peter Rajnoha - 7:2.02.165-2 +- Fix possible NULL pointer dereference when checking for monitoring. +- Add lvmreport(7) man page. +- Report 0% as dirty (copy%) for cache without any used block. +- Fix lvm2api reporting of cache data and metadata percent. +- Restore reporting of metadata usage for cache volumes (2.02.155). + +* Wed Sep 07 2016 Peter Rajnoha - 7:2.02.165-1 +- Support raid scrubbing on cache origin LV. +- Add lvmraid(7) man page. +- Use udev db to check for mpath components before running pvscan for lvmetad. +- Improve explanation of udev fallback in libdevmapper.h. + +* Mon Sep 05 2016 Peter Rajnoha - 7:2.02.164-5 +- Use udev db to check for mpath components before running pvscan for lvmetad. +- Use devices/allow_changes_with_duplicate_pvs=1 by default. + +* Wed Aug 31 2016 Peter Rajnoha - 7:2.02.164-4 +- Use lsblk -s and lsblk -O in lvmdump only if these options are supported. +- Fix typo in report/columns_as_rows config option name recognition (2.02.99). +- Do not monitor cache-pool metadata when LV is just being cleared. +- Add allocation/cache_pool_max_chunks to prevent misuse of cache target. +- Fix number of stripes shown in lvcreate raid10 message when too many. +- Give error not segfault in lvconvert --splitmirrors when PV lies outside LV. +- Avoid PV tags when checking allocation against parallel PVs. + +* Wed Aug 24 2016 Peter Rajnoha - 7:2.02.164-3 +- Disallow segtype and mirror conversions of raid10 volumes. +- Fix dmeventd unmonitoring when segment type (and dso) changes. +- Don't allow lvconvert --repair on raid0 devices or attempt to monitor them. +- No longer adjust incorrect number of raid stripes supplied to lvcreate. +- Move lcm and gcd to lib/misc. +- Suppress some unnecessary --stripesize parameter warnings. +- Fix 'pvmove -n name ...' to prohibit collocation of RAID SubLVs + +* Tue Aug 16 2016 Peter Rajnoha - 7:2.02.164-2 +- Suppress some unnecessary --stripesize parameter warnings. +- Fix selection of PVs when allocating raid0_meta. +- Specify max stripes for raid LV types: raid0:64; 1:10; 4,5:63; 6:62; 10:32. +- Avoid double suffix when naming _rmeta LV paired with _rimage LV. + +* Wed Aug 10 2016 Peter Rajnoha - 7:2.02.163-1 +- Add profile for lvmdbusd which uses lvm shell json report output. +- Restrict in-command modification of some parms in lvm shell. +- Apply LVM_COMMAND_PROFILE early for lvm shell. +- Refactor reporting so lvm shell log report collects whole of cmd execution. +- Support LVM_*_FD envvars to redirect output to file descriptors. +- Limit use of --corelog and --mirrorlog to mirrors in lvconvert. +- Reject --nosync option for RAID6 LVs in lvcreate. +- Do not refresh whole cmd context if profile dropped after processing LVM cmd. +- Support straightforward lvconvert between striped and raid4 LVs. +- Support straightforward lvconvert between raid1 and mirror LVs. +- Report supported conversions when asked for unsupported raid lvconvert. +- Add "--rebuild PV" option to lvchange to allow for PV selective rebuilds. +- Preserve existing mirror region size when using --repair. +- Forbid stripe parameters with lvconvert --repair. +- Unify stripe size validation into get_stripe_params to catch missing cases. +- Further lvconvert validation logic refactoring. +- Add "lvm fullreport" man page. +- Add dm_report_destroy_rows/dm_report_group_output_and_pop_all for lvm shell. +- Adjust group handling and json production for lvm shell. + +* Fri Jul 29 2016 Peter Rajnoha - 7:2.02.162-1 +- Extend vg_validate also to check raid configurations thoroughly. +- Support lvconvert -Zn also when doing full cache pool conversion. +- Suppress not zeroing warn when converting to thin LV for non-zeroing tpool. +- Fix automatic updates of PV extension headers to newest version. +- Improve lvconvert --trackchanges validation to require --splitmirrors 1. +- Add note about lastlog built-in command to lvm man page. +- Fix unrecognised segtype flag message. +- lvconvert not clears cache pool metadata ONLY with -Zn. +- Add allocation/raid_stripe_all_devices to reinstate previous behaviour. +- Create raid stripes across fixed small numbers of PVs instead of all PVs. +- Disallow lvconvert --replace with raid0* LVs. +- Fix some lvmetad changed VG metadata notifications that sent uncommitted data. +- Fix json reporting to escape '"' character that may appear in reported string. + +* Thu Jul 28 2016 Peter Rajnoha - 7:2.02.161-3 +- Improve lvmlockd message for lock-start. +- Improve lvmlockd activation locking error message. +- Improve lvmlockd error message about missing global lock. +- Allow lvconvert with implied cache pool. +- Fix vgsplit with external origin LV. (2.02.161) + +* Wed Jul 20 2016 Peter Rajnoha - 7:2.02.161-2 +- Fix output redirection while executing blkdeactivate -m disablequeueing. + +* Wed Jul 20 2016 Peter Rajnoha - 7:2.02.161-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed Jul 06 2016 Alasdair Kergon - 7:2.02.160-1 +- Minor fixes from coverity. +- vgimportclone is now a symlink. + +* Wed Jul 06 2016 Alasdair Kergon - 7:2.02.159-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Mon Jun 13 2016 Peter Rajnoha - 7:2.02.156-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed May 04 2016 Peter Rajnoha - 7:2.02.152-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed Oct 14 2015 Peter Rajnoha - 7:2.02.130-5 +- Fixup /etc/lvm/archive ownership. + +* Wed Oct 14 2015 Peter Rajnoha - 7:2.02.130-4 +- Reinstate /etc/lvm dir content permissions after change in defaults. + +* Wed Oct 14 2015 Peter Rajnoha - 7:2.02.130-3 +- Enforce writethrough mode for cleaner policy. +- Check for enough space in thin-pool in command before creating new thin. + +* Tue Sep 15 2015 Peter Rajnoha - 7:2.02.130-2 +- Fix vgimportclone cache_dir path name (2.02.115). +- Disallow usage of --stripe and --stripesize when creating cache pool. +- Swapping of LV identifiers handles more complex LVs. +- Fix VG metadata comparison failure while scanning the VG for lvmetad. +- Ignore persistent cache if configuration changed. (2.02.127) +- Do not check for full thin pool when activating without messages (1.02.107). + +* Wed Sep 09 2015 Peter Rajnoha - 7:2.02.130-1 +- Fix use of uninitialized device status if reading outdated .cache record. +- Restore support for --monitor option in lvcreate (2.02.112). +- Read thin-pool data and metadata percent without flush. +- Detect blocked thin-pool and avoid scanning their thin volumes. +- Check if dm device is usable before checking its size (2.02.116). +- Extend parsing of cache_check version in configure. +- Make lvpoll error messages visible in lvmpolld's stderr and in syslog. +- Add 'make install_full_man' to install all man pages regardless of config. +- Parse thin-pool status with one single routine internally. +- Add --histogram to select default histogram fields for list and report. +- Add report fields for displaying latency histogram configuration and data. +- Add dmstats --bounds to specify histogram boundaries for a new region. +- Add dm_histogram_to_string() to format histogram data in string form. +- Add public methods to libdm to access numerical histogram config and data. +- Parse and store histogram data in dm_stats_list() and dm_stats_populate(). +- Add an argument to specify histogram bounds to dm_stats_create_region(). +- Add dm_histogram_bounds_from_{string,uint64_t}() to parse histogram bounds. +- Add dm_histogram handle type to represent a latency histogram and its bounds. + +* Wed Sep 02 2015 Peter Rajnoha - 7:2.02.129-2 +- Reinstate dm_task_get_info@Base to libdevmapper exports. (1.02.106) + +* Mon Aug 31 2015 Peter Rajnoha - 7:2.02.129-1 +- Drop error message when vgdisplay encounters an exported VG. (2.02.27) +- Fix shared library generation to stop exporting internal functions.(2.02.120) +- Accept --cachemode with lvconvert. +- Fix and improve reporting properties of cache-pool. +- Enable usage of --cachepolicy and --cachesetting with lvconvert. +- Don't allow to reduce size of thin-pool metadata. +- Fix debug buffer overflows in cmirrord logging. +- Add --foreground and --help to cmirrord. +- Add 'precise' column to statistics reports. +- Add --precise switch to 'dmstats create' to request nanosecond counters. +- Add precise argument to dm_stats_create_region(). +- Add support to libdm-stats for precise_timestamps +- Fix devmapper.pc pkgconfig file to declare -lrt dependency properly. + +* Tue Aug 18 2015 Peter Rajnoha - 7:2.02.128-1 +- Allocation setting cache_pool_cachemode is replaced by cache_mode. +- Don't attempt to close config file that couldn't be opened. +- Check for valid cache mode in validation of cache segment. +- Change internal interface handling cache mode and policy. +- When no cache policy specified, prefer smq (if available) over mq. +- Add demo cache-mq and cache-smq profiles. +- Add cmd profilable allocation/cache_policy,cache_settings,cache_mode. +- Require cache_check 0.5.4 for use of --clear-needs-check-flag. +- Fix lvmetad udev rules to not override SYSTEMD_WANTS, add the service instead. +- Fix 'dmstats list -o all' segfault. +- Separate dmstats statistics fields from region information fields. +- Add interval and interval_ns fields to dmstats reports. +- Do not include internal glibc headers in libdm-timestamp.c (1.02.104) +- Exit immediately if no device is supplied to dmsetup wipe_table. +- Suppress dmsetup report headings when no data is output. (1.02.104) +- Adjust dmsetup usage/help output selection to match command invoked. +- Fix dmsetup -o all to select correct fields in splitname report. +- Restructure internal dmsetup argument handling across all commands. +- Add dm_report_is_empty() to indicate there is no data awaiting output. +- Add more arg validation for dm_tree_node_add_cache_target(). +- Add --alldevices switch to replace use of --force for stats create / delete. + +* Mon Aug 10 2015 Peter Rajnoha - 7:2.02.127-1 +- Do not init filters, locking, lvmetad, lvmpolld if command doesn't use it. +- Order fields in struct cmd_context more logically. +- Add lock_type to lvmcache VG summary and info structs. +- Fix regression in cache causing some PVs to bypass filters (2.02.105). +- Make configure --enable-realtime the default now. +- Add dmstats.8 man page. +- Add dmstats --segments switch to create one region per device segment. +- Add dmstats --regionid, --allregions to specify a single / all stats regions. +- Add dmstats --allprograms for stats commands that filter by program ID. +- Add dmstats --auxdata and --programid args to specify aux data and program ID. +- Add report stats sub-command to provide repeating stats reports. +- Add clear, delete, list, and print stats sub-commands. +- Add create stats sub-command and --start, --length, --areas and --areasize. +- Recognize 'dmstats' as an alias for 'dmsetup stats' when run with this name. +- Add a 'stats' command to dmsetup to configure, manage and report stats data. +- Add statistics fields to dmsetup -o. +- Add libdm-stats library to allow management of device-mapper statistics. +- Add --nosuffix to suppress dmsetup unit suffixes in report output. +- Add --units to control dmsetup report field output units. +- Add support to redisplay column headings for repeating column reports. +- Fix report header and row resource leaks. +- Report timestamps of ioctls with dmsetup -vvv. +- Recognize report field name variants without any underscores too. +- Add dmsetup --interval and --count to repeat reports at specified intervals. +- Add dm_timestamp functions to libdevmapper. +- Recognise vg/lv name format in dmsetup. +- Move size display code to libdevmapper as dm_size_to_string. + +* Tue Jul 28 2015 Peter Rajnoha - 7:2.02.126-1 +- Fix long option hyphen removal. (2.02.122) +- Fix clvmd freeze if client disappears without first releasing its locks. +- Fix lvconvert segfaults while performing snapshots merge. +- Ignore errors during detection if use_blkid_wiping=1 and --force is used. +- Recognise DM_ABORT_ON_INTERNAL_ERRORS env var override in lvm logging fn. +- Fix alloc segfault when extending LV with fewer stripes than in first seg. +- Fix handling of cache policy name. +- Set cache policy before with the first lvm2 cache pool metadata commit. +- Fix detection of thin-pool overprovisioning (2.02.124). +- Fix lvmpolld segfaults on 32 bit architectures. +- Add lvmlockd lock_args validation to vg_validate. +- Fix ignored --startstopservices option if running lvmconf with systemd. +- Hide sanlock LVs when processing LVs in VG unless named or --all used. +- Introduce libdevmapper wrappers for all malloc-related functions. + +* Fri Jul 10 2015 Peter Rajnoha - 7:2.02.125-2 +- lvm2-lockd subpackage requires dlm-lib or sanlock-lib or both + based on which support is compiled in. +- lvm2-lockd subpackage requires dlm-lib instead of former dlm + for lvmlockd daemon with dlm support. + +* Tue Jul 07 2015 Peter Rajnoha - 7:2.02.125-1 +- Fix getline memory usage in lvmpolld. +- Add support --clear-needs-check-flag for cache_check of cache pool metadata. +- Add lvmetactl for developer use only. +- Rename global/lock_retries to lvmlockd_retries. +- Replace --enable-lvmlockd by --enable-lockd-sanlock and --enable-lockd-dlm. + +* Mon Jul 06 2015 Peter Rajnoha - 7:2.02.124-1 +- Add lvm2-lockd subpackage with technical preview of lvm locking daemon. +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed Jan 28 2015 Peter Rajnoha - 7:2.02.115-3 +- Preserve chunk size with repair and metadata swap of a thin pool. +- Fix raid --splitmirror 1 functionality (2.02.112). +- Fix tree preload to handle splitting raid images. + +* Thu Jan 22 2015 Peter Rajnoha - 7:2.02.115-2 +- Remove rules from 10-dm.rules which handle multipath, rules for handling + multipath devices are directly part of device-mapper-multipath package. + +* Wed Jan 21 2015 Peter Rajnoha - 7:2.02.115-1 +- Report segment types without monitoring support as undefined. +- Support lvchange --errorwhenfull for thin pools. +- Improve the processing and reporting of duplicate PVs. +- Add support for lvcreate --errorwhenfull y|n for thin pools +- Fix lvconvert --repair to honour resilience requirement for segmented RAID LV. +- Also call lvscan --cache in dmeventd for mirror device update in lvmetad. +- Filter out partitioned device-mapper devices as unsuitable for use as PVs. +- Also notify lvmetad about filtered device if using pvscan --cache DevicePath. +- Add report/compact_output to lvm.conf to enable/disable compact report output. +- Rename lv_error_when_full reporting field to lv_when_full. +- Reduce severity of ioctl error message when dmeventd waitevent is interrupted. +- Report 'unknown version' when incompatible version numbers were not obtained. +- Add dm_report_compact_fields to remove empty fields from report output. +- Add BuildRequires: device-mapper-persistent-data for proper thin_check configuration. + +* Wed Jan 14 2015 Peter Rajnoha - 7:2.02.114-5 +- Report lv_health_status and health attribute also for thin pool. +- Add lv_error_when_full reporting field. +- Add support for lvcreate --errorwhenfull y|n for thin pools. +- Report more info from thin pool status (out of data, metadata-ro, fail). +- Support error_if_no_space for thin pool target. +- Do not filter out snapshot origin LVs as unusable devices for an LVM stack. +- Fix process_each_pv to match item by device not by its PV device name only. + +* Wed Jan 07 2015 Peter Rajnoha - 7:2.02.114-4 +- Fix incorrect rimage names when converting from mirror to raid1 LV (2.02.112). +- Avoid excessive re-reading of metadata and related error messages in pvremove. +- Check for cmirror availability during cluster mirror creation and activation. +- Fix possible segfault when using cache_policy and cache_settings fields. +- Fix reserved values recognition for cache_policy and cache_settings fields. + +* Wed Dec 17 2014 Peter Rajnoha - 7:2.02.114-3 +- Add cache_policy and cache_settings reporting fields. +- Add missing recognition for --binary option with {pv,vg,lv}display -C. +- Fix vgimportclone to notify lvmetad about changes done if lvmetad is used. +- Fix vgimportclone to properly override config if it is missing in lvm.conf. +- Fix automatic use of configure --enable-udev-systemd-background-jobs. +- Correctly rename active split LV with -splitmirrors for raid1. +- Still restrict mirror region size to power of 2 when VG extent size is not. +- Fix segfault while using selection with regex and unbuffered reporting. +- Remove unimplemented dm_report_set_output_selection from libdevmapper.h. + +* Mon Dec 01 2014 Peter Rajnoha - 7:2.02.114-2 +- Release socket in daemon_close and protocol string in daemon_open error path. +- Add --cachepolicy and --cachesettings to lvcreate. +- Fix regression when parsing /dev/mapper dir (2.02.112). +- Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT var to be ignored. + +* Wed Nov 26 2014 Peter Rajnoha - 7:2.02.113-1 +- Fix missing rounding to 64KB when estimating optimal thin pool chunk size. +- Fix size in pvresize "Resizing to ..." verbose msg to show proper result size. +- Add --cachepolicy and --cachesettings options to lvchange. +- Validate that converted volume and specified pool volume differ in lvconvert. +- Fix regression in vgscan --mknodes usage (2.02.112). +- Respect --prefix when setting CLMVD_PATH configure (2.02.89). +- Default to configure --enable-udev-systemd-background-jobs for systemd>=205. +- Fix ignore_vg() to properly react on various vg_read errors (2.02.112). +- Failed recovery returns FAILED_RECOVERY status flag for vg_read(). +- Exit with non-zero status code when pvck encounters a problem. +- Fix clean_tree after activation/resume for cache target (2.02.112). +- Fix memory corruption with sorting empty string lists (1.02.86). +- Fix man dmsetup.8 syntax warning of Groff +- Accept unquoted strings and / in place of {} when parsing configs. + +* Tue Nov 11 2014 Peter Rajnoha - 7:2.02.112-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Mon Sep 29 2014 Peter Rajnoha - 7:2.02.111-1 +- Update to latest upstream release with various fixes and + enhancements documented in WHATS_NEW and WHATS_NEW_DM file. + +* Wed Mar 26 2014 Peter Rajnoha - 7:2.02.105-14 +- Increase wait time for finishing initial lvmetad scan that's run in parallel. +- Reinitialise lvmcache properly on fork to fix polldaemon exiting prematurely. +- Add more cleanup for stray "cpg_dispatch_failed" cmirror messages. + +* Wed Mar 19 2014 Peter Rajnoha - 7:2.02.105-13 +- Use VG read lock during 'pvscan --cache -aay' autoactivation. +- Issue a VG refresh before autoactivation only if the PV has changed/is new. +- Add flag to lvmetad protocol to indicate the PV scanned has changed/is new. +- Also add vgname to lvmetad protocol when referencing VGs for PVs scanned. +- Use correct PATH_MAX for locking dir path. + +* Wed Mar 12 2014 Peter Rajnoha - 7:2.02.105-12 +- Do not try to check empty pool with scheduled messages. +- Fix return value in pool_has_message() when quering for any message. +- Fix dmeventd logging with parallel wait event processing. + +* Thu Mar 06 2014 Peter Rajnoha - 7:2.02.105-11 +- Cleanup stray "cpg_dispatch failed: CS_ERR_BAD_HANDLE" messages for cmirror. + +* Wed Mar 05 2014 Peter Rajnoha - 7:2.02.105-10 +- Fix cache consistency in lvmetad when PV moves around. +- Fix memleak when lvmetad discovers PV to appear on another device. +- Fix invalid memory read in lvmetad that could cause a deadlock. + +* Fri Feb 28 2014 Peter Rajnoha - 7:2.02.105-9 +- Use configure --with-cache=internal to enable cache support code. + +* Thu Feb 27 2014 Peter Rajnoha - 7:2.02.105-8 +- Fix incorrect calculation of snapshot cow size. + +* Wed Feb 26 2014 Peter Rajnoha - 7:2.02.105-7 +- Fix previous build that reinstated obsoleted multipath rule in 10-dm.rules. + +* Wed Feb 26 2014 Peter Rajnoha - 7:2.02.105-6 +- Add initial support for LVM cache and cachepool segment types. +- Include various bug fixes from upcoming lvm2 v2.02.106 release + detailed in WHATS_NEW and WHATS_NEW_DM file. + +* Fri Feb 21 2014 Peter Rajnoha - 7:2.02.105-5 +- Avoid a PV label scan while in a critical section. +- Add Requires: resource-agents to lvm2-cluster and cmirror subpackage. +- Add new lvm2-cluster-standalone and cmirror-standalone subpackages. +- Add systemd native service for clvmd, cmirrord and clustered LV activation. +- Move obsolete clvmd/cmirrord initscripts to lvm2-sysvinit subpackage. +- Use --ignoreskippedcluster in lvm2-monitor initscript/systemd unit. +- Use --ignoreskippedcluster in activation systemd units if use_lvmetad=0. + +* Wed Feb 19 2014 Peter Rajnoha - 7:2.02.105-4 +- Fix unwanted drop of hold flocks on forked children. +- Fix merging of old snapshot into thin volume origin. +- Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request. +- Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol. +- Do not use systemd's reload for dmeventd restart, use dmeventd -R instead. + +* Wed Feb 05 2014 Peter Rajnoha - 7:2.02.105-3 +- Drop obsolete multipath rules from 10-dm.rules. +- Drop cryptsetup rules from 10-dm.rules - cryptsetup >= 1.1.3 sets them. +- Avoid trying to convert single to thin pool and volume at the same time. +- Detect thin feature external_origin_extend and limit extend when missing. + +* Fri Jan 24 2014 Daniel Mach - 7:2.02.105-2 +- Mass rebuild 2014-01-24 + +* Wed Jan 22 2014 Peter Rajnoha - 7:2.02.105-1 +- Online thin pool metadata resize requires 1.10 kernel thin pool target. +- Fix thin LV flagging for udev to skip scanning only if the LV is wiped. +- Replace use of xfs_check with xfs_repair in fsadm. +- Mark lvm1 format metadata as FMT_OBSOLETE. Do not use it with lvmetad. +- Invalidate cached VG struct after a PV in it gets orphaned. (2.02.87) +- Mark pool format metadata as FMT_OBSOLETE. +- Syntax and spelling fixes in some man pages. +- Dependency scan counts with snapshots and external origins. +- Make sure VG extent size is always greater or equal to PV phys. block size. +- Optimize double call of stat() for cached devices. +- Enable support for thin provisioning for default configuration. +- Return success when inserting dirs and links into device cache. +- Test for remote exclusive activation after activation fails. +- Support lvconvert --merge for thin snapshots. +- Add support to read thin device id from table line entry. +- Extend lv_remove_single() to not print info about removed LV. +- Replace open_count check with lv_check_not_in_use() for snapshot open test. +- Add error messages with LV names for failing lv refresh. +- Add --splitsnapshot to lvconvert to separate out cow LV. +- Reinstate origin reload to complete lvconvert -s with active LVs. (2.02.98) +- Select only active volume groups if vgdisplay -A is used. +- Add -p and LVM_LVMETAD_PID env var to lvmetad to change pid file. +- Allow lvmetad to reuse stale socket. +- Only unlink lvmetad socket on error if created by the same process. +- Append missing newline to lvmetad missing socket path error message. +- Check for non-zero aligment in _text_pv_add_metadata_area() to not div by 0. +- Add allocation/use_blkid_wiping to lvm.conf to enable blkid wiping. +- Enable blkid_wiping by default if the blkid library is present. +- Add configure --disable-blkid_wiping to disable libblkid signature detection. +- Add -W/--wipesignatures lvcreate option to support wiping on new LVs. +- Add allocation/wipe_signatures_when_zeroing_new_lvs to lvm.conf. +- Do not connect to lvmetad on vg/lvchange --sysinit -aay and socket absent. +- Use lv_check_not_in_use() when testing device in use before merging. +- Check for failure of lvmcache_add_mda() when writing pv. +- Check for failure of dev_get_size() when reporting device size. +- Drop extra unneeded '/' when scanning sysfs directory. +- Fix undef value if skipped clustered VG ignored for toollib PV seg. (2.02.103) +- Support validation of VG/LV names in liblvm/python. +- Allow creation of PVs with arguments to liblvm/python. +- Ensure sufficient metadata copies retained in liblvm/python vgreduce. +- Fix installation of profiles from conf subdir when not building in srcdir. +- Show UUIDs for missing PVs in reports. +- Add reporting of thin_id device id for thin volumes. +- Fix reporting of empty numerical values for recently-added fields. +- Use _field_set_percent/value in reporting code. +- Return success when LV cannot be activated because of volume_list filter. +- Return proper error state for remote exclusive activation. +- Fix clvmd message verification to not reject REMOTE flag. (2.02.100) +- Compare equality of double values with DBL_EPSILON predefined constant. +- Use additional gcc warning flags by default. +- Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors. +- Fix endless loop in blkdeactivate ... if unable to umount/deactivate. +- Remove 2>/dev/null from three lvm commands executed by vgimportclone. +- Check for open count with a timeout before removal/deactivation of an LV. +- Report RAID images split with tracking as out-of-sync ("I"). +- Add workaround for deactivation problem of opened virtual snapshot. +- Disable unsupported merge for virtual snapshot. +- Revert activation of activated nodes if a node preload callback fails. +- Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY. +- Ensure global mutex is held when working with dmeventd thread. +- Drop taking timeout mutex for un/registering dmeventd monitor. +- Allow section names in config file data to be quoted strings. +- Close fifos before exiting in dmeventd restart() error path. +- Catch invalid use of string sort values when reporting numerical fields. +- Consistently report on stderr when device is not found for dmsetup info. +- Skip race errors when non-udev dmsetup build runs on udev-enabled system. +- Skip error message when holders are not present in sysfs. +- Require libpthread to build now. +- Add BuildRequires: libblkid-devel for blkid wiping functionality. + +* Wed Jan 15 2014 Peter Rajnoha - 7:2.02.103-11 +- Do not drop SYSTEMD_READY for non-activating events (LVM on MD or loop). +- Add missing AC_TRY_CCFLAG defined in acinclude.m4 for configuration checks. + +* Tue Jan 07 2014 Peter Rajnoha - 7:2.02.103-10 +- Properly apply RELRO and PIE compiler and linker options. + +* Tue Jan 07 2014 Peter Rajnoha - 7:2.02.103-9 +- Consolidate file permissions for all packaged files. + +* Mon Jan 06 2014 Peter Rajnoha - 7:2.02.103-8 +- Use major:minor in lvm2-pvscan@.service for proper global_filter application. +- Fix SYSTEMD_READY assignment for foreign devices in lvmetad udev rules. +- Handle failures in temporary mirror used when adding images to mirrors. +- Compile/link executables with new RELRO and PIE options (non-static builds). +- Replace hardcoded sbin dir value with rpm variable for clvmd and cmirrord. +- Install all binary executables with 0555 permissions. +- Configure with --enable-write_install for writeable executables + during rpm processing of debug info. + +* Fri Dec 27 2013 Daniel Mach - 7:2.02.103-7 +- Mass rebuild 2013-12-27 + +* Wed Nov 27 2013 Peter Rajnoha - 2.02.103-6 +- Do not fail the whole autoactivation if the VG refresh done before fails. + +* Tue Nov 12 2013 Peter Rajnoha - 2.02.103-5 +- Fix missing lvmetad scan for PVs found on MD partitions. +- Add internal flag for temporary LVs to properly direct udev to not interfere. +- Respect DM_UDEV_DISABLE_OTHER_RULES_FLAG in lvmetad udev rules. +- Workaround VG refresh race during autoactivation by retrying the refresh. + +* Thu Oct 24 2013 Peter Rajnoha - 2.02.103-4 +- Add dev-block-:.device systemd alias for complete PV tracking. +- Use major:minor as short form of --major and --minor arg for pvscan --cache. +- Fix lvconvert swap of poolmetadata volume for active thin pool. + +* Fri Oct 18 2013 Peter Rajnoha - 2.02.103-3 +- Add configure --enable-udev-systemd-background-jobs. +- Add lvm2-pvscan@.service to run pvscan as a service for lvmetad/autoactivation. + +* Thu Oct 10 2013 Peter Rajnoha - 2.02.103-2 +- Fix LV_NOSCAN flag so it's properly recognized as internal LV flag. + +* Thu Oct 10 2013 Peter Rajnoha - 2.02.103-1 +- Fix possible race during daemon worker thread creation (lvmetad). +- Fix possible deadlock while clearing lvmetad cache for full rescan. +- Fix possible race while creating/destroying memory pools. +- Fix failing metadata repair when lvmetad is used. +- Fix incorrect memory handling when reading messages from lvmetad. +- Fix locking in lvmetad when handling the PV which is gone. +- Run full scan before vgrename operation to avoid any cache name collision. +- Recognize new flag to skip udev scanning in udev rules and act appropriately. +- Add support for flagging an LV to skip udev scanning during activation. +- Improve message when unable to change discards setting on active thin pool. +- Fix lvconvert when converting to a thin pool and thin LV at once. +- Ensure vgid matches before removing vgname entry from lvmetad cache. +- Add --ignoreskippedcluster for exit status success when clustered VGs skipped. +- Fix 3 minute udev timeout so that it is applied for all LVM volumes. +- Fix thin/raid & activation config defaults with configure --disable-devmapper. +- Fix RAID calculation for sufficient allocatable space. +- lvconvert from linear to mirror or RAID1 now honors mirror_segtype_default. +- Add thin-performance configuration profile. +- Add lvm.conf allocation/thin_pool_chunk_size_policy option. +- Fix contiguous & cling allocation policies for parity RAID. (2.02.100) +- Have lvmconf --enable/disable-cluster reset/set use_lvmetad. +- Add seg_size_pe field to reports. +- Support start+length notation with command line PE ranges. +- Exit cleanly with message when pvmove cannot restart because LV is inactive. +- Define symbolic names for subsystem udev flags in libdevmapper for easier use. +- Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*. +- Start using a distinct Epoch number in pkg version for major RHEL release. + +* Tue Sep 24 2013 Peter Rajnoha - 2.02.102-1 +- Fix missing build dependency for scripts subdir in Makefile. +- Fix node up/down handling in clvmd corosync module. +- Fix 3-thread clvmd deadlock triggered by cleanup on EOF from client. +- Remove VG from lvmetad before restoring it with vgcfgrestore. +- Add devtypes report command to display built-in recognised block device types. +- Fix CC Makefile override which had reverted to using built-in value. (2.02.75) +- Recognise bcache block devices in filter (experimental). +- Run lvm2-activation-net after lvm2-activation service to prevent parallel run. +- Add man page entries for lvmdump's -u and -l options. +- Fix lvm2app segfault while using lvm_list_pvs_free fn if there are no PVs. +- Improve of clvmd singlenode locking simulation. +- lvconvert no longer converts LVs of "mirror" segment type to thinpool. +- lvconvert no longer converts thinpool sub-LVs to "mirror" segment type. +- Direct udev to use 3min timeout for LVM devices. Recent udev has default 30s. +- Do not scan multipath or RAID components and avoid incorrect autoactivation. +- Fix MD/loop udev handling to fire autoactivation after setup or coldplug only. +- Make RAID capable of single-machine exclusive operations in a cluster. +- Drop calculation of read ahead for deactivated volume. +- Check for exactly one lv segment in validation of thin pools and volumes. +- Fix dmeventd unmonitoring of thin pools. +- Fix lvresize for stacked thin pool volumes (i.e. mirrors). +- Write Completed debug message before reinstating log defaults after command. +- Refresh existing VG before autoactivation (event retrigger/device reappeared). +- Use pvscan -b in udev rules to avoid a deadlock on udev process count limit. +- Add pvscan -b/--background for the command to be processed in the background. +- Don't assume stdin file descriptor is readable. +- Avoid unlimited recursion when creating dtree containing inactive pvmove LV. +- Require exactly 3 arguments for lvm2-activation-generator. Remove defaults. +- Inform lvmetad about any lost PV label to make it in sync with system state. +- Support most of lvchange operations on stacked thin pool meta/data LVs. +- Enable non-clustered pvmove of snapshots and snapshot origins. +- Add ability to pvmove non-clustered RAID, mirror, and thin volumes. +- Make lvm2-activation-generator silent unless it's in error state. +- Remove "mpath major is not dm major" msg for mpath component scan (2.02.94). +- Prevent cluster mirror logs from being corrupted by redundant checkpoints. +- Fix ignored lvmetad update on loop device configuration (2.02.99). +- Use LVM_PATH instead of hardcoded value in lvm2 activation systemd generator. +- Fix vgck to notice on-disk corruption even if lvmetad is used. +- Move mpath device filter before partitioned filter (which opens devices). +- Require confirmation for vgchange -c when no VGs listed explicitly. +- Also skip /var and /var/log by default in blkdeactivate when unmounting. +- Add support for bind mounts in blkdeactivate. +- Add blkdeactivate -v/--verbose for debug output from external tools used. +- Add blkdeactivate -e/--errors for error messages from external tools used. +- Suppress messages from external tools called in blkdeactivate by default. +- Fix inability to remove a VG's cluster flag if it contains a mirror. +- Fix bug making lvchange unable to change recovery rate for RAID. +- Prohibit conversion of thin pool to external origin. +- Workaround gcc v4.8 -O2 bug causing failures if config/checks=1 (32bit arch). +- Verify clvmd message validity before processing and log error if incorrect. +- When creating PV on existing LV don't forbid reserved LV names on LVs below. +- When converting mirrors, default segtype should be the same unless specified. +- Make "raid1" the default mirror segment type. +- Fix clogd descriptor leak when daemonizing. +- Fix clvmd descriptor leak on restart. +- Add pipe_open/close() to use instead of less efficient/secure popen(). +- Inherit and apply any profile attached to a VG if creating new thin pool. +- Ignore previous LV seg with alloc contiguous & cling when num stripes varies. +- Set use_lvmetad=0 on lvmconf --enable-cluster, reset to default on --disable-cluster. +- Tidy dmeventd fifo initialisation. +- Detect invalid sector supplied to 'dmsetup message'. +- Free any previously-set string if a dm_task_set_* function is called again. +- Do not allow passing empty new name for dmsetup rename. +- Display any output returned by 'dmsetup message'. +- Add dm_task_get_message_response to libdevmapper. +- Create dmeventd timeout threads as "detached" so exit status is freed. +- Add DM_ABORT_ON_INTERNAL_ERRORS env var support to abort on internal errors. + +* Wed Jul 31 2013 Peter Rajnoha - 2.02.99-1 +- o Features/Extensions/Additions: +- Add initial support thin pool lvconvert --repair. +- Add support for poolmetadataspare LV, that will be used for pool recovery. +- Improve activation order when creating thin pools in non-clustered VG. +- Add lvm2-activation-net systemd unit to activate LVs on net-attached storage. +- Automatically flag thin snapshots to be skipped during activation. +- Add support for persistent flagging of LVs to be skipped during activation. +- Make selected thinp settings customizable by a profile. +- Support storing profile name in metadata for both VGs and LVs. +- Add support for configuration profiles. +- Add support for thin volumes in vgsplit. +- Add lvresize support for online thin pool metadata volume resize. +- Add detection for thin pool metadata resize kernel support. +- Add vg->vg_ondisk / lv_ondisk() holding committed metadata. +- Add detection of mounted fs also for vgchange deactivation. +- Avoid a global lock in pvs when lvmetad is in use. +- Detect maximum usable size for snapshot for lvresize. +- Improve RAID kernel status retrieval to include sync_action/mismatch_cnt. +- Add external origin support for lvcreate. +- Support automatic config validation. +- Add PV header extension: extension version, flags and bootloader areas. +- Initial support for lvconvert of thin external origin. +- Improve activation code for better support of stacked devices. +- vgimport '--force' now allows import of VGs with missing PVs. +- Allow removal or replacement of RAID LV components that are error segments. +- Make 'vgreduce --removemissing' able to handle RAID LVs with missing PVs. +- Add lvconvert support to swap thin pool metadata volume. +- Allow vgcfgrestore of lvm2 metadata with thin volumes if --force is used. +- Give precedence to EMC power2 devices with duplicate PVIDs. +- Recognise Storage Class Memory (IBM S/390) devices in filter. +- Recognise STEC skd devices in filter. +- Recognise Violin Memory vtms devices in filter. +- Support discards for non-power-of-2 thin pool chunks. +- Automatically restore MISSING PVs with no MDAs. +- Support allocation of pool metadata with lvconvert command. +- Detect mounted fs also via reading /proc/self/mountinfo. +- o Command Interface/Options: +- Support ARG_GROUPABLE with merge_synonym (for --raidwritemostly). +- Add --ignoreactivationskip to lvcreate/vgchange/lvchange to ignore skip flag. +- Add --setactivationskip to lvcreate/lvchange to set activation skip flag. +- Add --type profilable to lvm dumpconfig to show profilable config settings. +- Add --mergedconfig to lvm dumpconfig for merged --config/--profile/lvm.conf. +- Support changing VG/LV profiles: vgchange/lvchange --profile/--detachprofile. +- Add new --profile command line arg to select a configuration profile for use. +- For creation of snapshot require size for at least 3 chunks. +- Do not accept size parameters bigger then 16EiB. +- Accept --yes in all commands so test scripts can be simpler. +- Add lvcreate/lvchange --[raid]{min|max}recoveryrate for raid LVs. +- Add lvchange --[raid]writemostly/writebehind support for RAID1 +- Add lvchange --[raid]syncaction for scrubbing of RAID LVs. +- Add --validate option to lvm dumpconfig to validate current config on demand. +- Add --ignoreadvanced and --ignoreunsupported switch to lvm dumpconfig. +- Add --withcomments and --withversions switch to lvm dumpconfig. +- Add --type {current|default|missing|new} and --atversion to lvm dumpconfig. +- Add --bootloaderareasize to pvcreate and vgconvert to create bootloader area. +- Do not take a free lv name argument for lvconvert --thinpool option. +- Allow lvconvert --stripes/stripesize only with --mirrors/--repair/--thinpool. +- Do not ignore -f in lvconvert --repair -y -f for mirror and raid volumes. +- Support use of option --yes for lvchange --persistent. +- Fix clvmd support for option -d and properly use its argument. +- o Reporting: +- Issue an error msg if lvconvert --type used incorrectly with other options. +- Use LOG_DEBUG/ERR msg severity instead default for lvm2-activation-generator. +- Add LV report fields: raid_mismatch_count/raid_sync_action/raid_write_behind. +- Add LV reporting fields raid_min_recovery_rate, raid_max_recovery_rate. +- Add sync_percent as alias for copy_percent LV reporting field. +- Add lv_ prefix to modules reporting field. +- Use units B or b (never E) with no decimal places when displaying sizes < 1k. +- List thin-pool and thin modules for thin volumes. +- Add 's(k)ip activation' bit to lvs -o lv_attr to indicate skip flag attached. +- Improve error loging when user tries to interrupt commands. +- Add vgs/lvs -o vg_profile/lv_profile to report profiles attached to VG/LV. +- Report lvs volume type 'e' with higher priority. +- Report lvs volume type 'o' also for external origin volumes. +- Report lvs target type 't' only for thin pools and thin volumes. +- Add "active" LV reporting field to show activation state. +- Add "monitor" segment reporting field to show dmevent monitoring status. +- Add explicit message about unsupported pvmove for thin/thinpool volumes. +- Add pvs -o pv_ba_start,pv_ba_size to report bootloader area start and size. +- Fix pvs -o pv_free reporting for PVs with zero PE count. +- Report blank origin_size field if the LV doesn't have an origin instead of 0. +- Report partial and in-sync RAID attribute based on kernel status +- Log output also to syslog when abort_on_internal_error is set. +- Change lvs heading Copy% to Cpy%%Sync and print RAID4/5/6 sync% there too. +- Report error for nonexisting devices in dmeventd communication. +- Reduce some log_error messages to log_warn where we don't fail. +- o Configuration: +- Add lvm.conf thin_repair/dump_executable and thin_repair_options. +- Add activation/auto_set_activation_skip to control activation skip flagging. +- Add default.profile configuration profile and install it on make install. +- Add config/profile_dir to set working directory to load profiles from. +- Use mirror_segtype_default if type not specified for linear->mirror upconvert. +- Refine lvm.conf and man page documentation for autoactivation feature. +- Override system's global_filter settings for vgimportclone. +- Find newest timestamp of merged config files. +- Add 'config' section to lvm.conf to set the way the LVM configuration is handled. +- Add global/raid10_segtype_default to lvm.conf. +- Accept activation/raid_region_size in preference to mirror_region_size config. +- Add log/debug_classes to lvm.conf to control debug log messages. +- Allow empty activation/{auto_activation|read_only|}_volume_list config option. +- Add lvm.conf option global/thin_disabled_features. +- Add lvm.conf thin pool allocation settings thin_pool_{chunk_size|discards|zero}. +- Relax ignore_suspended_devices to read from mirrors that don't have a device marked failed. +- o Documentation: +- Add man page entries for profile configuration and related options. +- Document lvextend --use-policies option in man. +- Improve lvcreate, lvconvert and lvm man pages. +- o API/interfaces: +- liblvm/python API: Additions: PV create/removal/resize/listing +- liblvm/python API: Additions: LV attr/origin/Thin pool/Thin LV creation +- Fix exported symbols regex for non-GNU busybox sed. +- Add LV snapshot support to liblvm and python-lvm. +- Fix lvm2app to return all property sizes in bytes (not sectors). +- Fix lvm2app and return lvseg discards property as string. +- Remove python liblvm object. systemdir can only be changed using env var now. +- Add DM_DISABLE_UDEV environment variable to manage dev nodes by libdm only. +- Add dm_get_status_snapshot() for parsing snapshot status. +- Append discards and read-only fields to exported struct dm_status_thin_pool. +- Validate passed params to dm_get_status_raid/thin/thin_pool(). +- Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. +- Add dm_mountinfo_read() for parsing /proc/self/mountinfo. +- Add dm_config_write_{node_out/one_node_out} for enhanced config output. +- Add dm_config_value_is_bool to check for boolean value in supported formats. +- Add DM_ARRAY_SIZE public macro. +- Add DM_TO_STRING public macro. +- Implement ref-counting for parents in python lib. +- o Fixes (general) +- Do not zero init 4KB of thin snapshot for non-zeroing thin pool (2.02.94). +- Correct thin creation error paths. +- Add whole log_lv and metadata_lv sub volumes when creating partial tree. +- Properly use snapshot layer for origin which is also thin volume. +- Avoid generating metadata backup when calling update_pool_lv(). +- Send thin messages also for active thin pool and inactive thin volume. +- Avoid creation of multiple archives for one command. +- Avoid flushing thin pool when just requesting transaction_id. +- Fix use of too big chunks of memory when communication with lvmetad. +- Also filter partitions on mpath components if multipath_component_detection=1. +- Do not use persistent filter with lvmetad. +- Move syslog code out of signal handle in dmeventd. +- Fix lvresize --use-policies of VALID but 100% full snapshot. +- Skip monitoring of snapshots that are already bigger then origin. +- Refuse to init a snapshot merge in lvconvert if there's no kernel support. +- Fix alignment of PV data area if detected alignment less than 1 MB (2.02.74). +- Fix premature DM version checking which caused useless mapper/control access. +- Fix creation and removal of clustered snapshot. +- Fix clvmd caching of metadata when suspending inactive volumes. +- Fix lvmetad error path in lvmetad_vg_lookup() for null vgname. +- Fix clvmd _cluster_request() return code in memory fail path. +- Fix vgextend to not allow a PV with 0 MDAs to be used while already in a VG. +- Fix PV alignment to incorporate alignment offset if the PV has zero MDAs. +- Fix missing cleanup of flags when the LV is detached from pool. +- Fix check for some forbidden discards conversion of thin pools. +- Fix blkdeactivate to handle nested mountpoints and mangled mount paths. +- Synchronize with udev in pvscan --cache and fix dangling udev_sync cookies. +- Fix autoactivation to not autoactivate VG/LV on each change of the PVs used. +- Limit RAID device replacement to repair only if LV is not in-sync. +- Disallow RAID device replacement or repair on inactive LVs. +- Unlock vg mutex in error path when lvmetad tries to lock_vg. +- Detect key string duplication failure in config_make_nodes_v in libdaemon. +- Disallow pvmove on RAID LVs until they are addressed properly +- Recognize DM_DISABLE_UDEV environment variable for a complete fallback. +- Do not verify udev operations if --noudevsync command option is used. +- When no --stripes argument is given when creating a RAID10 volume, default to 2 stripes. +- Do not allow lvconvert --splitmirrors on RAID10 logical volumes. +- Skip mlocking [vectors] on arm architecture. +- Repair a mirrored log before the mirror itself when both fail. +- Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. +- Avoid trying to read a mirror that has a failed device in its mirrored log. +- Fix 'dmsetup splitname -o' to not fail if used without '-c' switch (1.02.68). +- Fix segfault for truncated string token in config file after the first '"'. +- Fix config node lookup inside empty sections to not return the section itself. +- Fix parsing of 64bit snapshot status in dmeventd snapshot plugin. +- Always return success on dmeventd -V command call. +- o Fixes (segfaults/crashes/deadlocks/races): +- Fix segfault if devices/global_filter is not specified correctly. +- Fix segfault when reporting raid_syncaction for older kernels. +- Fix vgcfgrestore crash when specified incorrect vg name. +- Avoid crash-inducing race in lvmetad when VG disappears during rename. +- Fix possible race while removing metadata from lvmetad. +- Fix possible deadlock when querying and updating lvmetad at the same time. +- Check for memory failure of dm_config_write_node() in lvmetad. +- Fix crash in pvscan --cache -aay triggered by non-mda PV. +- Prevent double free error after dmeventd call of _fill_device_data(). +- o Fixes (resource leaks/memleaks): +- Release memory allocated with _cached_info(). +- Release memory and unblock signals in lock_vol error path. +- Fix memory resource leak in memlocking error path. +- Fix memleak in dmeventd thin plugin in device list obtaining err path. +- Fix socket leak on error path in lvmetad's handle_connect. +- Fix memleak on error path for lvmetad's pv_found. +- Fix memleak in device_is_usable mirror testing function. +- Fix memory leak on error path for pvcreate with invalid uuid. +- Fix resource leak in error path of dmeventd's umount of thin volume. +- Close open dmeventd FIFO file descriptors on exec (FD_CLOEXEC). +- o Testing: +- Fix test for active snapshot in cluster before resizing it. +- Add python-lvm unit test case +- o Other: +- Add --with-thin-repair and --with-thin-dump configure options. +- Require 1.9 thin pool target version for online thin pool metadata resize. +- Use local activation for clearing snapshot COW device. +- Add configure --with-default-profile-subdir to select dir to keep profiles in. +- Creation of snapshot takes at most 100% origin coverage. +- Use LC_ALL to set locale in daemons and fsadm instead of lower priority LANG. +- Remove dependency on fedora-storage-init.service in lvm2 systemd units. +- Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. +- Optimize out setting the same value of read_ahead. +- Automatically deactivate failed preloaded dm tree node. +- Process thin messages once to active thin pool target for dm_tree. +- Move common functionality for thin lvcreate and lvconvert to toollib. +- o Packaging: +- Add /etc/lvm/profile dir and /etc/lvm/profile/default.profile to lvm2 package. +- Do not include /lib/udev and /lib/udev/rules.d in device-mapper package. +- Fix spec file's util-linux version definition for proper expansion when used. +- Fix some incorrect changelog dates. + +* Fri Jun 07 2013 Peter Rajnoha - 2.02.98-6 +- Add pidfile reference to clvmd and cmirrord initscript for systemd + to not assume RemainAfterExit=yes which would end up with inconsistent + state for these services if daemon is killed. + +* Thu Apr 11 2013 Peter Rajnoha - 2.02.98-5 +- Add lvm2-activation-generator systemd generator to automatically generate + systemd units to activate LVM2 volumes even if lvmetad is not used. + This replaces lvm activation part of the former fedora-storage-init + script that was included in the initscripts package before. + +* Tue Nov 27 2012 Peter Rajnoha - 2.02.98-4 +- Apply the patch for pvscan --cache exit if cluster locking used or lvmetad not used. + +* Tue Nov 27 2012 Peter Rajnoha - 2.02.98-3 +- Incorporate former python-lvm package in lvm2 as lvm2-python-libs subpackage. +- Do not use lvmetad by default if lvm.conf missing or use_lvmetad not defined. +- Exit pvscan --cache immediately if cluster locking used or lvmetad not used. + +* Wed Nov 07 2012 Peter Rajnoha - 2.02.98-2 +- Fix ExecStop line in lvm2-monitor.service systemd unit - remove quotes. + +* Thu Nov 01 2012 Peter Rajnoha - 2.02.98-1 +- Don't use lvmetad in lvm2-monitor.service ExecStop to avoid a systemd issue. +- Depend on lvm2-lvmetad.socket in lvm2-monitor.service systemd unit. +- Init lvmetad lazily to avoid early socket access on config overrides. +- Hardcode use_lvmetad=0 if cluster locking used and issue a warning msg. +- Fix dm_task_set_cookie to properly process udev flags if udev_sync disabled. +- Don't try to issue discards to a missing PV to avoid segfault. +- Fix vgchange -aay not to activate non-matching LVs that follow a matching LV. +- Fix lvchange --resync for RAID LVs which had no effect. +- Add RAID10 support (--type raid10). +- Introduce blkdeactivate script to deactivate block devs with dependencies. +- Apply 'dmsetup mangle' for dm UUIDs besides dm names. +- Use -q as short form of --quiet. +- Suppress non-essential stdout with -qq. +- Add log/silent to lvm.conf equivalent to -qq. +- Add (p)artial attribute to lvs. +- Implement devices/global_filter to hide devices from lvmetad. +- Add lvmdump -l, to collect a state dump from lvmetad. +- Add --discards to lvconvert. +- Add support for lvcreate --discards. +- Add --poolmetadata to lvconvert and support thin meta/data dev stacking. +- Support creation of read-only thin volumes (lvcreate -p r). +- Support changes of permissions for thin snapshot volumes. +- Make lvremove ask before discarding data areas. +- Prohibit not yet supported change of thin-pool to read-only. +- Using autoextend percent 0 for thin pool fails 'lvextend --use-policies'. +- Make vgscan --cache an alias for pvscan --cache. +- Clear lvmetad metadata/PV cache before a rescan. +- Fix a segmentation fault upon receiving a corrupt lvmetad response. +- Give inconsistent metadata warnings in pvscan --cache. +- Avoid overlapping locks that could cause a deadlock in lvmetad. +- Fix memory leaks in libdaemon and lvmetad. +- Optimize libdaemon logging for a fast no-output path. +- Only create lvmetad pidfile when running as a daemon (no -f). +- Warn if lvmetad is running but disabled. +- Warn about running lvmetad with use_lvmetad = 0 in example.conf. +- Update lvmetad help output (flags and their meaning). +- Make pvscan --cache read metadata from LVM1 PVs. +- Make libdaemon buffer handling asymptotically more efficient. +- Make --sysinit suppress lvmetad connection failure warnings. +- Prohibit usage of lvcreate --thinpool with --mirrors. +- Fix lvm2api origin reporting for thin snapshot volume. +- Add implementation of lvm2api function lvm_percent_to_float. +- Allow non power of 2 thin chunk sizes if thin pool driver supports that. +- Allow limited metadata changes when PVs are missing via [vg|lv]change. +- Do not start dmeventd for lvchange --resync when monitoring is off. +- Remove pvscan --cache from lvm2-lvmetad init script. +- Remove ExecStartPost with pvscan --cache from lvm2-lvmetad.service. +- Report invalid percentage for property snap_percent of non-snaphot LVs. +- Disallow conversion of thin LVs to mirrors. +- Fix lvm2api data_percent reporting for thin volumes. +- Do not allow RAID LVs in a clustered volume group. +- Enhance insert_layer_for_lv() with recursive rename for _tdata LVs. +- Skip building dm tree for thin pool when called with origin_only flag. +- Ensure descriptors 0,1,2 are always available, using /dev/null if necessary. +- Use /proc/self/fd when available for closing opened descriptors efficiently. +- Fix inability to create, extend or convert to a large (> 1TiB) RAID LV. +- Update lvmetad communications to cope with clients using different filters. +- Clear LV_NOSYNCED flag when a RAID1 LV is converted to a linear LV. +- Disallow RAID1 upconvert if the LV was created with --nosync. +- Depend on systemd-udev-settle in units generated by activation generator. +- Disallow addition of RAID images until the array is in-sync. +- Fix RAID LV creation with '--test' so valid commands do not fail. +- Add lvm_lv_rename() to lvm2api. +- Fix setvbuf code by closing and reopening stream before changing buffer. +- Disable private buffering when using liblvm. +- When private stdin/stdout buffering is not used always use silent mode. +- Fix 32-bit device size arithmetic needing 64-bit casting throughout tree. +- Fix dereference of NULL in lvmetad error path logging. +- Fix buffer memory leak in lvmetad logging. +- Correct the discards field in the lvs manpage (2.02.97). +- Use proper condition to check for discards settings unsupported by kernel. +- Reinstate correct default to ignore discards for thin metadata from old tools. +- Issue error message when -i and -m args do not match specified RAID type. +- Change lvmetad logging syntax from -ddd to -l {all|wire|debug}. +- Add new libdaemon logging infrastructure. +- Support unmount of thin volumes from pool above thin pool threshold. +- Update man page to reflect that dm UUIDs are being mangled as well. +- Add 'mangled_uuid' and 'unmangled_uuid' fields to dmsetup info -c -o. +- Mangle device UUID on dm_task_set_uuid/newuuid call if necessary. +- Add dm_task_get_uuid_mangled/unmangled to libdevmapper. +- Always reset delay_resume_if_new flag when stacking thin pool over anything. +- Don't create value for dm_config_node and require dm_config_create_value call. +- Check for existing new_name for dmsetup rename. +- Fix memory leak in dmsetup _get_split_name() error path. +- Clean up spec file and keep support only for Fedora 18 upwards. +- Use systemd macros in rpm scriptlets to set up systemd units. +- Add Requires: bash >= 4.0 for blkdeactivate script. + +* Tue Aug 07 2012 Alasdair Kergon - 2.02.97-1 +- Improve documention of allocation policies in lvm.8. +- Increase limit for major:minor to 4095:1048575 when using -My option. +- Add generator for lvm2 activation systemd units. +- Add lvm_config_find_bool lvm2app fn to retrieve bool value from config tree. +- Respect --test when using lvmetad. +- No longer capitalise first LV attribute char for invalid snapshots. +- Allow vgextend to add PVs to a VG that is missing PVs. +- Recognise Micron PCIe SSDs in filter and move array out to device-types.h. +- Fix dumpconfig to print only without its siblings. (2.02.89) +- Do not issue "Failed to handle a client connection" error if lvmetad killed. +- Support lvchange --discards and -Z with thin pools. +- Add discard LV segment field to reports. +- Add --discards to lvcreate --thin. +- Set discard and external snapshot features if thin pool target is vsn 1.1+. +- Count percentage of completeness upwards not downwards when merging snapshot. +- Skip activation when using vg/lvchange --sysinit -a ay and lvmetad is active. +- Fix extending RAID 4/5/6 logical volumes +- Fix test for PV with unknown VG in process_each_pv to ignore ignored mdas. +- Fix _alloc_parallel_area to avoid picking already-full areas for raid devices. +- Never issue discards when LV extents are being reconfigured, not deleted. +- Allow release_lv_segment_area to fail as functions it calls can fail. +- Fix missing sync of filesystem when creating thin volume snapshot. +- Allow --noflush with dmsetup status and wait (for thin target). +- Add dm_config_write_one_node to libdevmapper. +- Add dm_vasprintf to libdevmapper. +- Support thin pool message release/reserve_metadata_snap in libdevmapper. +- Support thin pool discards and external origin features in libdevmapper. + +* Thu Jul 19 2012 Fedora Release Engineering - 2.02.96-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 04 2012 Peter Rajnoha - 2.02.96-3 +- Use configure --with-default-pid-dir=/run. +- Use globally set prefix for udev rules path. + +* Mon Jul 02 2012 Peter Rajnoha - 2.02.96-2 +- Compile with lvmetad support enabled. +- Add support for volume autoactivation using lvmetad. +- Update man pages with --activate ay option and auto_activation_volume_list. +- Use vgchange -aay instead of vgchange -ay in clmvd init script. +- Add activation/auto_activation_volume_list to lvm.conf. +- Add --activate ay to lvcreate, lvchange, pvscan and vgchange. +- Add --activate synonym for --available arg and prefer --activate. +- Open device read-only to obtain readahead value. +- Add configure --enable-udev-rule-exec-detection to detect exec path in rules. +- Use sbindir in udev rules by default and remove executable path detection. +- Remove hard-coded paths for dmeventd fifos and use default-dm-run-dir. +- Add configure --with-lvmetad-pidfile to remove hard-coded value. +- Add configure --with-default-pid-dir for common directory with pid files. +- Add configure --with-default-dm-run-dir to set run directory for dm tools. +- Add documentation references in systemd units. +- Clean up spec file and keep support only for Fedora 17 upwards. + +* Mon Jun 18 2012 Alasdair Kergon - 2.02.96-1 +- Require device-mapper-persistent-data package for thin provisioning. +- Set delay_resume_if_new on deptree snapshot origin. +- Log value chosen in _find_config_bool like other variable types do. +- Wait for dmeventd to exit after sending it DM_EVENT_CMD_DIE when restarting. +- Append 'Used' to {Blk}DevNames/DevNos dmsetup report headers for clarity. +- Remove dmeventd fifos on exit if they are not managed by systemd. +- Use SD_ACTIVATION environment variable in systemd units to detect systemd. +- Only start a new dmeventd instance on restart if one was already running. +- Extend the time waited for input from dmeventd fifo to 5 secs. (1.02.73) +- Fix error paths for regex filter initialization. +- Re-enable partial activation of non-thin LVs until it can be fixed. (2.02.90) +- Fix alloc cling to cling to PVs already found with contiguous policy. +- Fix cling policy not to behave like normal policy if no previous LV seg. +- Fix allocation loop not to use later policies when --alloc cling without tags. +- Fix division by zero if PV with zero PE count is used during vgcfgrestore. +- Add initial support for thin pool lvconvert. +- Fix lvrename for thin volumes (regression in for_each_sub_lv). (2.02.89) +- Fix up-convert when mirror activation is controlled by volume_list and tags. +- Warn of deadlock risk when using snapshots of mirror segment type. +- Fix bug in cmirror that caused incorrect status info to print on some nodes. +- Remove statement that snapshots cannot be tagged from lvm man page. +- Disallow changing cluster attribute of VG while RAID LVs are active. +- Fix lvconvert error message for non-mergeable volumes. +- Allow subset of failed devices to be replaced in RAID LVs. +- Prevent resume from creating error devices that already exist from suspend. +- Update and correct lvs man page with supported column names. +- Handle replacement of an active device that goes missing with an error device. +- Change change raid1 segtype always to request a flush when suspending. +- Add udev info and context to lvmdump. +- Add lvmetad man page. +- Fix RAID device replacement code so that it works under snapshot. +- Fix inability to split RAID1 image while specifying a particular PV. +- Update man pages to give them all the same look&feel. +- Fix lvresize of thin pool for striped devices. +- For lvresize round upward when specifying number of extents. +- For lvcreate with %%FREE support rounding downward stripe alignment. +- Change message severity to log_very_verbose for missing dev info in udev db. +- Fix lvconvert when specifying removal of a RAID device other than last one. +- Fix ability to handle failures in mirrored log in dmeventd plugin. (2.02.89) +- Fix unlocking volume group in vgreduce in error path. +- Cope when VG name is part of the supplied name in lvconvert --splitmirrors -n. +- Fix exclusive lvchange running from other node. (2.02.89) +- Add 'vgscan --cache' functionality for consistency with 'pvscan --cache'. +- Keep exclusive activation in pvmove if LV is already active. +- Disallow exclusive pvmove if some affected LVs are not exclusively activated. +- Remove unused and wrongly set cluster VG flag from clvmd lock query command. +- Fix pvmove for exclusively activated LV pvmove in clustered VG. (2.02.86) +- Update and fix monitoring of thin pool devices. +- Check hash insert success in lock_vg in clvmd. +- Check for buffer overwrite in get_cluster_type() in clvmd. +- Fix global/detect_internal_vg_cache_corruption config check. +- Fix initializiation of thin monitoring. (2.02.92) +- Cope with improperly formatted device numbers in /proc/devices. (2.02.91) +- Exit if LISTEN_PID environment variable incorrect in lvmetad systemd handover. +- Fix fsadm propagation of -e option. +- Fix fsadm parsing of /proc/mounts files (don't check for substrings). +- Fix fsadm usage of arguments with space. +- Fix arg_int_value alongside ARG_GROUPABLE --major/--minor for lvcreate/change. +- Fix name conflicts that prevent down-converting RAID1 when specifying a device +- Improve thin_check option passing and use configured path. +- Add --with-thin-check configure option for path to thin_check. +- Fix error message when pvmove LV activation fails with name already in use. +- Better structure layout for device_info in dev_subsystem_name(). +- Change message severity for creation of VG over uninitialised devices. +- Fix error path for failed toolcontext creation. +- Don't unlink socket on lvmetad shutdown if instantiated from systemd. +- Restart lvmetad automatically from systemd if it exits from uncaught signal. +- Fix warn msg for thin pool chunk size and update man for chunksize. (2.02.89) + +* Thu Jun 07 2012 Kay Sievers - 2.02.95-8 +- Remove explicit Requires: libudev, rpm takes care of that: + $ rpm -q --requires device-mapper | grep udev + libudev.so... + +* Tue Jun 05 2012 Peter Rajnoha - 2.02.95-7 +- Use BuildRequires: systemd-devel instead of BuildRequires: libudev-devel. +- Remove unsupported udev_get_dev_path libudev call used for checking udev dir. + +* Thu Mar 29 2012 Fabio M. Di Nitto - 2.02.95-6 +- BuildRequires and Requires on newer version of corosync and dlm. +- Restart clvmd on upgrades. + +* Mon Mar 19 2012 Peter Rajnoha - 2.02.95-5 +- Do not strictly require openais for cmirror subpackage. + +* Mon Mar 19 2012 Peter Rajnoha - 2.02.95-4 +- Reinstate cmirror support. +- Detect lvm binary path in lvmetad udev rules. +- Use pvscan --cache instead of vgscan in systemd units/init scripts. + +* Fri Mar 16 2012 Fabio M. Di Nitto - 2.02.95-3 +- Rebuild against new corosync (soname change). +- BuildRequires and Requires on newer version of corosync. + +* Thu Mar 08 2012 Peter Rajnoha - 2.02.95-2 +- Reload dm-event systemd service on upgrade. + +* Tue Mar 06 2012 Alasdair Kergon - 2.02.95-1 +- If unspecified, adjust thin pool metadata and chunk size to fit into 128MB. +- Deactivation of failed thin check on thin pool returns success. +- Check for multiply-mangled names in auto mangling mode. +- Fix dm_task_get_name_unmangled to not unmangle already unmangled name. +- Check whether device names are properly mangled on ioctl return. + +* Sat Mar 03 2012 Alasdair Kergon - 2.02.94-1 +- Add support to execute thin_check with each de/active of thin pool. +- Fix automatic estimation of metadata device size for thin pool. +- Wipe initial 4KiB of non zeroed thin volumes. +- Update code-base to incorporate new metadata daemon. (Not used in Fedora yet.) +- Numerous minor cleanups across the code-base. +- Fix dmsetup / dm_task_set_name to properly resolve path to dm name. (2.02.93) + +* Thu Feb 23 2012 Alasdair Kergon - 2.02.93-1 +- Moved systemd tmpfiles installation upstream for lvm2 lock and run dirs. +- Require number of stripes to be greater than parity devices in higher RAID. +- Fix allocation code to allow replacement of single RAID 4/5/6 device. +- Check all tags and LV names are in a valid form before writing any metadata. +- Allow 'lvconvert --repair' to operate on RAID 4/5/6. +- Fix build_parallel_areas_from_lv to account correctly for raid parity devices. +- Print message when faulty raid devices have been replaced. + +* Mon Feb 20 2012 Alasdair Kergon - 2.02.92-1 +- Read dmeventd monitoring config settings for every lvm command. +- For thin devices, initialize monitoring only for thin pools not thin volumes. +- Make conversion from a synced 'mirror' to 'raid1' not cause a full resync. +- Add clvmd init dependency on dlm service when running with new corosync. +- Switch to using built-in blkid in 13-dm-disk.rules. +- Add "watch" rule to 13-dm-disk.rules. +- Detect failing fifo and skip 20s retry communication period. +- Replace any '\' char with '\\' in dm table specification on input. +- New 'mangle' options in dmsetup/libdevmapper for transparent reversible + encoding of characters that udev forbids in device names. +- Add --manglename option to dmsetup to select the name mangling mode. +- Add mangle command to dmsetup to provide renaming to correct mangled form. +- Add 'mangled_name' and 'unmangled_name' fields to dmsetup info -c -o. +- Mangle device name on dm_task_set_name/newname call if necessary. +- Add dm_task_get_name_mangled/unmangled to libdevmapper. +- Add dm_set/get_name_mangling_mode to set/get name mangling in libdevmapper. + +* Mon Feb 13 2012 Peter Rajnoha - 2.02.91-2 +- Add configure --with-systemdsystemunitdir. + +* Sun Feb 12 2012 Alasdair Kergon - 2.02.91-1 +- New upstream with trivial fixes and refactoring of some lvmcache and orphan code. + +* Wed Feb 1 2012 Alasdair Kergon - 2.02.90-1 +- Drop support for cman, openais and cmirror for f17. Require dlm not cluster. +- Automatically detect whether corosync clvmd needs to use confdb or cmap. +- Disable partial activation for thin LVs and LVs with all missing segments. +- sync_local_dev_names before (re)activating mirror log for initialisation. +- Do not print warning for pv_min_size between 512KB and 2MB. +- Clean up systemd unit ordering and requirements. +- Allow ALLOC_NORMAL to track reserved extents for log and data on same PV. +- Fix data% report for thin volume used as origin for non-thin snapshot. + +* Thu Jan 26 2012 Alasdair Kergon - 2.02.89-2 +- New upstream release with experimental support for thinly-provisioned devices. +- The changelog for this release is quite long and contained in + WHATS_NEW and WHATS_NEW_DM in the documentation directory. + +* Fri Jan 13 2012 Fedora Release Engineering - 2.02.88-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Dec 30 2011 Peter Robinson - 2.02.88-2 +- update util-linux-ng -> util-linux dependency as it changed long ago. + +* Mon Aug 22 2011 Alasdair Kergon - 2.02.88-1 +- Remove incorrect 'Breaking' error message from allocation code. (2.02.87) +- Add lvconvert --merge support for raid1 devices split with --trackchanges. +- Add --trackchanges support to lvconvert --splitmirrors option for raid1. +- Add dm_tree_node_add_null_area for temporarily-missing raid devs tracked. +- Support lvconvert of -m1 raid1 devices to a higher number. +- Support splitting off a single raid1 rimage in lvconvert --splitmirrors. +- Add -V as short form of --virtualsize in lvcreate. + +* Fri Aug 12 2011 Peter Rajnoha - 2.02.87-1 +- Cache and share generated VG structs to improve performance. +- Suppress locking error messages in monitoring init scripts. +- Add global/detect_internal_vg_cache_corruption to lvm.conf. +- If pipe in clvmd fails return busy instead of using uninitialised descriptors. +- Initialise clvmd locks before lvm context to avoid open descriptor leaks. +- Suppress low-level locking errors and warnings while using --sysinit. +- Add test for fcntl error in singlenode client code. +- Compare file size (as well as timestamp) to detect changed config file. +- Change DEFAULT_UDEV_SYNC to 1 so udev_sync is used if there is no config file. +- Update udev rules to skip DM flags decoding for removed devices. +- Remove device name prefix from dmsetup line output if -j & -m or -u supplied. +- Add new segtype 'raid' for MD RAID 1/4/5/6 support with dmeventd plugin. +- Add ability to reduce the number of mirrors in raid1 arrays to lvconvert. +- Add support for systemd file descriptor handover in dmeventd. +- Add systemd unit file to provide lvm2 monitoring. +- Add systemd unit files for dmeventd. +- Use new oom killer adjustment interface (oom_score_adj) when available. +- Fix read-only identical table reload supression. +- Remove --force option from lvrename manpage. + +* Wed Aug 03 2011 Peter Rajnoha - 2.02.86-5 +- Change DEFAULT_UDEV_SYNC to 1 so udev_sync is used even without any config. + +* Thu Jul 28 2011 Peter Rajnoha - 2.02.86-4 +- Add support for systemd file descriptor handover to dmeventd. +- Add support for new oom killer adjustment interface (oom_score_adj). + +* Wed Jul 20 2011 Peter Rajnoha - 2.02.86-3 +- Fix broken lvm2-sysinit Requires: lvm2 dependency. + +* Mon Jul 18 2011 Peter Rajnoha - 2.02.86-2 +- Add dm-event and lvm2-monitor unit files for use with systemd. +- Add sysvinit subpackage for legacy SysV init script support. + +* Fri Jul 8 2011 Alasdair Kergon - 2.02.86-1 +- Fix activation sequences to avoid trapped I/O with multiple LVs. +- Fix activation sequences to avoid allocating tables while devs suspended. +- Remove unnecessary warning in pvcreate for MD linear devices. +- Add activation/checks to lvm.conf to perform additional ioctl validation. +- Append 'm' attribute to pv_attr for missing PVs. +- Fix to preserve exclusive activation of mirror while up-converting. +- Reject allocation if number of extents is not divisible by area count. +- Fix cluster mirror creation to work with new mirror allocation algorithm. +- Ignore activation/verify_udev_operations if dm kernel driver vsn < 4.18. +- Add activation/verify_udev_operations to lvm.conf, disabled by default. +- Ignore inconsistent pre-commit metadata on MISSING_PV devs while activating. +- Add proper udev library context initialization and finalization to liblvm. +- Downgrade critical_section errors to debug level until it is moved to libdm. +- Fix ignored background polling default in vgchange -ay. +- Fix reduction of mirrors with striped segments to always align to stripe size. +- Validate mirror segments size. +- Fix extent rounding for striped volumes never to reduce more than requested. +- Fix create_temp_name to replace any '/' found in the hostname with '?'. +- Always use append to file in lvmdump. selinux policy may ban file truncation. +- Propagate test mode to clvmd to skip activation and changes to held locks. +- Permit --available with lvcreate so non-snapshot LVs need not be activated. +- Clarify error message when unable to convert an LV into a snapshot of an LV. +- Do not issue an error message when unable to remove .cache on read-only fs. +- Avoid memlock size mismatch by preallocating stdio line buffers. +- Report internal error if suspending a device using an already-suspended dev. +- Report internal error if any table is loaded while any dev is known suspended. +- Report error if a table load requiring target parameters has none supplied. +- Add dmsetup --checks and dm_task_enable_checks framework to validate ioctls. +- Add age_in_minutes parameter to dmsetup udevcomplete_all. +- Disable udev fallback by default and add --verifyudev option to dmsetup. +- Add dm_get_suspended_counter() for number of devs in suspended state by lib. +- Fix "all" report field prefix matching to include label fields with pv_all. +- Delay resuming new preloaded mirror devices with core logs in deptree code. + +* Wed Jun 22 2011 Zdenek Kabelac - 2.02.84-3 +- Updated uname string test. + +* Sat Jun 4 2011 Milan Broz - 2.02.84-2 +- Accept kernel 3.0 uname string in libdevmapper initialization. +- Make systemd initscripts configurable. + +* Wed Feb 9 2011 Alasdair Kergon - 2.02.84-1 +- Fix big-endian CRC32 checksumming broken since 2.02.75. If affected, + ensure metadata backups in /etc/lvm/backup are up-to-date (vgcfgbackup) + then after updating to 2.02.84 restore metadata from them (using pvcreate + with -Zn --restorefile and -u if PVs can no longer be seen, then + vgcfgrestore -f). +- Reinstate libdevmapper DEBUG_MEM support. (Removed in 1.02.62.) + +* Tue Feb 08 2011 Fedora Release Engineering - 2.02.83-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Feb 4 2011 Alasdair Kergon - 2.02.83-1 +- Allow exclusive activation of snapshots in a cluster. +- Don't lose LV exclusive lock state when suspending clustered devices. +- Fix fs operation stack handling when multiple operations on same device. +- Increase hash table sizes to 1024 LV names and 64 PV uuids. +- When setting up mda wipe first 4k of it as was intended. +- Remove unneeded checks for open_count in lv_info(). +- Synchronize with udev before checking open_count in lv_info(). +- Add "dmsetup ls --tree" output to lvmdump. +- Fix udev synchronization with no-locking --sysinit (2.02.80). +- Improve man page style consistency for pvcreate, pvremove, pvresize, pvscan. +- Avoid rebuilding of uuid validation table. +- Improve lvcreate error text from insufficient "extents" to "free space". +- Always use O_DIRECT when opening block devices to check for partitioning. +- Move creation of device nodes from 'create' to 'resume'. +- Add --addnodeonresume and --addnodeoncreate options to dmsetup. +- Add dm_task_set_add_node to libdevmapper to control dev node creation time. +- Add dm_task_secure_data to libdevmapper to wipe ioctl buffers in kernel. +- Log debug message when expected uevent is not generated. +- Set DM_UDEV_DISABLE_OTHER_RULES_FLAG for suspended DM devices in udev rules. +- Begin a new pool object for each row in _output_as_rows() correctly. + +* Mon Jan 24 2011 Alasdair Kergon - 2.02.82-2 +- Bring lvscan man page up-to-date. +- Fix lvchange --test to exit cleanly. +- Add change_tag to toollib. +- Allow multiple pvchange command line options to be specified together. +- Do not fail pvmove polling if another process cleaned up first. +- Avoid clvmd incrementing dlm lockspace reference count more than once. +- Add -f (don't fork) option to clvmd and fix clvmd -d description. + +* Mon Jan 17 2011 Alasdair Kergon - 2.02.81-1 +- Add disk to allowed mirrored log type conversions. +- Accept fusion fio in device type filter. +- Speed up command processing by caching resolved config tree. +- Use same dm cookie for consecutive dm ops in same VG to reduce udev waits. +- Do not scan devices in dev_reset_error_count() when forking. +- Skip unnecessary LOCK_NULL unlock call during volume deactivation. +- Skip fs_unlock when calling exec_cmd within activation code (for modprobe). +- Replace fs_unlock by sync_local_dev_names to notify local clvmd. (2.02.80) +- Fix wrongly paired unlocking of VG_GLOBAL in pvchange. (2.02.66) +- Return 0 from cmirrord initscript 'start' if daemon is already running. +- Add DM_COOKIE_AUTO_CREATE to libdevmapper.h. +- Improve general lvconvert man page description. +- Detect NULL handle in get_property(). +- Fix memory leak in persistent filter creation error path. +- Check for errors setting up dm_task struct in _setup_task(). +- Fail polldaemon creation when lvmcache_init() fails. +- Return PERCENT_INVALID for errors in _copy_percent() and _snap_percent(). +- Detect errors from dm_task_set calls in _get_device_info (dmeventd). +- Fix memory leak in debug mode of restart_clvmd() error path. +- Log error message for pthread_join() failure in clvmd. +- Use tmpfiles.d/lvm2.conf to create /var/lock/lvm and /var/run/lvm at boot. +- Require initscripts for tmpfiles.d/lvm2.conf. + +* Tue Dec 21 2010 Alasdair Kergon - 2.02.79-1 +- Create /var/run/lvm directory during clvmd initialisation if missing. +- Avoid revalidating the label cache immediately after scanning. +- Support scanning for a single VG in independent mdas. +- Don't skip full scan when independent mdas are present even if memlock is set. +- Add copy_percent and snap_percent to liblvm. +- Add new dm_prepare_selinux_context fn to libdevmapper and use it throughout. +- Enhance vg_validate to ensure integrity of LV and PV structs referenced. +- Enhance vg_validate to check composition of pvmove LVs. +- Avoid writing to freed memory in vg_release. (2.02.78) +- Add missing test for reallocation error in _find_parallel_space(). +- Add checks for allocation errors in config node cloning. +- Fix error path if regex engine cannot be created in _build_matcher(). +- Check read() and close() results in _get_cmdline(). +- Fix NULL pointer check in error path in clvmd do_command(). (2.02.78) +- Check for unlink failure in remove_lockfile() in dmeventd. +- Use dm_free for dm_malloc-ed areas in _clog_ctr/_clog_dtr in cmirrord. +- Change dm_regex_create() API to accept const char * const *patterns. + +* Mon Dec 6 2010 Alasdair Kergon - 2.02.78-1 +- Miscellaneous error path corrections and minor leaks fixed. +- Avoid misleading PV missing warnings in vgextend --restoremissing. +- Ignore unrecognised allocation policy found in metadata instead of aborting. +- Disallow lvconvert ops that both allocate & free supplied PEs in a single cmd. +- Fix liblvm seg_size to give bytes not sectors. +- Add functions to look up LV/PV by name/uuid to liblvm. +- Suppress 'No PV label' message when removing several PVs without mdas. +- Fix default /etc/lvm permissions to be 0755. (2.02.66) + +* Mon Nov 22 2010 Alasdair Kergon - 2.02.77-1 +- Add PV and LV segment types and functions to liblvm. +- Add set_property functions to liblvm. +- Remove tag length restriction and allow / = ! : # & characters. +- Support repetition of --addtag and --deltag arguments. +- Add infrastructure for specific cmdline arguments to be repeated in groups. +- Fix fsadm no longer to require '-f' to resize an unmounted filesystem. +- Fix fsadm to detect mounted filesystems on older systems. (2.0.75) +- Extend cling allocation policy to recognise PV tags (cling_by_tags). +- Add allocation/cling_tag_list to lvm.conf. + +* Tue Nov 9 2010 Alasdair Kergon - 2.02.76-1 +- Clarify error messages when activation fails due to activation filter use. +- Fix handling of online filesystem resize (using new fsadm return code). +- Modify fsadm to return different status code for check of mounted filesystem. +- Add DIAGNOSTICS section to fsadm man page. +- Update VG metadata only once in vgchange when making multiple changes. +- Allow independent vgchange arguments to be used together. +- Fix vgchange to process -a, --refresh, --monitor and --poll like lvchange. +- Add dmeventd -R to restart dmeventd without losing monitoring state. (1.02.56) +- Automatically unmount invalidated snapshots in dmeventd. +- Add lvm2app functions to query any pv, vg, or lv property / report field. +- Fix a deadlock caused by double close in clvmd. +- Fix NULL pointer dereference on too-large MDA error path in _vg_read_raw_area. +- Fix regex optimiser not to ignore RHS of OR nodes in _find_leftmost_common. +- Fix memory leak of field_id in _output_field function. +- Allocate buffer for reporting functions dynamically to support long outputs. + +* Mon Oct 25 2010 Alasdair Kergon - 2.02.75-1 +- Fix pthread mutex usage deadlock in clvmd. +- Avoid segfault by limiting partial mode for lvm1 metadata. (2.02.74) +- Skip dm devices in scan if they contain only error targets or are empty. +- Don't take write lock in vgchange --refresh, --poll or --monitor. +- Fix hang when repairing a mirrored-log that had both devs fail. +- Speed up unquoting of quoted double quotes and backslashes. +- Speed up CRC32 calculations by using a larger lookup table. +- Implement dmeventd -R to restart without state loss. +- Add --setuuid to dmsetup rename. +- Add global/metadata_read_only to use unrepaired metadata in read-only cmds. +- Automatically extend snapshots with dmeventd according to policy in lvm.conf. +- Add activation/snapshot_autoextend_threshold/percent to lvm.conf. +- Add devices/disable_after_error_count config to limit access to failing devs. +- Implement vgextend --restoremissing to reinstate missing devs that return. +- Read whole /proc/self/maps file before working with maps entries. +- Convey need for snapshot-merge target in lvconvert error message and man page. +- Give correct error message when creating a too-small snapshot. +- Make lvconvert respect --yes and --force when converting an inactive log. +- Better support of noninteractive shell execution of fsadm. +- Fix usage of --yes flag for ReiserFS resize in fsadm. +- Fix detection of mounted filesystems for fsadm when udev is used. +- Fix assignment of default value to LVM variable in fsadm. +- Fix support for --yes flag for fsadm. +- Do not execute lvresize from fsadm --dry-run. +- Fix fsadm return error code from user's break action. +- Return const pointer from dm_basename() in libdevmapper. +- Add dm_zalloc and use it and dm_pool_zalloc throughout. +- Add dm_task_set_newuuid to set uuid of mapped device post-creation. +- Fix missing variable initialization in cluster_send() function from cmirrord. +- Fix pointer for VG name in _pv_resize_single error code path. +- Fix vg_read memory leak with directory-based metadata. +- Fix memory leak of config_tree in reinitialization code path. +- Fix pool destruction order in dmeventd_lvm2_exit() to avoid leak debug mesg. +- Remove dependency on libm by replacing floor() by an integer-based algorithm. +- Refactor and add 'get' functions for pv, vg and lv properties/fields. +- Add pv_get_property and create generic internal _get_property function. +- Make generic GET_*_PROPERTY_FN macros with secondary macro for vg, pv & lv. + +* Fri Oct 15 2010 Alasdair Kergon - 2.02.73-3 +- Add --setuuid to dmsetup rename. +- Add dm_task_set_newuuid to set uuid of mapped device post-creation. + +* Wed Sep 29 2010 jkeating - 2.02.74-2 +- Rebuilt for gcc bug 634757 + +* Fri Sep 24 2010 Alasdair Kergon - 2.02.74-1 +- Fix the way regions are marked complete to avoid slow --nosync cmirror I/O. +- Add DM_REPORT_FIELD_TYPE_ID_LEN to libdevmapper.h. +- Allow : and @ to be escaped with \ in device names of PVs. +- Avoid stack corruption when reading in large metadata. +- Fix partial mode operations for lvm1 metadata format. +- Track recursive filter iteration to avoid refreshing while in use. (2.02.56) +- Allocate buffer for metadata tags dynamically to remove 4k limit. +- Add random suffix to archive file names to prevent races when being created. +- Reinitialize archive and backup handling on toolcontext refresh. +- Make poll_mirror_progress report PROGRESS_CHECK_FAILED if LV is not a mirror. +- Like mirrors, don't scan origins if ignore_suspended_devices() is set. +- Automatically generate tailored LSB Requires-Start for clvmd init script. +- Fix return code of pvmove --abort PV. +- Fix pvmove --abort to remove even for empty pvmove LV. +- Add implementation for simple numeric 'get' property functions. +- Simplify MD/swap signature detection in pvcreate and allow aborting. +- Allow --yes to be used without --force mode. +- Fix file descriptor leak in swap signature detection error path. +- Detect and allow abort in pvcreate if LUKS signature is detected. + +* Wed Aug 25 2010 Peter Rajnoha - 2.02.73-2 +- Add configure --with-default-data-alignment. +- Update heuristic used for default and detected data alignment. +- Add "devices/default_data_alignment" to lvm.conf. + +* Wed Aug 18 2010 Alasdair Kergon - 2.02.73-1 +- Change default alignment of data extents to 1MB. +- Add --norestorefile option to pvcreate. +- Require --restorefile when using pvcreate --uuid. +- Fix potential for corruption during cluster mirror device failure. +- Ignore snapshots when performing mirror recovery beneath an origin. +- Monitor origin -real device below snapshot instead of overlay device. +- Don't really change monitoring status when in test mode. +- Fix some exit statuses when starting/stopping monitoring fails. +- Enable snapshot monitoring by default when dmeventd is enabled. +- Fix 'lvconvert --splitmirrors' in cluster operation. +- Fix clvmd init script exit code to return 4 when executed as non-root user. +- Recognise and give preference to md device partitions (blkext major). +- Never scan internal LVM devices. +- Don't ignore user-specified PVs in split-mirror operations. (2.02.71) +- Fix data corruption bug in cluster mirrors. +- Require logical volume(s) to be explicitly named for lvconvert --merge. +- Avoid changing aligned pe_start as a side-effect of a log message. +- Use built-in rule for device aliases: block/ < dm- < disk/ < mapper/ < other. +- Handle failure of all mirrored log devices and all but one mirror leg. +- Disallow 'mirrored' log type for cluster mirrors. +- Fix configure to supply DEFAULT_RUN_DIR to Makefiles. +- Fix allocation of wrong number of mirror logs with 'remove' fault policy. +- Add dmeventd/executable to lvm.conf to test alternative dmeventd. +- Fix udev rules to support udev database content generated by older rules. +- Reinstate detection of inappropriate uevent with DISK_RO set and suppress it. +- Fix regex ttree off-by-one error. +- Fix segfault in regex matcher with characters of ordinal value > 127. +- Wait for node creation before displaying debug info in dmsetup. +- Fix return status 0 for "dmsetup info -c -o help". + +* Mon Aug 2 2010 Alasdair Kergon - 2.02.72-5 +- Make udev configurable and merge with f12. + +* Mon Aug 2 2010 Alasdair Kergon - 2.02.72-4 +- Merge f13, f14 and rawhide spec files. + +* Sat Jul 31 2010 Alasdair Kergon - 2.02.72-3 +- Address lvm2-cluster security flaw CVE-2010-2526. + https://bugzilla.redhat.com/CVE-2010-2526 +- Change clvmd to communicate with lvm2 via a socket in /var/run/lvm. +- Return controlled error if clvmd is run by non-root user. +- Never use clvmd singlenode unless explicitly requested with -Isinglenode. +- Fix exported_symbols generation to use standard compiler arguments. +- Use #include <> not "" in lvm2app.h which gets installed on the system. +- Make liblvm.device-mapper wait for include file generation. +- Fix configure to supply DEFAULT_RUN_DIR to Makefiles. +- Fix wrong number of mirror log at allocate policy + +* Wed Jul 28 2010 Alasdair Kergon - 2.02.71-1 +- Make vgck warn about missing PVs. +- Revert failed table load preparation after "create, load and resume". +- Check if cluster log daemon is running before allowing cmirror create. +- Add dm_create_lockfile to libdm and use for pidfiles for all daemons. +- Correct LV list order used by lvconvert when splitting a mirror. +- Check if LV with specified name already exists when splitting a mirror. +- Fix suspend/resume logic for LVs resulting from splitting a mirror. +- Fix possible hang when all mirror images of a mirrored log fail. +- Adjust auto-metadata repair and caching logic to try to cope with empty mdas. +- Update pvcreate, {pv|vg}change, and lvm.conf man pages about metadataignore. +- Prompt if metadataignore with vgextend or pvchange would adjust vg_mda_copies. +- Adjust vg_mda_copies if metadataignore given with vgextend or pvchange. +- Speed up the regex matcher. +- Use "nowatch" udev rule for inappropriate devices. +- Document LVM fault handling in lvm_fault_handling.txt. +- Clarify help text for vg_mda_count. +- Add more verbose messages while checking volume_list and hosttags settings. +- Add log_error when strdup fails in {vg|lv}_change_tag(). +- Do not log backtrace in valid _lv_resume() code path. + +* Wed Jul 7 2010 Alasdair Kergon - 2.02.70-1 +- Remove log directly if all mirror images of a mirrored log fail. +- Randomly select which mdas to use or ignore. +- Add printf format attributes to yes_no_prompt and fix a caller. +- Always pass unsuspended dm devices through persistent filter to other filters. +- Move test for suspended dm devices ahead of other filters. +- Fix another segfault in clvmd -R if no response from daemon received. (2.02.68) +- Remove superfluous suspended device counter from clvmd. +- Fix lvm shell crash when input is entirely whitespace. +- Update partial mode warning message. +- Preserve memlock balance in clvmd when activation triggers a resume. +- Restore the removemissing behaviour of lvconvert --repair --use-policies. + +* Wed Jun 30 2010 Alasdair Kergon - 2.02.69-1 +- Fix vgremove to allow removal of VG with missing PVs. (2.02.52) +- Add metadata/vgmetadatacopies to lvm.conf. +- Add --metadataignore to pvcreate and vgextend. +- Add vg_mda_copies, pv_mda_used_count and vg_mda_used_count to reports. +- Describe --vgmetadatacopies in lvm.conf and other man pages. +- Add --[vg]metadatacopies to select number of mdas to use in a VG. +- Make the metadata ignore bit control read/write metadata areas in a PV. +- Add pvchange --metadataignore to set or clear a metadata ignore bit. +- Refactor metadata code to prepare for --metadataignore / --vgmetadatacopies. +- Ensure region_size of mirrored log does not exceed its full size. +- Preload libc locale messages to prevent reading it in memory locked state. +- Fix handling of simultaneous mirror image and mirrored log image failure. + +* Thu Jun 24 2010 Peter Rajnoha - 2.02.68-2 +- Fix udev rules to handle spurious events properly. +- Add Requires: udev >= 158-1 (needed for the change in udev rules). + +* Wed Jun 23 2010 Alasdair Kergon - 2.02.68-1 +- Have device-mapper-libs require device-mapper (circular) for udev rules. +- Clear exec_prefix. +- Use early udev synchronisation and update of dev nodes for clustered mirrors. +- Add lv_path to reports to offer full /dev pathname. +- Avoid abort when generating cmirror status. +- Fix clvmd initscript status to print only active clustered LVs. +- Fix segfault in clvmd -R if no response from daemon received. +- Honour log argument when down-converting stacked mirror. +- Sleep to workaround clvmd -S race: socket closed early and server drops cmd. +- Exit successfully when using -o help (but not -o +help) with LVM reports. +- Add man pages for lvmconf, dmeventd and non-existent lvmsadc and lvmsar tools. +- Add --force, --nofsck and --resizefs to lvresize/extend/reduce man pages. +- Fix lvm2cmd example in documentation. +- Fix typo in warning message about missing device with allocated data areas. +- Add device name and offset to raw_read_mda_header error messages. +- Allow use of lvm2app and lvm2cmd headers in C++ code. + +* Fri Jun 4 2010 Alasdair Kergon - 2.02.67-1 +- Require partial option in lvchange --refresh for partial LVs. +- Don't merge unchanged persistent cache file before dumping if tool scanned. +- Avoid selecting names under /dev/block if there is an alternative. +- Fix semctl parameter (union) to avoid misaligned parameter on some arches. +- Fix clvmd initscript restart command to start clvmd if not yet running. +- Handle failed restart of clvmd using -S switch properly. +- Use built-in absolute paths in clvmd (clvmd restart and PV and LV queries). +- Consistently return ECMD_FAILED if interrupted processing multiple LVs. +- Add --type parameter description to the lvcreate man page. +- Document 'clear' in dmsetup man page. +- Replace strncmp kernel version number checks with proper ones. +- Update clustered log kernel module name to log-userspace for 2.6.31 onwards. +- Support autoloading of dm-mod module for kernels from 2.6.35. +- Add dm_tree_node_set_presuspend_node() to presuspend child when deactivating. +- Do not fail lvm_init() if init_logging() or _init_rand() generates an errno. +- Fix incorrect memory pool deallocation while using vg_read for files. + +* Thu May 20 2010 Alasdair Kergon - 2.02.66-2 +- Simplify and fix Requires package headers. +- If unable to obtain snapshot percentage leave value blank on reports. +- Use new install_system_dirs and install_initscripts makefile targets. +- Add lvm2app functions to lookup a vgname from a pvid and pvname. +- Change internal processing of PVs in pvchange. +- Validate internal lock ordering of orphan and VG_GLOBAL locks. + +* Mon May 17 2010 Alasdair Kergon - 2.02.65-1 +- Disallow vgchange --clustered if there are active mirrors or snapshots. +- Fix truncated total size displayed by pvscan. +- Skip internal lvm devices in scan if ignore_suspended_devices is set. +- Do not merge old device cache after we run full scan. (2.02.56) +- Add new --sysinit compound option to vgchange and lvchange. +- Fix clvmd init script never to deactivate non-clustered volume groups. +- Drop duplicate errors for read failures and missing devices to verbose level. +- Do not print encryption key in message debug output (cryptsetup luksResume). +- Use -d to control level of messages sent to syslog by dmeventd. +- Change -d to -f to run dmeventd in foreground. +- Fix udev flags on remove in create_and_load error path. +- Add dm_list_splice() function to join two lists together. +- Use /bin/bash for scripts with bashisms. +- Switch Libs.private to Requires.private in devmapper.pc and lvm2app.pc. +- Use pkgconfig Requires.private for devmapper-event.pc. + +* Fri Apr 30 2010 Alasdair Kergon - 2.02.64-1 +- Avoid pointless initialisation when the 'version' command is run directly. +- Fix memory leak for invalid regex pattern input. +- Display invalid regex pattern for filter configuration in case of error. +- Fix -M and --type to use strings, not pointers that change on config refresh. +- Fix lvconvert error message when existing mirrored LV is not found. +- Set appropriate udev flags for reserved LVs. +- Disallow the direct removal of a merging snapshot. +- Don't preload the origin when removing a snapshot whose merge is pending. +- Disallow the addition of mirror images while a conversion is happening. +- Disallow primary mirror image removal when mirror is not in-sync. +- Remove obsolete --name parameter from vgcfgrestore. +- Add -S command to clvmd to restart the daemon preserving exclusive locks. +- Increment lvm2app version from 1 to 2 (memory allocation changes). +- Change lvm2app memory alloc/free for pv/vg/lv properties. +- Change daemon lock filename from lvm2_monitor to lvm2-monitor for consistency. +- Add support for new IMPORT{db} udev rule. +- Add DM_UDEV_PRIMARY_SOURCE_FLAG udev flag to recognize proper DM events. +- Also include udev libs in libdevmapper.pc. +- Cache bitset locations to speed up _calc_states. +- Add a regex optimisation pass for shared prefixes and suffixes. +- Add dm_bit_and and dm_bitset_equal to libdevmapper. +- Speed up dm_bit_get_next with ffs(). + +* Thu Apr 15 2010 Alasdair Kergon - 2.02.63-2 +- Remove 'lvmconf --lockinglibdir' from cluster post: locking is now built-in. +- Move libdevmapper-event-lvm2.so to devel package. +- Explicitly specify libdevmapper-event.so* attributes. +- Drop support for upgrades from very old versions that used lvm not lvm2. +- Move libdevmapper-event plug-in libraries into new device-mapper subdirectory. +- Don't verify lvm.conf contents when using rpm --verify. + +* Wed Apr 14 2010 Alasdair Kergon - 2.02.63-1 +- Move development links to shared objects to /usr (hard-coded temporarily). +- Change libdevmapper deactivation to fail if device is open. +- Wipe memory buffers for libdevmapper dm-ioctl parameters before releasing. +- Strictly require libudev if udev_sync is used. +- Add support for ioctl's DM_UEVENT_GENERATED_FLAG. +- Allow incomplete mirror restore in lvconvert --repair upon insufficient space. +- Do not reset position in metadata ring buffer on vgrename and vgcfgrestore. +- Allow VGs with active LVs to be renamed. +- Only pass visible LVs to tools in cmdline VG name/tag expansions without -a. +- Use C locale and mlockall in clvmd and dmeventd. +- Mask LCK_HOLD in cluster VG locks for upgrade compatibility with older clvmd. +- Add activation/polling_interval to lvm.conf as --interval default. +- Don't ignore error if resuming any LV fails when resuming groups of LVs. +- Skip closing persistent filter cache file if open failed. +- Permit mimage LVs to be striped in lvcreate, lvresize and lvconvert. +- Fix pvmove allocation to take existing parallel stripes into account. +- Fix incorrect removal of symlinks after LV deactivation fails. +- Fix is_partitioned_dev not to attempt to reopen device. +- Fix another thread race in clvmd. +- Improve vg_validate to detect some loops in lists. +- Change most remaining log_error WARNING messages to log_warn. +- Always use blocking lock for VGs and orphan locks. +- Allocate all memory for segments from private VG mempool. +- Optimise searching PV segments for seeking the most recently-added. +- Remove duplicated vg_validate checks when parsing cached metadata. +- Use hash table of LVs to speed up parsing of text metadata with many LVs. +- Fix two vg_validate messages, adding whitespace and parentheses. +- When dmeventd is not forking because of -d flag, don't kill parent process. +- Fix dso resource leak in error path of dmeventd. +- Fix --alloc contiguous policy only to allocate one set of parallel areas. +- Do not allow {vg|lv}change --ignoremonitoring if on clustered VG. +- Add ability to create mirrored logs for mirror LVs. +- Fix clvmd cluster propagation of dmeventd monitoring mode. +- Allow ALLOC_ANYWHERE to split contiguous areas. +- Add some assertions to allocation code. +- Introduce pv_area_used into allocation algorithm and add debug messages. +- Add activation/monitoring to lvm.conf. +- Add --monitor and --ignoremonitoring to lvcreate. +- Don't allow resizing of internal logical volumes. +- Fix libdevmapper-event pkgconfig version string to match libdevmapper. +- Avoid scanning all pvs in the system if operating on a device with mdas. +- Disable long living process flag in lvm2app library. +- Fix pvcreate device md filter check. +- Suppress repeated errors about the same missing PV uuids. +- Bypass full device scans when using internally-cached VG metadata. +- Only do one full device scan during each read of text format metadata. +- Look up missing PVs by uuid not dev_name in pvs to avoid invalid stat. + +* Tue Mar 09 2010 Alasdair Kergon - 2.02.62-1 +- Rewrite clvmd init script. +- Add default alternative to mlockall using mlock to reduce pinned memory size. +- Add use_mlockall and mlock_filter to activation section of lvm.conf. +- Handle misaligned devices that report alignment_offset of -1. +- Extend core allocation code in preparation for mirrored log areas. +- No longer fall back to looking up active devices by name if uuid not found. +- Don't touch /dev in vgmknodes if activation is disabled. +- Add --showkeys parameter description to dmsetup man page. +- Add --help option as synonym for help command. +- Add lvm2app functions lvm_{vg|lv}_{get|add|remove}_tag() functions. +- Refactor snapshot-merge deptree and device removal to support info-by-uuid. + +* Fri Mar 05 2010 Peter Rajnoha - 2.02.61-2 +- Change spec file to support excluding cluster components from the build. + +* Tue Feb 16 2010 Alasdair Kergon - 2.02.61-1 +- Add %%ORIGIN support to lv{create,extend,reduce,resize} --extents. +- Accept a list of LVs with 'lvconvert --merge @tag' using process_each_lv. +- Remove false "failed to find tree node" error when activating merging origin. +- Exit with success when lvconvert --repair --use-policies performs no action. +- Avoid unnecessary second resync when adding mimage to core-logged mirror. +- Make clvmd -V return status zero. +- Fix cmirrord segfault in clog_cpg list processing when converting mirror log. +- Deactivate temporary pvmove mirror cluster-wide when activating it fails. +- Add missing metadata vg_reverts in pvmove error paths. +- Unlock shared lock in clvmd if activation calls fail. +- Add lvm_pv_get_size, lvm_pv_get_free and lvm_pv_get_dev_size to lvm2app. +- Change lvm2app to return all sizes in bytes as documented (not sectors). +- Exclude internal VG names and uuids from lists returned through lvm2app. +- Add LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES environment variable. +- Add DM_UDEV_DISABLE_LIBRARY_FALLBACK udev flag to rely on udev only. +- Remove hard-coding that skipped _mimage devices from 11-dm-lvm.rules. +- Export dm_udev_create_cookie function to create new cookies on demand. +- Add --udevcookie, udevcreatecookie and udevreleasecookie to dmsetup. +- Set udev state automatically instead of using DM_UDEV_DISABLE_CHECKING. +- Set udev state automatically instead of using LVM_UDEV_DISABLE_CHECKING. +- Remove pointless versioned symlinks to dmeventd plugin libraries. + +* Fri Jan 29 2010 Alasdair Kergon - 2.02.60-5 +- Replace spaces with tabs in a couple of places in spec file. + +* Sat Jan 23 2010 Alasdair Kergon - 2.02.60-4 +- Extend cmirrord man page. +- Sleep before first progress check iff pvmove/lvconvert interval has prefix '+'. +- Fix cmirror initscript syntax problems. +- Fix first syslog message prefix for dmeventd plugins. +- Make failed locking initialisation messages more descriptive. + +* Fri Jan 22 2010 Alasdair Kergon - 2.02.59-3 +- Fix dmeventd lvm2 wrapper (plug-ins unusable in last build). +- Make failed locking initialisation messages more descriptive. + +* Fri Jan 22 2010 Fabio M. Di Nitto - 2.02.59-2 +- Drop duplicated BuildRequires on openaislib-devel. +- Drop Requires on clusterlib for cmirror subpackage. +- clvmd subpackage should Requires cman (#506592). + +* Fri Jan 22 2010 Alasdair Kergon - 2.02.59-1 +- Add cmirror subpackage for clustered mirrors. +- Set 'preferred_names' in default lvm.conf. +- Add libdevmapper-event-lvm2.so to serialise dmeventd plugin liblvm2cmd use. +- Stop dmeventd trying to access already-removed snapshots. +- Fix clvmd to never scan suspended devices. +- Fix detection of completed snapshot merge. +- Improve snapshot merge metadata import validation. + +* Thu Jan 14 2010 Alasdair Kergon - 2.02.58-1 +- Fix clvmd automatic target module loading crash. +- Fix allocation code not to stop at the first area of a PV that fits. +- Add support for the "snapshot-merge" kernel target (2.6.33-rc1). +- Add --merge to lvconvert to merge a snapshot into its origin. + +* Tue Jan 12 2010 Alasdair Kergon - 2.02.57-1 +- Add --splitmirrors to lvconvert to split off part of a mirror. +- Allow vgremove to remove a VG with PVs missing after a prompt. +- Add activation/udev_rules config option in lvm.conf. +- Add --poll flag to vgchange and lvchange to control background daemon launch. +- Impose limit of 8 mirror images to match the in-kernel kcopyd restriction. +- Log failure type and recognise type 'F' (flush) in dmeventd mirror plugin. +- Add --noudevrules option for dmsetup to disable /dev node management by udev. +- Fix 'dmsetup info -c -o all' to show all fields. +- Fix coredump and memory leak for 'dmsetup help -c'. +- Rename mirror_device_fault_policy to mirror_image_fault policy. +- Use extended status of new kernel snapshot target 1.8.0 to detect when empty. +- Allow use of precommitted metadata when a PV is missing. +- Add global/abort_on_internal_errors to lvm.conf to assist testing. +- If aborting due to internal error, always send that message to stderr. +- Keep log type consistent when changing mirror image count. +- Exit with success in lvconvert --repair --use-policies on failed allocation. +- Ensure any background daemon exits without duplicating parent's functionality. +- Change background daemon process names to "(lvm2)". +- Fix internal lock state after forking. +- Remove empty PV devices if lvconvert --repair is using defined policies. +- Use fixed buffer to prevent stack overflow in persistent filter dump. +- Propagate metadata commit and revert notifications to other cluster nodes. +- Fix metadata caching and lock state propagation to remote nodes in clvmd. +- Properly decode all flags in clvmd messages including VG locks. +- Drop cached metadata after device was auto-repaired and removed from VG. +- Clear MISSING_PV flag if PV reappeared and is empty. +- Fix removal of multiple devices from a mirror. +- Also clean up PVs flagged as missing in vgreduce --removemissing --force. +- Fix some pvresize and toollib error paths with missing VG releases/unlocks. +- Explicitly call suspend for temporary mirror layer. +- Add memlock information to do_lock_lv debug output. +- Always bypass calls to remote cluster nodes for non-clustered VGs. +- Permit implicit cluster lock conversion in pre/post callbacks on local node. +- Permit implicit cluster lock conversion to the lock mode already held. +- Fix lock flag masking in clvmd so intended code paths get invoked. +- Remove newly-created mirror log from metadata if initial deactivation fails. +- Improve pvmove error message when all source LVs are skipped. +- Fix memlock imbalance in lv_suspend if already suspended. +- Fix pvmove test mode not to poll (and fail). +- Fix vgcreate error message if VG already exists. +- Fix tools to use log_error when aborted due to user response to prompt. +- Fix ignored readahead setting in lvcreate --readahead. +- Fix clvmd memory leak in lv_info_by_lvid by calling release_vg. +- If LVM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings. +- If DM_UDEV_DISABLE_CHECKING is set in environment, disable udev warnings. +- Always set environment variables for an LVM2 device in 11-dm-lvm.rules. +- Disable udev rules for change events with DISK_RO set. +- Add dm_tree_add_dev_with_udev_flags to provide wider support for udev flags. +- Correct activated or deactivated text in vgchange summary message. +- Fix fsadm man page typo (fsdam). + +* Tue Nov 24 2009 Alasdair Kergon - 2.02.56-2 +- Revert vg_read_internal change as clvmd was not ready for vg_read. (2.02.55) +- Fix unbalanced memory locking when deactivating LVs. +- Add missing vg_release to pvs and pvdisplay to fix memory leak. +- Do not try to unlock VG which is not locked when processing a VG. +- Update .cache file after every full device rescan in clvmd. +- Refresh all device filters (including sysfs) before each full device rescan. +- Return error status if vgchange fails to activate any volume. + +* Thu Nov 19 2009 Alasdair Kergon - 2.02.55-1 +- Fix deadlock when changing mirrors due to unpaired memlock refcount changes. +- Fix pvmove region_size overflow for very large PVs. +- Fix lvcreate and lvresize %%PVS argument always to use sensible total size. +- Directly restrict vgchange to activating visible LVs. +- Fix hash lookup segfault when keys compared are different lengths. +- Flush stdout after yes/no prompt. +- Recognise DRBD devices and handle them like md devices. +- Add dmsetup --inactive support (requires kernel support targetted for 2.6.33). + +* Fri Nov 13 2009 Peter Rajnoha - 2.02.54-3 +- Support udev flags even when udev_sync is disabled. +- Remove last_rule from udev_rules. +- Udev rules cleanup. + +* Tue Nov 3 2009 Peter Rajnoha - 2.02.54-2 +- Enable udev synchronisation code. +- Install default udev rules for device-mapper and LVM2. +- Add BuildRequires: libudev-devel. +- Add Requires: libudev (to check udev is running). +- Add Requires: util-linux-ng (blkid used in udev rules). +- Add Conflicts: dracut < 002-18 (for dracut to install required udev rules) + +* Tue Oct 27 2009 Alasdair Kergon - 2.02.54-1 +- Add implict pvcreate support to vgcreate and vgextend. +- Add --pvmetadatacopies for pvcreate, vgcreate, vgextend, vgconvert. +- Distinguish between powers of 1000 and powers of 1024 in unit suffixes. +- Restart lvconverts in vgchange. +- Don't attempt to deactivate an LV if any of its snapshots are in use. +- Return error if lv_deactivate fails to remove device from kernel. +- Treat input units of both 's' and 'S' as 512-byte sectors. (2.02.49) +- Use standard output units for 'PE Size' and 'Stripe size' in pv/lvdisplay. +- Add global/si_unit_consistency to enable cleaned-up use of units in output. +- Only do lock conversions in clvmd if we are explicitly asked for one. +- Fix clvmd segfault when refresh_toolcontext fails. +- Cleanup mimagetmp LV if allocation fails for new lvconvert mimage. +- Handle metadata with unknown segment types more gracefully. +- Make clvmd return 0 on success rather than 1. +- Correct example.conf to indicate that lvm2 not lvm1 is the default format. +- Delay announcing mirror monitoring to syslog until initialisation succeeded. +- Update lvcreate/lvconvert man pages to explain PhysicalVolume parameter. +- Document --all option in man pages and cleanup {pv|vg|lv}{s|display} pages. + +* Mon Oct 19 2009 Fabio M. Di Nitto - 2.02.53-3 +- Enable openais support in clvmd. + +* Fri Sep 25 2009 Alasdair Kergon - 2.02.53-2 +- Reissued tarball to fix compilation warning from lvm2_log_fn prototype. + +* Fri Sep 25 2009 Alasdair Kergon - 2.02.53-1 +- Create any directories in /dev with umask 022. (#507397) +- Handle paths supplied to dm_task_set_name by getting name from /dev/mapper. +- Add splitname and --yes to dmsetup man page. + +* Thu Sep 24 2009 Peter Rajnoha - 2.02.52-4 +- Disable udev synchronisation code (revert previous build). + +* Mon Sep 21 2009 Peter Rajnoha - 2.02.52-3 +- Enable udev synchronisation code. +- Install default udev rules for device-mapper and LVM2. +- Add BuildRequires: libudev-devel. +- Add Requires: libudev (to check udev is running). +- Add Requires: util-linux-ng (blkid used in udev rules). + +* Wed Sep 16 2009 Alasdair Kergon - 2.02.52-2 +- Build dmeventd and place into a separate set of subpackages. +- Remove no-longer-needed BuildRoot tag and buildroot emptying at install. + +* Tue Sep 15 2009 Alasdair Kergon - 2.02.52-1 +- Prioritise write locks over read locks by default for file locking. +- Add local lock files with suffix ':aux' to serialise locking requests. +- Fix readonly locking to permit writeable global locks (for vgscan). (2.02.49) +- Make readonly locking available as locking type 4. +- Fix global locking in PV reporting commands (2.02.49). +- Make lvchange --refresh only take a read lock on volume group. +- Fix race where non-blocking file locks could be granted in error. +- Fix pvcreate string termination in duplicate uuid warning message. +- Don't loop reading sysfs with pvcreate on a non-blkext partition (2.02.51). +- Fix vgcfgrestore error paths when locking fails (2.02.49). +- Make clvmd check corosync to see what cluster interface it should use. +- Fix vgextend error path - if ORPHAN lock fails, unlock / release vg (2.02.49). +- Clarify use of PE ranges in lv{convert|create|extend|resize} man pages. +- Restore umask when device node creation fails. +- Check kernel vsn to use 'block_on_error' or 'handle_errors' in mirror table. + +* Mon Aug 24 2009 Milan Broz - 2.02.51-3 +- Fix global locking in PV reporting commands (2.02.49). +- Fix pvcreate on a partition (2.02.51). +- Build clvmd with both cman and corosync support. + +* Thu Aug 6 2009 Alasdair Kergon - 2.02.51-2 +- Fix clvmd locking broken in 2.02.50-1. +- Only change LV /dev symlinks on ACTIVATE not PRELOAD (so not done twice). +- Make lvconvert honour log mirror options combined with downconversion. +- Add devices/data_alignment_detection to lvm.conf. +- Add devices/data_alignment_offset_detection to lvm.conf. +- Add --dataalignmentoffset to pvcreate to shift start of aligned data area. +- Update synopsis in lvconvert manpage to mention --repair. +- Document -I option of clvmd in the man page. + +* Thu Jul 30 2009 Alasdair Kergon - 2.02.50-2 +- lvm2-devel requires device-mapper-devel. +- Fix lvm2app.pc filename. + +* Tue Jul 28 2009 Alasdair Kergon - 2.02.50-1 +- Add libs and devel subpackages to include shared libraries for applications. + N.B. The liblvm2app API is not frozen yet and may still be changed + Send any feedback to the mailing list lvm-devel@redhat.com. +- Remove obsolete --with-dmdir from configure. +- Add global/wait_for_locks to lvm.conf so blocking for locks can be disabled. +- Fix race condition with vgcreate and vgextend on same device since 2.02.49. +- Add an API version number, LVM_LIBAPI, to the VERSION string. +- Return EINVALID_CMD_LINE not success when invalid VG name format is used. +- Remove unnecessary messages after vgcreate/vgsplit code change in 2.02.49. +- Store any errno and error messages issued while processing each command. + +* Sat Jul 25 2009 Fedora Release Engineering - 2.02.49-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 15 2009 Alasdair Kergon - 2.02.49-1 +- Exclude VG_GLOBAL from vg_write_lock_held so scans open devs read-only again. +- Fix dev name mismatch in vgcreate man page example. +- Check md devices for a partition table during device scan. +- Add extended device (blkext) and md partition (mdp) types to filters. +- Make text metadata read errors for segment areas more precise. +- Fix text segment metadata read errors to mention correct segment name. +- Include segment and LV names in text segment import error messages. +- Fix memory leak in vgsplit when re-reading the vg. +- Permit several segment types to be registered by a single shared object. +- Update the man pages to document size units uniformly. +- Allow commandline sizes to be specified in terms of bytes and sectors. +- Update 'md_chunk_alignment' to use stripe-width to align PV data area. +- Fix segfault in vg_release when vg->cmd is NULL. +- Add dm_log_with_errno and dm_log_with_errno_init, deprecating the old fns. +- Fix whitespace in linear target line to fix identical table line detection. +- Add device number to more log messages during activation. + +* Fri Jul 10 2009 Fabio M. Di Nitto 2.02.48-2 +- BuildRequires and Requires on stable versions of both corosync-lib (1.0.0-1) + and cluster-lib (3.0.0-20). + +* Tue Jun 30 2009 Alasdair Kergon - 2.02.48-1 +- Abort if automatic metadata correction fails when reading VG to update it. +- Don't fallback to default major number in libdm: use dm_task_set_major_minor. +- Explicitly request fallback to default major number in device mapper. +- Ignore suspended devices during repair. +- Suggest using lvchange --resync when adding leg to not-yet-synced mirror. +- Destroy toolcontext on clvmd exit to avoid memory pool leaks. +- Fix lvconvert not to poll mirror if no conversion in progress. +- Fix memory leaks in toolcontext error path. +- Reinstate partial activation support in clustered mode. +- Allow metadata correction even when PVs are missing. +- Use 'lvm lvresize' instead of 'lvresize' in fsadm. +- Do not use '-n' realine option in fsadm for rescue disk compatiblity. +- Round up requested readahead to at least one page and print warning. +- Try to repair vg before actual vgremove when force flag provided. +- Unify error messages when processing inconsistent volume group. +- Introduce lvconvert --use_policies (repair policy according to lvm.conf). +- Fix rename of active snapshot with virtual origin. +- Fix convert polling to ignore LV with different UUID. +- Cache underlying device readahead only before activation calls. +- Fix segfault when calculating readahead on missing device in vgreduce. +- Remove verbose 'visited' messages. +- Handle multi-extent mirror log allocation when smallest PV has only 1 extent. +- Add LSB standard headers and functions (incl. reload) to clvmd initscript. +- When creating new LV, double-check that name is not already in use. +- Remove /dev/vgname/lvname symlink automatically if LV is no longer visible. +- Rename internal vorigin LV to match visible LV. +- Suppress 'removed' messages displayed when internal LVs are removed. +- Fix lvchange -a and -p for sparse LVs. +- Fix lvcreate --virtualsize to activate the new device immediately. +- Make --snapshot optional with lvcreate --virtualsize. +- Generalise --virtualoriginsize to --virtualsize. +- Skip virtual origins in process_each_lv_in_vg() without --all. +- Fix counting of virtual origin LVs in vg_validate. +- Attempt to load dm-zero module if zero target needed but not present. +- Add crypt target handling to libdevmapper tree nodes. +- Add splitname command to dmsetup. +- Add subsystem, vg_name, lv_name, lv_layer fields to dmsetup reports. +- Make mempool optional in dm_split_lvm_name() in libdevmapper. + +* Wed Jun 10 2009 Fabio M. Di Nitto - 2.02.47-2 +- BuildRequire newer version of corosynclib (0.97-1) to link against + latest libraries version (soname 4.0.0). +- Add lvm2-2_02_48-cluster-cpg-new-api.patch to port clvmd-corosync + to new corosync cpg API. + +* Fri May 22 2009 Alasdair Kergon - 2.02.47-1 +- Inherit readahead setting from underlying devices during activation. +- Detect LVs active on remote nodes by querying locks if supported. +- Enable online resizing of mirrors. +- Use suspend with flush when device size was changed during table preload. +- Implement query_resource_fn for cluster_locking. +- Support query_resource_fn in locking modules. +- Fix pvmove to revert operation if temporary mirror creation fails. +- Fix metadata export for VG with missing PVs. +- Add vgimportclone and install it and the man page by default. +- Force max_lv restriction only for newly created LV. +- Do not query nonexistent devices for readahead. +- Reject missing PVs from allocation in toollib. +- Fix PV datalignment for values starting prior to MDA area. (2.02.45) +- Add sparse devices: lvcreate -s --virtualoriginsize (hidden zero origin). +- Fix minimum width of devices column in reports. +- Add lvs origin_size field. +- Implement lvconvert --repair for repairing partially-failed mirrors. +- Fix vgreduce --removemissing failure exit code. +- Fix remote metadata backup for clvmd. +- Fix metadata backup to run after vg_commit always. +- Fix pvs report for orphan PVs when segment attributes are requested. +- Fix pvs -a output to not read volume groups from non-PV devices. +- Introduce memory pools per volume group (to reduce memory for large VGs). +- Always return exit error status when locking of volume group fails. +- Fix mirror log convert validation question. +- Enable use of cached metadata for pvs and pvdisplay commands. +- Fix memory leak in mirror allocation code. +- Save and restore the previous logging level when log level is changed. +- Fix error message when archive initialization fails. +- Make sure clvmd-corosync releases the lockspace when it exits. +- Fix segfault for vgcfgrestore on VG with missing PVs. +- Block SIGTERM & SIGINT in clvmd subthreads. +- Detect and conditionally wipe swapspace signatures in pvcreate. +- Fix maximal volume count check for snapshots if max_lv set for volume group. +- Fix lvcreate to remove unused cow volume if the snapshot creation fails. +- Fix error messages when PV uuid or pe_start reading fails. +- Flush memory pool and fix locking in clvmd refresh and backup command. +- Fix unlocks in clvmd-corosync. (2.02.45) +- Fix error message when adding metadata directory to internal list fails. +- Fix size and error message of memory allocation at backup initialization. +- Remove old metadata backup file after renaming VG. +- Restore log_suppress state when metadata backup file is up-to-date. +- Export dm_tree_node_size_changed() from libdevmapper. +- Fix segfault when getopt processes dmsetup -U, -G and -M options. +- Add _smp_mflags to compilation and remove DESTDIR. + +* Fri Apr 17 2009 Milan Broz - 2.02.45-4 +- Add MMC (mmcblk) device type to filters. (483686) + +* Mon Mar 30 2009 Jussi Lehtola 2.02.45-3 +- Add FTP server location to Source0. + +* Mon Mar 30 2009 Fabio M. Di Nitto - 2.02.45-2 +- BuildRequires a newer version of corosync (0.95-2) to fix linking. + +* Tue Mar 3 2009 Alasdair Kergon - 2.02.45-1 +- Update clusterlib and corosync dependencies. +- Attempt proper clean up in child before executing fsadm or modprobe. +- Do not scan devices if reporting only attributes from PV label. +- Use pkgconfig to obtain corosync library details during configuration. +- Fix error returns in clvmd-corosync interface to DLM. +- Add --refresh to vgchange and vgmknodes man pages. +- Pass --test from lvresize to fsadm as --dry-run. +- Prevent fsadm from checking mounted filesystems. +- No longer treats any other key as 'no' when prompting in fsadm. +- Add --dataalignment to pvcreate to specify alignment of data area. +- Fix unblocking of interrupts after several commands. +- Provide da and mda locations in debug message when writing text format label. +- Mention the restriction on file descriptors at invocation on the lvm man page. +- Index cached vgmetadata by vgid not vgname to cope with duplicate vgnames. +- No longer require kernel and metadata major numbers to match. +- If kernel supports only one dm major number, use in place of any supplied. +- Add option to /etc/sysconfig/cluster to select cluster type for clvmd. +- Allow clvmd to start up if its lockspace already exists. +- Separate PV label attributes which do not need parse metadata when reporting. +- Remove external dependency on the 'cut' command from fsadm. +- Fix pvs segfault when pv mda attributes requested for unavailable PV. +- Add fsadm support for reszing ext4 filesysystems. +- Change lvm2-cluster to corosync instead of cman. +- Fix some old changelog typos in email addresses. + +* Wed Feb 25 2009 Fedora Release Engineering - 2.02.44-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Tue Jan 27 2009 Alasdair Kergon - 2.02.44-1 +- Add --nameprefixes, --unquoted, --rows to pvs, vgs, lvs man pages. +- Fix lvresize size conversion for fsadm when block size is not 1K. +- Fix pvs segfault when run with orphan PV and some VG fields. +- Display a 'dev_size' of zero for missing devices in reports. +- Add pv_mda_size to pvs and vg_mda_size to vgs. +- Fix lvmdump /sys listing to include virtual devices directory. +- Add "--refresh" functionality to vgchange and vgmknodes. +- Avoid exceeding LV size when wiping device. +- Calculate mirror log size instead of using 1 extent. +- Ensure requested device number is available before activating with it. +- Fix incorrect exit status from 'help '. +- Fix vgrename using UUID if there are VGs with identical names. +- Fix segfault when invalid field given in reporting commands. +- Use better random seed value in temp file creation. +- Add read_urandom to read /dev/urandom. Use in uuid calculation. +- Fix race in vgcreate that would result in second caller overwriting first. +- Fix uninitialised lv_count in vgdisplay -c. +- Don't skip updating pvid hash when lvmcache_info struct got swapped. +- Fix startup race in clvmd. +- Cope with snapshot dependencies when removing a whole VG with lvremove. +- Make man pages and tool help text consistent using | for alternative options. +- Add "all" field to reports expanding to all fields of report type. +- Enforce device name length and character limitations in libdm. + +* Mon Nov 10 2008 Alasdair Kergon - 2.02.43-1 +- Upstream merge of device-mapper and lvm2 source. +- Correct prototype for --permission on lvchange and lvcreate man pages. +- Exit with non-zero status from vgdisplay if couldn't show any requested VG. +- libdevmapper.pc: Use simplified x.y.z version number. +- Accept locking fallback_to_* options in the global section as documented. +- Several fixes to lvconvert involving mirrors. +- Avoid overwriting in-use on-disk text metadata when metadataarea fills up. +- Generate man pages from templates and include version. +- Fix misleading error message when there are no allocatable extents in VG. +- Fix handling of PVs which reappeared with old metadata version. +- Fix validation of --minor and --major in lvcreate to require -My always. +- Allow lvremove to remove LVs from VGs with missing PVs. +- In VG with PVs missing, by default allow activation of LVs that are complete. +- Require --force with --removemissing in vgreduce to remove partial LVs. +- No longer write out PARTIAL flag into metadata backups. +- Treat new default activation/missing_stripe_filler "error" as an error target. +- Add devices/md_chunk_alignment to lvm.conf. +- Pass struct physical_volume to pe_align and adjust for md chunk size. +- Avoid shuffling remaining mirror images when removing one, retaining primary. +- Prevent resizing an LV while lvconvert is using it. +- Avoid repeatedly wiping cache while VG_GLOBAL is held in vgscan & pvscan. +- Fix pvresize to not allow resize if PV has two metadata areas. +- Fix setting of volume limit count if converting to lvm1 format. +- Fix vgconvert logical volume id metadata validation. +- Fix lvmdump metadata gather option (-m) to work correctly. +- Fix allocation bug in text metadata format write error path. +- Fix vgcfgbackup to properly check filename if template is used. +- vgremove tries to remove lv snapshot first. +- Improve file descriptor leak detection to display likely culprit and filename. +- Avoid looping forever in _pv_analyze_mda_raw used by pvck. +- Change lvchange exit status to indicate if any part of the operation failed. +- Fix pvchange and pvremove to handle PVs without mdas. +- Fix pvchange -M1 -u to preserve existing extent locations when there's a VG. +- Cease recognising snapshot-in-use percentages returned by early devt kernels. +- Add backward-compatible flags field to on-disk format_text metadata. +- libdevmapper: Only resume devices in dm_tree_preload_children if size changes. +- libdevmapper: Extend deptree buffers so the largest possible device numbers fit. +- libdevmapper: Underline longer report help text headings. + +* Tue Oct 7 2008 Alasdair Kergon - 2.02.39-6 +- Only set exec_prefix once and configure explicit directories to work with + new version of rpm. + +* Fri Sep 26 2008 Fabio M. Di Nitto - 2.02.39-5 +- Add BuildRequires on cmanlib-devel. This is required after libcman split + from cman and cman-devel into cmanlib and cmanlib-devel. +- Make versioned BuildRequires on cman-devel and cmanlib-devel more strict + to guarantee to get the right version. + +* Thu Sep 25 2008 Fabio M. Di Nitto - 2.02.39-5 +- Add versioned BuildRequires on new cman-devel. + +* Sun Sep 21 2008 Ville Skyttä - 2.02.39-5 +- Change %%patch to %%patch0 to match Patch0 as required by RPM package update. + +* Thu Aug 7 2008 Tom "spot" Callaway - 2.02.39-4 +- Fix license tag. + +* Fri Jun 27 2008 Alasdair Kergon - 2.02.39-3 +- Fix up cache for PVs without mdas after consistent VG metadata is processed. +- Update validation of safe mirror log type conversions in lvconvert. +- Fix lvconvert to disallow snapshot and mirror combinations. +- Fix reporting of LV fields alongside unallocated PV segments. +- Add --unquoted and --rows to reporting tools. +- Avoid undefined status code after _memlock commands in lvm shell. +- Fix and improve readahead 'auto' calculation for stripe_size. +- Fix lvchange output for -r auto setting if auto is already set. +- Fix add_mirror_images not to dereference uninitialized log_lv upon failure. +- Add --force to lvextend and lvresize. +- Fix vgchange to not activate component mirror volumes directly. + +* Wed Jun 25 2008 Alasdair Kergon - 2.02.38-2 +- dmsetup: Add --unquoted and --rows to 'info -c' command. +- libdevmapper: Fix inverted no_flush debug message. + +* Fri Jun 13 2008 Alasdair Kergon - 2.02.38-1 +- libdevmapper: Make dm_hash_iter safe against deletion. +- libdevmapper: Accept a NULL pointer to dm_free silently. +- libdevmapper: Calculate string size within dm_pool_grow_object. +- libdevmapper: Send reporting field help text to stderr not stdout. + +- dmsetup: Add tables_loaded, readonly and suspended columns to reports. +- dmsetup: Add --nameprefixes for new report output format FIELD=VALUE. + +- Add --nameprefixes to reporting tools for field name prefix output format. +- Fix return values for reporting commands when run with no PVs, LVs, or VGs. +- Add omitted unlock_vg() call when sigint_caught() during vg processing. +- Fix free_count when reading pool metadata. +- Fix segfault when using pvcreate on a device containing pool metadata. +- In script-processing mode, stop if any command fails. +- Warn if command exits with non-zero status code without a prior log_error. +- Correct config file line numbers in messages when parsing comments. +- Add missing deactivation after activation failure in lvcreate -Zy. +- When removing LV symlinks, skip any where the VG name is not determined. +- Fix vgsplit internal counting of snapshot LVs. +- Update vgsplit to only restrict split with active LVs involved in split. +- Fix vgsplit to only move hidden 'snapshotN' LVs when necessary. +- Update vgsplit man page to reflect lvnames on the cmdline. +- Update vgsplit to take "-n LogicalVolumeName" on the cmdline. +- Fix vgsplit error paths to release vg_to lock. +- Avoid spurious duplicate VG messages referring to VGs that are gone. +- Drop dev_name_confirmed error message to debug level. +- Fix setpriority error message to signed int. +- Add assertions to trap deprecated P_ and V_ lock usage. +- Avoid using DLM locks with LCK_CACHE type P_ lock requests. +- Don't touch /dev in vgrename if activation is disabled. +- Exclude VG_GLOBAL from internal concurrent VG lock counter. +- Fix vgmerge snapshot_count when source VG contains snapshots. +- Fix internal LV counter when a snapshot is removed. +- Fix metadata corruption writing lvm1-formatted metadata with snapshots. +- Fix lvconvert -m0 allocatable space check. +- Don't attempt remote metadata backups of non-clustered VGs. +- Improve preferred_names lvm.conf example. +- Fix vgdisplay 'Cur LV' field to match lvdisplay output. +- Fix lv_count report field to exclude hidden LVs. +- Fix some pvmove error status codes. +- Indicate whether or not VG is clustered in vgcreate log message. +- Mention default --clustered setting in vgcreate man page. +- Fix vgreduce to use vg_split_mdas to check sufficient mdas remain. +- Update lvmcache VG lock state for all locking types now. +- Fix output if overriding command_names on cmdline. +- Add check to vg_commit() ensuring VG lock held before writing new VG metadata. +- Add validation of LV name to pvmove -n. +- Add some basic internal VG lock validation. +- Fix vgsplit internal counting of snapshot LVs. +- Update vgsplit to only restrict split with active LVs involved in split. +- Fix vgsplit to only move hidden 'snapshotN' LVs when necessary. +- Update vgsplit man page to reflect lvnames on the cmdline. +- Update vgsplit to take "-n LogicalVolumeName" on the cmdline. +- Fix vgsplit error paths to release vg_to lock. +- Fix vgsplit locking of new VG. +- Avoid erroneous vgsplit error message for new VG. +- Suppress duplicate message when lvresize fails because of invalid vgname. +- Cache VG metadata internally while VG lock is held. +- Fix redundant lvresize message if vg doesn't exist. +- Make clvmd-cman use a hash rather than an array for node updown info. +- Decode numbers in clvmd debugging output. +- Fix uninitialised mutex in clvmd if all daemons are not running at startup. +- Add config file overrides to clvmd when it reads the active LVs list. +- Make clvmd refresh the context correctly when lvm.conf is updated. +- Fix another allocation bug with clvmd and large node IDs. +- Fix uninitialised variable in clvmd that could cause odd hangs. +- Correct command name in lvmdiskscan man page. +- clvmd no longer crashes if it sees nodeids over 50. +- Fix potential deadlock in clvmd thread handling. +- Update usage message for clvmd. +- Fix clvmd man page not to print
and clarified debug options. +- Escape double quotes and backslashes in external metadata and config data. +- Correct a function name typo in _line_append error message. +- Fix resetting of MIRROR_IMAGE and VISIBLE_LV after removal of LV. +- Fix remove_layer_from_lv to empty the LV before removing it. +- Add missing no-longer-used segs_using_this_lv test to check_lv_segments. +- Fix lvconvert detection of mirror conversion in progress. +- Avoid automatic lvconvert polldaemon invocation when -R specified. +- Fix 'pvs -a' to detect VGs of PVs without metadata areas. +- Divide up internal orphan volume group by format type. +- Fix lvresize to support /dev/mapper prefix in the LV name. +- Fix lvresize to pass new size to fsadm when extending device. +- Fix unfilled parameter passed to fsadm from lvresize. +- Update fsadm to call lvresize if the partition size differs (with option -l). +- Fix fsadm to support VG/LV names. + +* Wed Apr 2 2008 Jeremy Katz - 2.02.33-11 +- Adjust for new name for vio disks (from danpb) +- And fix the build (also from danpb) + +* Wed Mar 5 2008 Jeremy Katz - 2.02.33-10 +- recognize vio disks + +* Thu Jan 31 2008 Alasdair Kergon - 2.02.33-9 +- Improve internal label caching performance while locks are held. +- Fix mirror log name construction during lvconvert. + +* Tue Jan 29 2008 Alasdair Kergon - 2.02.32-8 +- Fix pvs, vgs, lvs error exit status on some error paths. +- Fix new parameter validation in vgsplit and test mode. +- Fix internal metadata corruption in lvchange --resync. + +* Sat Jan 19 2008 Alasdair Kergon - 2.02.31-7 +- Avoid readahead error message when using default setting of lvcreate -M1. +- Fix lvcreate --nosync not to wait for non-happening sync. +- Add very_verbose lvconvert messages. + +* Thu Jan 17 2008 Alasdair Kergon - 2.02.30-6 +- Remove static libraries and binaries and move most binaries out of /usr. +- Fix a segfault if using pvs with --all argument. +- Fix vgreduce PV list processing not to process every PV in the VG. +- Reinstate VG extent size and stripe size defaults (halved). +- Set default readahead to twice maximium stripe size. +- Detect non-orphans without MDAs correctly. +- Prevent pvcreate from overwriting MDA-less PVs belonging to active VGs. +- Don't use block_on_error with mirror targets version 1.12 and above. +- Change vgsplit -l (for unimplemented --list) into --maxlogicalvolumes. +- Update vgsplit to accept vgcreate options when new VG is destination. +- Update vgsplit to accept existing VG as destination. +- Major restructuring of pvmove and lvconvert code, adding stacking support. +- Add new convert_lv field to lvs output. +- Permit LV segment fields with PV segment reports. +- Extend lvconvert to use polldaemon and wait for completion of initial sync. +- Add seg_start_pe and seg_pe_ranges to reports. +- Add fsadm interface to filesystem resizing tools. +- Update --uuid argument description in man pages. +- Print warning when lvm tools are running as non-root. + +* Thu Dec 20 2007 Alasdair Kergon - 2.02.29-5 +- Fix libdevmapper readahead processing with snapshots (for example). + +* Thu Dec 13 2007 Alasdair Kergon - 2.02.29-4 +- Add missing lvm2 build & runtime dependencies on module-init-tools (modprobe). + +* Thu Dec 6 2007 Jeremy Katz - 2.02.29-3 +- fix requirements + +* Thu Dec 06 2007 Alasdair Kergon - 2.02.29-2 +- Fold device-mapper build into this lvm2 spec file. + +* Wed Dec 05 2007 Alasdair Kergon - 2.02.29-1 +- Make clvmd backup vg metadata on remote nodes. +- Decode cluster locking state in log message. +- Change file locking state messages from debug to very verbose. +- Fix --addtag to drop @ prefix from name. +- Stop clvmd going haywire if a pre_function fails. +- Avoid nested vg_reads when processing PVs in VGs and fix associated locking. +- Attempt to remove incomplete LVs with lvcreate zeroing/activation problems. +- Add full read_ahead support. +- Add lv_read_ahead and lv_kernel_read_ahead fields to reports and lvdisplay. +- Prevent lvconvert -s from using same LV as origin and snapshot. +- Fix human-readable output of odd numbers of sectors. +- Add pv_mda_free and vg_mda_free fields to reports for raw text format. +- Add LVM2 version to 'Generated by' comment in metadata. +- Show 'not usable' space when PV is too large for device in pvdisplay. +- Ignore and fix up any excessive device size found in metadata. +- Fix error message when fixing up PV size in lvm2 metadata (2.02.11). +- Fix orphan-related locking in pvdisplay and pvs. +- Fix missing VG unlocks in some pvchange error paths. +- Add some missing validation of VG names. +- Detect md superblocks version 1.0, 1.1 and 1.2. +- Add some pv-related error paths. +- Handle future sysfs subsystem/block/devices directory structure. +- Fix a bug in lvm_dump.sh checks for lvm/dmsetup binaries. +- Fix underquotations in lvm_dump.sh. +- Print --help output to stdout, not stderr. +- After a cmdline processing error, don't print help text but suggest --help. +- Add %%PVS extents option to lvresize, lvextend, and lvcreate. +- Remove no-longer-correct restrictions on PV arg count with stripes/mirrors. +- Fix strdup memory leak in str_list_dup(). +- Link with -lpthread when static SELinux libraries require that. +- Detect command line PE values that exceed their 32-bit range. +- Include strerror string in dev_open_flags' stat failure message. +- Avoid error when --corelog is provided without --mirrorlog. (2.02.28) +- Correct --mirrorlog argument name in man pages (not --log). +- Clear MIRROR_NOTSYNCED LV flag when converting from mirror to linear. +- Modify lvremove to prompt for removal if LV active on other cluster nodes. +- Add '-f' to vgremove to force removal of VG even if LVs exist. + +* Fri Aug 24 2007 Alasdair Kergon - 2.02.28-1 +- vgscan and pvscan now trigger clvmd -R, which should now work. +- Fix clvmd logging so you can get lvm-level debugging out of it. +- Allow clvmd debug to be turned on in a running daemon using clvmd -d [-C]. +- Add more cluster info to lvmdump. +- Fix lvdisplay man page to say LV size is reported in sectors, not KB. +- Fix loading of persistent cache if cache_dir is used. +- Only permit --force, --verbose and --debug arguments to be repeated. +- Add support for renaming mirrored LVs. +- Add --mirrorlog argument to specify log type for mirrors. +- Don't leak a file descriptor if flock or fcntl fails. +- Detect stream write failure reliably. +- Reduce severity of lstat error messages to very_verbose. +- Update to use autoconf 2.61, while still supporting 2.57. + +* Thu Aug 09 2007 Alasdair Kergon - 2.02.27-3 +- Clarify GPL licence as being version 2. + +* Wed Aug 01 2007 Milan Broz - 2.02.27-2 +- Add SUN's LDOM virtual block device (vdisk) and ps3disk to filters. + +* Wed Jul 18 2007 Alasdair Kergon - 2.02.27-1 +- Add -f to vgcfgrestore to list metadata backup files. +- Add pvdisplay --maps implementation. +- Add devices/preferred_names config regex list for displayed device names. +- Add vg_mda_count and pv_mda_count columns to reports. +- Change cling alloc policy attribute character from 'C' to l'. +- Print warnings to stderr instead of stdout. +- Fix snapshot cow area deactivation if origin is not active. +- Reinitialise internal lvmdiskscan variables when called repeatedly. +- Allow keyboard interrupt during user prompts when appropriate. +- Fix deactivation code to follow dependencies and remove symlinks. +- Fix a segfault in device_is_usable() if a device has no table. +- Fix creation and conversion of mirrors with tags. +- Add command stub for pvck. +- Handle vgsplit of an entire VG as a vgrename. +- Fix vgsplit for lvm1 format (set and validate VG name in PVs metadata). +- Split metadata areas in vgsplit properly. +- Fix and clarify vgsplit error messages. +- Update lists of attribute characters in man pages. +- Remove unsupported LVM1 options from vgcfgrestore man page. +- Update vgcfgrestore man page to show mandatory VG name. +- Update vgrename man page to include UUID and be consistent with lvrename. +- Add some more debug messages to clvmd startup. +- Fix thread race in clvmd. +- Make clvmd cope with quorum devices. +- Add extra internal error checking to clvmd. +- Fix missing lvm_shell symbol in lvm2cmd library. +- Move regex functions into libdevmapper. +- Add kernel and device-mapper targets versions to lvmdump. +- Add /sys/block listings to lvmdump. +- Make lvmdump list /dev recursively. +- Mark /etc/lvm subdirectories as directories in spec file. + +* Mon Mar 19 2007 Alasdair Kergon - 2.02.24-1 +- Add BuildRequires readline-static until makefiles get fixed. +- Fix processing of exit status in init scripts +- Fix vgremove to require at least one vg argument. +- Fix reading of striped LVs in LVM1 format. +- Flag nolocking as clustered so clvmd startup sees clustered LVs. +- Add a few missing pieces of vgname command line validation. +- Support the /dev/mapper prefix on most command lines. + +* Thu Mar 08 2007 Alasdair Kergon - 2.02.23-1 +- Fix vgrename active LV check to ignore differing vgids. +- Fix two more segfaults if an empty config file section encountered. +- Fix a leak in a reporting error path. +- Add devices/cache_dir & devices/cache_file_prefix, deprecating devices/cache. + +* Tue Feb 27 2007 Alasdair Kergon - 2.02.22-3 +- Move .cache file to /etc/lvm/cache. + +* Wed Feb 14 2007 Alasdair Kergon - 2.02.22-2 +- Rebuild after device-mapper package split. + +* Wed Feb 14 2007 Alasdair Kergon - 2.02.22-1 +- Add ncurses-static BuildRequires after package split. +- Fix loading of segment_libraries. +- If a PV reappears after it was removed from its VG, make it an orphan. +- Don't update metadata automatically if VGIDs don't match. +- Fix some vgreduce --removemissing command line validation. +- Trivial man page corrections (-b and -P). +- Add global/units to example.conf. +- Remove readline support from lvm.static. + +* Mon Feb 05 2007 Alasdair Kergon - 2.02.21-4 +- Remove file wildcards and unintentional lvmconf installation. + +* Mon Feb 05 2007 Alasdair Kergon - 2.02.21-3 +- Add build dependency on new device-mapper-devel package. + +* Wed Jan 31 2007 Alasdair Kergon - 2.02.21-2 +- Remove superfluous execute perm from .cache data file. + +* Tue Jan 30 2007 Alasdair Kergon - 2.02.21-1 +- Fix vgsplit to handle mirrors. +- Reorder fields in reporting field definitions. +- Fix vgs to treat args as VGs even when PV fields are displayed. +- Fix md signature check to handle both endiannesses. + +* Fri Jan 26 2007 Alasdair Kergon - 2.02.20-1 +- Fix exit statuses of reporting tools. +- Add some missing close() and fclose() return code checks. +- Add devices/ignore_suspended_devices to ignore suspended dm devices. +- Fix refresh_toolcontext() always to wipe persistent device filter cache. +- Long-lived processes write out persistent dev cache in refresh_toolcontext(). +- Streamline dm_report_field_* interface. +- Update reporting man pages. +- Add --clustered to man pages. +- Add field definitions to report help text. + +* Mon Jan 22 2007 Milan Broz - 2.02.19-2 +- Remove BuildRequires libtermcap-devel + Resolves: #223766 + +* Wed Jan 17 2007 Alasdair Kergon - 2.02.19-1 +- Fix a segfault if an empty config file section encountered. +- Fix partition table processing after sparc changes. +- Fix cmdline PE range processing segfault. +- Move basic reporting functions into libdevmapper. + +* Fri Jan 12 2007 Alasdair Kergon - 2.02.18-2 +- Rebuild. + +* Thu Jan 11 2007 Alasdair Kergon - 2.02.18-1 +- Use CFLAGS when linking so mixed sparc builds can supply -m64. +- Prevent permission changes on active mirrors. +- Print warning instead of error message if lvconvert cannot zero volume. +- Add snapshot options to lvconvert man page. +- dumpconfig accepts a list of configuration variables to display. +- Change dumpconfig to use --file to redirect output to a file. +- Avoid vgreduce error when mirror code removes the log LV. +- Fix ambiguous vgsplit error message for split LV. +- Fix lvextend man page typo. +- Use no flush suspending for mirrors. +- Fix create mirror with name longer than 22 chars. + +* Thu Dec 14 2006 Alasdair Kergon - 2.02.17-1 +- Add missing pvremove error message when device doesn't exist. +- When lvconvert allocates a mirror log, respect parallel area constraints. +- Check for failure to allocate just the mirror log. +- Support mirror log allocation when there is only one PV: area_count now 0. +- Fix detection of smallest area in _alloc_parallel_area() for cling policy. +- Add manpage entry for clvmd -T +- Fix hang in clvmd if a pre-command failed. + +* Fri Dec 01 2006 Alasdair Kergon - 2.02.16-1 +- Fix VG clustered read locks to use PR not CR. +- Adjust some alignments for ia64/sparc. +- Fix mirror segment removal to use temporary error segment. +- Always compile debug logging into clvmd. +- Add startup timeout to clvmd startup script. +- Add -T (startup timeout) switch to clvmd. +- Improve lvm_dump.sh robustness. + +* Tue Nov 21 2006 Alasdair Kergon - 2.02.15-3 +- Fix clvmd init script line truncation. + +* Tue Nov 21 2006 Alasdair Kergon - 2.02.15-2 +- Fix lvm.conf segfault. + +* Mon Nov 20 2006 Alasdair Kergon - 2.02.15-1 +- New upstream - see WHATS_NEW. + +* Sat Nov 11 2006 Alasdair Kergon - 2.02.14-1 +- New upstream - see WHATS_NEW. + +* Mon Oct 30 2006 Alasdair Kergon - 2.02.13-2 +- Fix high-level free-space check on partial allocation. + Resolves: #212774 + +* Fri Oct 27 2006 Alasdair Kergon - 2.02.13-1 +- New upstream - see WHATS_NEW. + Resolves: #205818 + +* Fri Oct 20 2006 Alasdair Kergon - 2.02.12-2 +- Remove no-longer-used ldconfig from lvm2-cluster and fix lvmconf + to cope without the shared library. + +* Mon Oct 16 2006 Alasdair Kergon - 2.02.12-1 +- New upstream. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-6 +- Incorporate lvm2-cluster as a subpackage. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-5 +- Install lvmdump script. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-4 +- Build in cluster locking with fallback if external locking fails to load. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-3 +- Drop .0 suffix from release. + +* Sat Oct 14 2006 Alasdair Kergon - 2.02.11-2.0 +- Append distribution to release. + +* Fri Oct 13 2006 Alasdair Kergon - 2.02.11-1.0 +- New upstream with numerous fixes and small enhancements. + (See the WHATS_NEW documentation file for complete upstream changelog.) + +* Thu Sep 28 2006 Peter Jones - 2.02.06-4 +- Fix metadata and map alignment problems on ppc64 (#206202) + +* Tue Aug 1 2006 Jeremy Katz - 2.02.06-3 +- require new libselinux to avoid segfaults on xen (#200783) + +* Thu Jul 27 2006 Jeremy Katz - 2.02.06-2 +- free trip through the buildsystem + +* Wed Jul 12 2006 Jesse Keating - 2.02.06-1.2.1 +- rebuild + +* Tue Jun 6 2006 Stephen C. Tweedie - 2.02.06-1.2 +- Rebuild to pick up new nosegneg libc.a for lvm.static + +* Mon May 22 2006 Alasdair Kergon - 2.02.06-1.1 +- Reinstate archs now build system is back. +- BuildRequires libsepol-devel. + +* Fri May 12 2006 Alasdair Kergon - 2.02.06-1.0 +- New upstream release. + +* Sat Apr 22 2006 Alasdair Kergon - 2.02.05-1.1 +- Exclude archs that aren't building. + +* Fri Apr 21 2006 Alasdair Kergon - 2.02.05-1.0 +- Fix VG uuid comparisons. + +* Wed Apr 19 2006 Alasdair Kergon - 2.02.04-1.0 +- New release upstream, including better handling of duplicated VG names. + +* Fri Feb 10 2006 Jesse Keating - 2.02.01-1.2.1 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2.02.01-1.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Fri Dec 2 2005 Peter Jones - 2.02.01-1 +- update to 2.02.01 + +* Tue Nov 8 2005 Jeremy Katz - 2.01.14-4 +- add patch for xen block devices + +* Sat Oct 15 2005 Florian La Roche +- add -lselinux -lsepol to the static linking -ldevice-mapper requires it + +* Wed Sep 14 2005 Jeremy Katz - 2.01.14-2 +- the distro doesn't really work without a 2.6 kernel, so no need to require it + +* Thu Aug 4 2005 Alasdair Kergon - 2.01.14-1.0 +- And a few more bugs fixes. + +* Wed Jul 13 2005 Alasdair Kergon - 2.01.13-1.0 +- Fix several bugs discovered in the last release. + +* Tue Jun 14 2005 Alasdair Kergon - 2.01.12-1.0 +- New version upstream with a lot of fixes and enhancements. + +* Wed Apr 27 2005 Alasdair Kergon - 2.01.08-2.1 +- Add /etc/lvm + +* Wed Apr 27 2005 Alasdair Kergon - 2.01.08-2.0 +- No longer abort read operations if archive/backup directories aren't there. +- Add runtime directories and file to the package. + +* Tue Mar 22 2005 Alasdair Kergon - 2.01.08-1.0 +- Improve detection of external changes affecting internal cache. +- Add clustered VG attribute. +- Suppress rmdir opendir error message. + +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.3 +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.2 +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.1 +- Suppress some new compiler messages. + +* Tue Mar 08 2005 Alasdair Kergon - 2.01.07-1.0 +- Remove build directory from built-in path. +- Extra /dev scanning required for clustered operation. + +* Thu Mar 03 2005 Alasdair Kergon - 2.01.06-1.0 +- Allow anaconda to suppress warning messages. + +* Fri Feb 18 2005 Alasdair Kergon - 2.01.05-1.0 +- Upstream changes not affecting Fedora. + +* Wed Feb 09 2005 Alasdair Kergon - 2.01.04-1.0 +- Offset pool minors; lvm2cmd.so skips open fd check; pvmove -f gone. + +* Tue Feb 01 2005 Alasdair Kergon - 2.01.03-1.0 +- Fix snapshot device size & 64-bit display output. + +* Fri Jan 21 2005 Alasdair Kergon - 2.01.02-1.0 +- Minor fixes. + +* Mon Jan 17 2005 Alasdair Kergon - 2.01.01-1.0 +- Update vgcreate man page. Preparation for snapshot origin extension fix. + +* Mon Jan 17 2005 Alasdair Kergon - 2.01.00-1.0 +- Fix metadata auto-correction. Only request open_count when needed. + +* Wed Jan 12 2005 Tim Waugh - 2.00.33-2.0 +- Rebuilt for new readline. + +* Fri Jan 7 2005 Alasdair Kergon - 2.00.33-1.0 +- pvcreate wipes ext label +- several clvm fixes + +* Thu Jan 6 2005 Alasdair Kergon - 2.00.32-2.0 +- Remove temporary /sbin symlinks no longer needed. +- Include read-only pool support in the build. + +* Wed Dec 22 2004 Alasdair Kergon - 2.00.32-1.0 +- More fixes (143501). + +* Sun Dec 12 2004 Alasdair Kergon - 2.00.31-1.0 +- Fix pvcreate install issues. + +* Fri Dec 10 2004 Alasdair Kergon - 2.00.30-1.0 +- Additional debugging code. +- Some trivial man page corrections. + +* Tue Nov 30 2004 Alasdair Kergon - 2.00.29-1.3 +- Reinstate all archs. + +* Sun Nov 28 2004 Alasdair Kergon - 2.00.29-1.2 +- Try excluding more archs. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.29-1.1 +- Exclude s390x which fails. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.29-1 +- Fix last fix. + +* Sat Nov 27 2004 Alasdair Kergon - 2.00.28-1 +- Endian fix to partition/md signature detection. + +* Wed Nov 24 2004 Alasdair Kergon - 2.00.27-1 +- Fix partition table detection & an out of memory segfault. + +* Tue Nov 23 2004 Alasdair Kergon - 2.00.26-1 +- Several installation-related fixes & man page updates. + +* Mon Oct 25 2004 Elliot Lee - 2.00.25-1.01 +- Fix 2.6 kernel requirement + +* Wed Sep 29 2004 Alasdair Kergon - 2.00.25-1 +- Fix vgmknodes return code & vgremove locking. + +* Fri Sep 17 2004 Alasdair Kergon - 2.00.24-2 +- Obsolete old lvm1 packages; refuse install if running kernel 2.4. [bz 128185] + +* Thu Sep 16 2004 Alasdair Kergon - 2.00.24-1 +- More upstream fixes. (Always check WHATS_NEW file for details.) +- Add requested BuildRequires. [bz 124916, 132408] + +* Wed Sep 15 2004 Alasdair Kergon - 2.00.23-1 +- Various minor upstream fixes. + +* Fri Sep 3 2004 Alasdair Kergon - 2.00.22-1 +- Permission fix included upstream; use different endian conversion macros. + +* Thu Sep 2 2004 Jeremy Katz - 2.00.21-2 +- fix permissions on vg dirs + +* Thu Aug 19 2004 Alasdair Kergon - 2.00.21-1 +- New upstream release incorporating fixes plus minor enhancements. + +* Tue Aug 17 2004 Jeremy Katz - 2.00.20-2 +- add patch for iSeries viodasd support +- add patch to check file type using stat(2) if d_type == DT_UNKNOWN (#129674) + +* Sat Jul 3 2004 Alasdair Kergon - 2.00.20-1 +- New upstream release fixes 2.6 kernel device numbers. + +* Tue Jun 29 2004 Alasdair Kergon - 2.00.19-1 +- Latest upstream release. Lots of changes (see WHATS_NEW). + +* Tue Jun 15 2004 Elliot Lee - 2.00.15-5 +- rebuilt + +* Wed May 26 2004 Alasdair Kergon - 2.00.15-4 +- clone %%description from LVM rpm + +* Wed May 26 2004 Alasdair Kergon - 2.00.15-3 +- vgscan shouldn't return error status when no VGs present + +* Thu May 06 2004 Warren Togami - 2.00.15-2 +- i2o patch from Markus Lidel + +* Tue Apr 20 2004 Bill Nottingham - 2.00.15-1.1 +- handle disabled SELinux correctly, so that LVMs can be detected in a + non-SELinux context + +* Mon Apr 19 2004 Alasdair Kergon - 2.00.15-1 +- Fix non-root build with current version of 'install'. + +* Fri Apr 16 2004 Alasdair Kergon - 2.00.14-1 +- Use 64-bit file offsets. + +* Fri Apr 16 2004 Alasdair Kergon - 2.00.13-1 +- Avoid scanning devices containing md superblocks. +- Integrate ENOTSUP patch. + +* Thu Apr 15 2004 Jeremy Katz - 2.00.12-4 +- don't die if we get ENOTSUP setting selinux contexts + +* Thu Apr 15 2004 Alasdair Kergon 2.00.12-3 +- Add temporary pvscan symlink for LVM1 until mkinitrd gets updated. + +* Wed Apr 14 2004 Alasdair Kergon 2.00.12-2 +- Mark config file noreplace. + +* Wed Apr 14 2004 Alasdair Kergon 2.00.12-1 +- Install default /etc/lvm/lvm.conf. +- Move non-static binaries to /usr/sbin. +- Add temporary links in /sbin to lvm.static until rc.sysinit gets updated. + +* Thu Apr 08 2004 Alasdair Kergon 2.00.11-1 +- Fallback to using LVM1 tools when using a 2.4 kernel without device-mapper. + +* Wed Apr 07 2004 Alasdair Kergon 2.00.10-2 +- Install the full toolset, not just 'lvm'. + +* Wed Apr 07 2004 Alasdair Kergon 2.00.10-1 +- Update to version 2.00.10, which incorporates the RH-specific patches + and includes various fixes and enhancements detailed in WHATS_NEW. + +* Wed Mar 17 2004 Jeremy Katz 2.00.08-5 +- Fix sysfs patch to find sysfs +- Take patch from dwalsh and tweak a little for setting SELinux contexts on + device node creation and also do it on the symlink creation. + Part of this should probably be pushed down to device-mapper instead + +* Thu Feb 19 2004 Stephen C. Tweedie 2.00.08-4 +- Add sysfs filter patch +- Allow non-root users to build RPM + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Dec 5 2003 Jeremy Katz 2.00.08-2 +- add static lvm binary + +* Tue Dec 2 2003 Jeremy Katz +- Initial build. + +