diff --git a/0001-devices-file-move-clean-up-after-command-is-run.patch b/0001-devices-file-move-clean-up-after-command-is-run.patch new file mode 100644 index 0000000..5e4a248 --- /dev/null +++ b/0001-devices-file-move-clean-up-after-command-is-run.patch @@ -0,0 +1,49 @@ +From 28a4df481fa47d0b71996a25ac08546c4bd094f8 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 27 May 2022 12:38:43 -0500 +Subject: [PATCH 1/7] devices file: move clean up after command is run + +devices_file_exit wasn't being called between lvm_shell +commands, so the file lock wouldn't be released. + +(cherry picked from commit 9dfa6f38793f6b5f7de2a4148ab2f7790e3c39da) +--- + lib/commands/toolcontext.c | 2 -- + tools/lvmcmdline.c | 1 + + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c +index 4cb81bf94..2666d7b42 100644 +--- a/lib/commands/toolcontext.c ++++ b/lib/commands/toolcontext.c +@@ -1905,7 +1905,6 @@ int refresh_toolcontext(struct cmd_context *cmd) + _destroy_segtypes(&cmd->segtypes); + _destroy_formats(cmd, &cmd->formats); + +- devices_file_exit(cmd); + if (!dev_cache_exit()) + stack; + _destroy_dev_types(cmd); +@@ -2034,7 +2033,6 @@ void destroy_toolcontext(struct cmd_context *cmd) + _destroy_segtypes(&cmd->segtypes); + _destroy_formats(cmd, &cmd->formats); + _destroy_filters(cmd); +- devices_file_exit(cmd); + dev_cache_exit(); + _destroy_dev_types(cmd); + _destroy_tags(cmd); +diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c +index 1e3547ed7..b052d698f 100644 +--- a/tools/lvmcmdline.c ++++ b/tools/lvmcmdline.c +@@ -3305,6 +3305,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) + hints_exit(cmd); + lvmcache_destroy(cmd, 1, 1); + label_scan_destroy(cmd); ++ devices_file_exit(cmd); + + if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING))) + dm_config_destroy(config_string_cft); +-- +2.34.3 + diff --git a/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch b/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch new file mode 100644 index 0000000..ed57cf2 --- /dev/null +++ b/0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch @@ -0,0 +1,55 @@ +From 9a79248fe21554e6cb99dd6ed044e7cbff18f777 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 27 May 2022 14:27:03 -0500 +Subject: [PATCH 2/7] devices file: fail if --devicesfile filename doesn't + exist + +A typo of the filename after --devicesfile should result in a +command error rather than the command falling back to using no +devices file at all. Exception is vgcreate|pvcreate which +create a new devices file if the file name doesn't exist. + +(cherry picked from commit bfe072e4388b530cbf5369be8a8f1305220198bf) +--- + lib/device/dev-cache.c | 9 +++++++++ + test/shell/devicesfile-basic.sh | 4 ++++ + 2 files changed, 13 insertions(+) + +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index 3aaf6a2e5..ed9c726c9 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -1863,6 +1863,15 @@ int setup_devices(struct cmd_context *cmd) + + file_exists = devices_file_exists(cmd); + ++ /* ++ * Fail if user specifies a file name that doesn't exist and ++ * the command is not creating a new devices file. ++ */ ++ if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) { ++ log_error("Devices file not found: %s", cmd->devices_file_path); ++ return 0; ++ } ++ + /* + * Removing the devices file is another way of disabling the use of + * a devices file, unless the command creates the devices file. +diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh +index 9c3455c76..77fe265a0 100644 +--- a/test/shell/devicesfile-basic.sh ++++ b/test/shell/devicesfile-basic.sh +@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices" + vgs --devicesfile test.devices $vg1 + not vgs --devicesfile test.devices $vg2 + ++# misspelled override name fails ++not vgs --devicesfile doesnotexist $vg1 ++not vgs --devicesfile doesnotexist $vg2 ++ + # devicesfile and devices cannot be used together + not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 + +-- +2.34.3 + diff --git a/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch b/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch new file mode 100644 index 0000000..7d3ca86 --- /dev/null +++ b/0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch @@ -0,0 +1,54 @@ +From 1e78ed5a0d9a8296b42578cfc250a3a281a32878 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 6 Jun 2022 11:39:02 -0500 +Subject: [PATCH 3/7] filter-mpath: handle other wwid types in blacklist + +Fixes commit 494372b4eed0c8f6040e3357939eb7511ac25745 + "filter-mpath: use multipath blacklist" +to handle wwids with initial type digits 1 and 2 used +for t10 and eui ids. Originally recognized type 3 naa. + +(cherry picked from commit c302903dbab1d5fd05b344c654bed83c9ecb69f8) +--- + lib/device/dev-mpath.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index 270366ad7..846f6c8ba 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -54,7 +54,7 @@ static void _read_blacklist_file(const char *path) + int section_black = 0; + int section_exceptions = 0; + int found_quote; +- int found_three; ++ int found_type; + int i, j; + + if (!(fp = fopen(path, "r"))) +@@ -114,7 +114,7 @@ static void _read_blacklist_file(const char *path) + + memset(wwid, 0, sizeof(wwid)); + found_quote = 0; +- found_three = 0; ++ found_type = 0; + j = 0; + + for (; i < MAX_WWID_LINE; i++) { +@@ -132,9 +132,10 @@ static void _read_blacklist_file(const char *path) + /* second quote is end of wwid */ + if ((line[i] == '"') && found_quote) + break; +- /* ignore first "3" in wwid */ +- if ((line[i] == '3') && !found_three) { +- found_three = 1; ++ /* exclude initial 3/2/1 for naa/eui/t10 */ ++ if (!j && !found_type && ++ ((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) { ++ found_type = 1; + continue; + } + +-- +2.34.3 + diff --git a/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch b/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch new file mode 100644 index 0000000..d2a09bc --- /dev/null +++ b/0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch @@ -0,0 +1,743 @@ +From 2966df2bcbbf553d86d0a608852dcc140df28fc0 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Mon, 6 Jun 2022 14:04:20 -0500 +Subject: [PATCH 4/7] filter-mpath: get wwids from sysfs vpd_pg83 + +to compare with wwids in /etc/multipath/wwids when +excluding multipath components. The wwid printed +from the sysfs wwid file may not be the wwid used +in multipath wwids. Save the wwids found for each +device on dev->wwids to avoid repeating reading +and parsing the sysfs files. + +(cherry picked from commit 3b0f9cec7e999c33f17714358d2b469bda6967d2) +--- + lib/Makefile.in | 1 + + lib/device/dev-cache.c | 18 ++++ + lib/device/dev-cache.h | 1 + + lib/device/dev-mpath.c | 232 ++++++++++++++++++++++++++++++++++------- + lib/device/device.h | 13 +++ + lib/device/device_id.c | 31 +++++- + lib/device/device_id.h | 2 + + lib/device/parse_vpd.c | 199 +++++++++++++++++++++++++++++++++++ + 8 files changed, 454 insertions(+), 43 deletions(-) + create mode 100644 lib/device/parse_vpd.c + +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 22b96134b..3ab5cb2f1 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -41,6 +41,7 @@ SOURCES =\ + device/dev-dasd.c \ + device/dev-lvm1-pool.c \ + device/online.c \ ++ device/parse_vpd.c \ + display/display.c \ + error/errseg.c \ + unknown/unknown.c \ +diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c +index ed9c726c9..193eb7585 100644 +--- a/lib/device/dev-cache.c ++++ b/lib/device/dev-cache.c +@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev) + + dm_list_init(&dev->aliases); + dm_list_init(&dev->ids); ++ dm_list_init(&dev->wwids); + } + + void dev_destroy_file(struct device *dev) +@@ -383,6 +384,22 @@ out: + return 1; + } + ++int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen) ++{ ++ int ret; ++ int fd; ++ ++ fd = open(path, O_RDONLY); ++ if (fd < 0) ++ return 0; ++ ret = read(fd, buf, buf_size); ++ close(fd); ++ if (ret <= 0) ++ return 0; ++ *retlen = ret; ++ return 1; ++} ++ + int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value) + { + FILE *fp; +@@ -1336,6 +1353,7 @@ int dev_cache_exit(void) + dm_hash_iterate(n, _cache.names) { + dev = (struct device *) dm_hash_get_data(_cache.names, n); + free_dids(&dev->ids); ++ free_wwids(&dev->wwids); + } + } + +diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h +index 46b1da72c..7ffe01152 100644 +--- a/lib/device/dev-cache.h ++++ b/lib/device/dev-cache.h +@@ -74,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path); + bool dev_cache_has_md_with_end_superblock(struct dev_types *dt); + + int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value); ++int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen); + int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor); + + int setup_devices_file(struct cmd_context *cmd); +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index 846f6c8ba..27b0f41a6 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -200,11 +200,12 @@ static void _read_wwid_exclusions(void) + log_debug("multipath config ignored %d wwids", rem_count); + } + +-static void _read_wwid_file(const char *config_wwids_file) ++static void _read_wwid_file(const char *config_wwids_file, int *entries) + { + FILE *fp; + char line[MAX_WWID_LINE]; + char *wwid, *p; ++ char typestr[2] = { 0 }; + int count = 0; + + if (config_wwids_file[0] != '/') { +@@ -226,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file) + if (line[0] == '/') + wwid++; + +- /* skip the initial '3' */ +- wwid++; ++ ++ /* ++ * the initial character is the id type, ++ * 1 is t10, 2 is eui, 3 is naa, 8 is scsi name. ++ * wwids are stored in the hash table without the type charater. ++ * It seems that sometimes multipath does not include ++ * the type charater (seen with t10 scsi_debug devs). ++ */ ++ typestr[0] = *wwid; ++ if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3') ++ wwid++; + + if ((p = strchr(wwid, '/'))) + *p = '\0'; +@@ -240,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file) + stack; + + log_debug("multipath wwids read %d from %s", count, config_wwids_file); ++ *entries = count; + } + + int dev_mpath_init(const char *config_wwids_file) +@@ -247,6 +258,7 @@ int dev_mpath_init(const char *config_wwids_file) + struct dm_pool *mem; + struct dm_hash_table *minor_tab; + struct dm_hash_table *wwid_tab; ++ int entries = 0; + + dm_list_init(&_ignored); + dm_list_init(&_ignored_exceptions); +@@ -283,10 +295,16 @@ int dev_mpath_init(const char *config_wwids_file) + _wwid_hash_tab = wwid_tab; + + if (config_wwids_file) { +- _read_wwid_file(config_wwids_file); ++ _read_wwid_file(config_wwids_file, &entries); + _read_wwid_exclusions(); + } + ++ if (!entries) { ++ /* reading dev wwids is skipped with null wwid_hash_tab */ ++ dm_hash_destroy(_wwid_hash_tab); ++ _wwid_hash_tab = NULL; ++ } ++ + return 1; + } + +@@ -434,10 +452,10 @@ static int _dev_is_mpath_component_udev(struct device *dev) + + /* mpath_devno is major:minor of the dm multipath device currently using the component dev. */ + +-static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, dev_t *mpath_devno) ++static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev, ++ int primary_result, dev_t primary_dev, dev_t *mpath_devno) + { + struct dev_types *dt = cmd->dev_types; +- const char *part_name; + const char *name; /* e.g. "sda" for "/dev/sda" */ + char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */ + char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */ +@@ -451,25 +469,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device + int dm_dev_major; + int dm_dev_minor; + struct stat info; +- dev_t primary_dev; + int is_mpath_component = 0; + +- /* multipathing is only known to exist for SCSI or NVME devices */ +- if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev)) +- return 0; +- +- switch (dev_get_primary_dev(dt, dev, &primary_dev)) { ++ switch (primary_result) { + + case 2: /* The dev is partition. */ +- part_name = dev_name(dev); /* name of original dev for log_debug msg */ + + /* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */ + if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path)))) + return_0; +- +- log_debug_devs("%s: Device is a partition, using primary " +- "device %s for mpath component detection", +- part_name, name); + break; + + case 1: /* The dev is already a primary dev. Just continue with the dev. */ +@@ -593,47 +601,189 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device + return is_mpath_component; + } + +-static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev) ++static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev, ++ char *idbuf, int idbufsize) + { +- char sysbuf[PATH_MAX] = { 0 }; +- char *wwid; +- long look; ++ char idtmp[DEV_WWID_SIZE]; + +- if (!_wwid_hash_tab) ++ if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) { ++ /* the wwid file is not under device for nvme devs */ ++ if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize)) ++ return 0; ++ } ++ if (!idbuf[0]) + return 0; + +- if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf))) ++ /* in t10 id, replace series of spaces with one _ like multipath */ ++ if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) { ++ if (idbufsize < DEV_WWID_SIZE) ++ return 0; ++ memcpy(idtmp, idbuf, DEV_WWID_SIZE); ++ memset(idbuf, 0, idbufsize); ++ format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize); ++ } ++ return 1; ++} ++ ++#define VPD_SIZE 4096 ++ ++static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev, ++ struct dm_list *ids) ++{ ++ unsigned char vpd_data[VPD_SIZE] = { 0 }; ++ int vpd_datalen = 0; ++ ++ if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen)) ++ return 0; ++ if (!vpd_datalen) + return 0; + +- if (!sysbuf[0]) ++ /* adds dev_wwid entry to dev->wwids for each id in vpd data */ ++ parse_vpd_ids(vpd_data, vpd_datalen, ids); ++ return 1; ++} ++ ++void free_wwids(struct dm_list *ids) ++{ ++ struct dev_wwid *dw, *safe; ++ ++ dm_list_iterate_items_safe(dw, safe, ids) { ++ dm_list_del(&dw->list); ++ free(dw); ++ } ++} ++ ++static int _wwid_type_num(char *id) ++{ ++ if (!strncmp(id, "naa.", 4)) ++ return 3; ++ else if (!strncmp(id, "eui.", 4)) ++ return 2; ++ else if (!strncmp(id, "t10.", 4)) ++ return 1; ++ else ++ return -1; ++} ++ ++/* ++ * TODO: if each of the different wwid types (naa/eui/t10) were ++ * represented by different DEV_ID_TYPE_FOO values, and used ++ * as device_id types, then we could drop struct dev_wwid and ++ * drop dev->wwids, and just use dev->ids for each of the ++ * different wwids found in vpd_pg83. This would also require ++ * the ability to handle both the original method of replacing ++ * every space in the id string with _ and the new/multipath ++ * format_t10_id replacing series of spaces with one _. ++ */ ++struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids) ++{ ++ struct dev_wwid *dw; ++ int len; ++ ++ if (!id_type) { ++ id_type = _wwid_type_num(id); ++ if (id_type == -1) ++ log_debug("unknown wwid type %s", id); ++ } ++ ++ if (!(dw = zalloc(sizeof(struct dev_wwid)))) ++ return NULL; ++ len = strlen(id); ++ if (len >= DEV_WWID_SIZE) ++ len = DEV_WWID_SIZE - 1; ++ memcpy(dw->id, id, len); ++ dw->type = id_type; ++ dm_list_add(ids, &dw->list); ++ return dw; ++} ++ ++/* ++ * we save ids with format: naa., eui., t10.. ++ * multipath wwids file uses format: 3, 2, 1. ++ * The values are saved in wwid_hash_tab without the type prefix. ++ */ ++ ++static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev, ++ int primary_result, dev_t primary_dev) ++{ ++ char idbuf[DEV_WWID_SIZE] = { 0 }; ++ struct dev_wwid *dw; ++ char *wwid; ++ ++ if (!_wwid_hash_tab) + return 0; + + /* +- * sysfs prints wwid as . +- * multipath wwid uses '3' +- * does "." always correspond to "3"? ++ * Check the primary device, not the partition. + */ +- if (!(wwid = strchr(sysbuf, '.'))) +- return 0; ++ if (primary_result == 2) { ++ if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) { ++ log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev)); ++ return 0; ++ } ++ } + +- /* skip the type and dot, just as '3' was skipped from wwids entry */ +- wwid++; +- +- look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid)); ++ /* ++ * This function may be called multiple times for the same device, in ++ * particular if partitioned for each partition. ++ */ ++ if (!dm_list_empty(&dev->wwids)) ++ goto lookup; + +- if (look) { +- log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid); +- return 1; ++ /* ++ * Get all the ids for the device from vpd_pg83 and check if any of ++ * those are in /etc/multipath/wwids. These ids should include the ++ * value printed from the sysfs wwid file. ++ */ ++ _read_sys_vpd_wwids(cmd, dev, &dev->wwids); ++ if (!dm_list_empty(&dev->wwids)) ++ goto lookup; ++ ++ /* ++ * This will read the sysfs wwid file, nvme devices in particular have ++ * a wwid file but not a vpd_pg83 file. ++ */ ++ if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf))) ++ add_wwid(idbuf, 0, &dev->wwids); ++ ++ lookup: ++ dm_list_iterate_items(dw, &dev->wwids) { ++ if (dw->type == 1 || dw->type == 2 || dw->type == 3) ++ wwid = &dw->id[4]; ++ else ++ wwid = dw->id; ++ ++ if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) { ++ log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id); ++ return 1; ++ } + } ++ + return 0; + } + + int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *holder_devno) + { +- if (_dev_is_mpath_component_sysfs(cmd, dev, holder_devno) == 1) ++ struct dev_types *dt = cmd->dev_types; ++ int primary_result; ++ dev_t primary_dev; ++ ++ /* ++ * multipath only uses SCSI or NVME devices ++ */ ++ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev)) ++ return 0; ++ ++ /* ++ * primary_result 2: dev is a partition, primary_dev is the whole device ++ * primary_result 1: dev is a whole device ++ */ ++ primary_result = dev_get_primary_dev(dt, dev, &primary_dev); ++ ++ if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev, holder_devno) == 1) + goto found; + +- if (_dev_in_wwid_file(cmd, dev)) ++ if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev)) + goto found; + + if (external_device_info_source() == DEV_EXT_UDEV) { +@@ -641,6 +791,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h + goto found; + } + ++ /* ++ * TODO: save the result of this function in dev->flags and use those ++ * flags on repeated calls to avoid repeating the work multiple times ++ * for the same device when there are partitions on the device. ++ */ ++ + return 0; + found: + return 1; +diff --git a/lib/device/device.h b/lib/device/device.h +index d0d670ec3..06440f44b 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -59,6 +59,14 @@ struct dev_ext { + void *handle; + }; + ++#define DEV_WWID_SIZE 128 ++ ++struct dev_wwid { ++ struct dm_list list; ++ int type; ++ char id[DEV_WWID_SIZE]; ++}; ++ + #define DEV_ID_TYPE_SYS_WWID 0x0001 + #define DEV_ID_TYPE_SYS_SERIAL 0x0002 + #define DEV_ID_TYPE_MPATH_UUID 0x0003 +@@ -105,6 +113,7 @@ struct dev_use { + */ + struct device { + struct dm_list aliases; /* struct dm_str_list */ ++ struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */ + struct dm_list ids; /* struct dev_id, different entries for different idtypes */ + struct dev_id *id; /* points to the the ids entry being used for this dev */ + dev_t dev; +@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev); + + int dev_mpath_init(const char *config_wwids_file); + void dev_mpath_exit(void); ++struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids); ++void free_wwids(struct dm_list *ids); ++int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids); ++int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes); + + #endif +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index f1928347c..9dec9f884 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids) + } + } + +-int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize) ++static int _read_sys_block(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, ++ int binary, int *retlen) + { + char path[PATH_MAX]; + dev_t devt = dev->dev; +@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff + return 0; + } + +- get_sysfs_value(path, sysbuf, sysbufsize, 0); ++ if (binary) { ++ ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen); ++ if (ret && !*retlen) ++ ret = 0; ++ } else { ++ ret = get_sysfs_value(path, sysbuf, sysbufsize, 0); ++ if (ret && !sysbuf[0]) ++ ret = 0; ++ } + +- if (sysbuf[0]) { +- if (prim) +- log_debug("Using primary device_id for partition %s.", dev_name(dev)); ++ if (ret) { + sysbuf[sysbufsize - 1] = '\0'; + return 1; + } +@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff + return 0; + } + ++int read_sys_block(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize) ++{ ++ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL); ++} ++ ++int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, ++ int *retlen) ++{ ++ return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen); ++} ++ + static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix) + { + if (!strncmp(sysbuf, prefix, strlen(prefix))) +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index 94773a65e..9b9c9ce03 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -58,6 +58,8 @@ void devices_file_exit(struct cmd_context *cmd); + void unlink_searched_devnames(struct cmd_context *cmd); + + int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize); ++int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, ++ const char *suffix, char *sysbuf, int sysbufsize, int *retlen); + + int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out); + +diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c +new file mode 100644 +index 000000000..4bafa7b9e +--- /dev/null ++++ b/lib/device/parse_vpd.c +@@ -0,0 +1,199 @@ ++/* ++ * Copyright (C) 2022 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 "base/memory/zalloc.h" ++#include "lib/misc/lib.h" ++#include "lib/device/device.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Replace series of spaces with a single _. ++ */ ++int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) ++{ ++ int in_space = 0; ++ int retlen = 0; ++ int j = 0; ++ int i; ++ ++ for (i = 0; i < in_bytes; i++) { ++ if (!in[i]) ++ break; ++ if (j >= (out_bytes - 2)) ++ break; ++ /* skip leading spaces */ ++ if (!retlen && (in[i] == ' ')) ++ continue; ++ /* replace one or more spaces with _ */ ++ if (in[i] == ' ') { ++ in_space = 1; ++ continue; ++ } ++ /* spaces are finished so insert _ */ ++ if (in_space) { ++ out[j++] = '_'; ++ in_space = 0; ++ retlen++; ++ } ++ out[j++] = in[i]; ++ retlen++; ++ } ++ return retlen; ++} ++ ++static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes) ++{ ++ int off = 0; ++ int num; ++ int i; ++ ++ for (i = 0; i < in_bytes; i++) { ++ num = sprintf((char *)out + off, "%02x", in[i]); ++ if (num < 0) ++ break; ++ off += num; ++ if (off + 2 >= out_bytes) ++ break; ++ } ++ return off; ++} ++ ++#define ID_BUFSIZE 1024 ++ ++/* ++ * based on linux kernel function ++ */ ++int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids) ++{ ++ char id[ID_BUFSIZE]; ++ unsigned char tmp_str[ID_BUFSIZE]; ++ const unsigned char *d, *cur_id_str; ++ size_t id_len = ID_BUFSIZE; ++ int id_size = -1; ++ uint8_t cur_id_size = 0; ++ ++ memset(id, 0, ID_BUFSIZE); ++ for (d = vpd_data + 4; ++ d < vpd_data + vpd_datalen; ++ d += d[3] + 4) { ++ memset(tmp_str, 0, sizeof(tmp_str)); ++ ++ switch (d[1] & 0xf) { ++ case 0x1: ++ /* T10 Vendor ID */ ++ cur_id_size = d[3]; ++ if (cur_id_size + 4 > id_len) ++ cur_id_size = id_len - 4; ++ cur_id_str = d + 4; ++ format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str); ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 1, ids); ++ break; ++ case 0x2: ++ /* EUI-64 */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ switch (cur_id_size) { ++ case 8: ++ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ case 12: ++ _to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ case 16: ++ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str); ++ break; ++ default: ++ break; ++ } ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 2, ids); ++ break; ++ case 0x3: ++ /* NAA */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ switch (cur_id_size) { ++ case 8: ++ _to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); ++ break; ++ case 16: ++ _to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str)); ++ id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str); ++ break; ++ default: ++ break; ++ } ++ if (id_size < 0) ++ break; ++ if (id_size >= ID_BUFSIZE) ++ id_size = ID_BUFSIZE - 1; ++ add_wwid(id, 3, ids); ++ break; ++ case 0x8: ++ /* SCSI name string */ ++ cur_id_size = d[3]; ++ cur_id_str = d + 4; ++ if (cur_id_size >= id_len) ++ cur_id_size = id_len - 1; ++ memcpy(id, cur_id_str, cur_id_size); ++ id_size = cur_id_size; ++ ++ /* ++ * Not in the kernel version, copying multipath code, ++ * which checks if this string begins with naa or eui ++ * and if so does tolower() on the chars. ++ */ ++ if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) { ++ int i; ++ for (i = 0; i < id_size; i++) ++ id[i] = tolower(id[i]); ++ } ++ add_wwid(id, 8, ids); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return id_size; ++} +-- +2.34.3 + diff --git a/0005-pvdisplay-restore-reportformat-option.patch b/0005-pvdisplay-restore-reportformat-option.patch new file mode 100644 index 0000000..b437a9c --- /dev/null +++ b/0005-pvdisplay-restore-reportformat-option.patch @@ -0,0 +1,36 @@ +From 3cfb00e5f7c720549100c5297be18600c9abf530 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 24 Jun 2022 10:40:54 -0500 +Subject: [PATCH 5/7] pvdisplay: restore --reportformat option + +Fixes commit b8f4ec846 "display: ignore --reportformat" +by restoring the --reportformat option to pvdisplay. +Adding -C to pvdisplay turns the command into a reporting +command (like pvs, vgs, lvs) in which --reportformat can +be useful. + +(cherry picked from commit db5277c97155632ce83e1125e348eda97c871968) +--- + tools/command-lines.in | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/command-lines.in b/tools/command-lines.in +index b64fd0dda..b6a03d158 100644 +--- a/tools/command-lines.in ++++ b/tools/command-lines.in +@@ -1593,10 +1593,10 @@ pvdisplay + OO: --aligned, --all, --binary, --colon, --columns, --configreport ConfigReport, + --foreign, --ignorelockingfailure, + --logonly, --maps, --noheadings, --nosuffix, --options String, +---readonly, --select String, --separator String, --shared, ++--readonly, --reportformat ReportFmt, --select String, --separator String, --shared, + --short, --sort String, --unbuffered, --units Units + OP: PV|Tag ... +-IO: --ignoreskippedcluster, --reportformat ReportFmt ++IO: --ignoreskippedcluster + ID: pvdisplay_general + + --- +-- +2.34.3 + diff --git a/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch b/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch new file mode 100644 index 0000000..273c939 --- /dev/null +++ b/0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch @@ -0,0 +1,247 @@ +From a369a7fd1fccf3c50103dd294b79055cc7c9d005 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Tue, 5 Jul 2022 17:08:00 -0500 +Subject: [PATCH 6/7] exit with error when --devicesfile name doesn't exist + +(cherry picked from commit 92b4fcf57f3c6d212d06b72b097e1a06e6efb84b) +--- + lib/cache/lvmcache.c | 3 ++- + lib/label/label.c | 4 ++-- + test/shell/devicesfile-basic.sh | 1 + + tools/pvcreate.c | 3 ++- + tools/pvremove.c | 3 ++- + tools/pvscan.c | 3 ++- + tools/toollib.c | 27 +++++++++++++++++++++------ + tools/vgcfgrestore.c | 5 ++++- + tools/vgcreate.c | 5 ++++- + tools/vgextend.c | 3 ++- + tools/vgmerge.c | 3 ++- + tools/vgsplit.c | 3 ++- + 12 files changed, 46 insertions(+), 17 deletions(-) + +diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c +index 22edcfd84..a1c4a61c8 100644 +--- a/lib/cache/lvmcache.c ++++ b/lib/cache/lvmcache.c +@@ -1612,7 +1612,8 @@ int lvmcache_label_scan(struct cmd_context *cmd) + * with infos/vginfos based on reading headers from + * each device, and a vg summary from each mda. + */ +- label_scan(cmd); ++ if (!label_scan(cmd)) ++ return_0; + + /* + * When devnames are used as device ids (which is dispreferred), +diff --git a/lib/label/label.c b/lib/label/label.c +index 711edb6f4..f845abb96 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -801,7 +801,7 @@ static int _setup_bcache(void) + } + + if (!(scan_bcache = bcache_create(BCACHE_BLOCK_SIZE_IN_SECTORS, cache_blocks, ioe))) { +- log_error("Failed to create bcache with %d cache blocks.", cache_blocks); ++ log_error("Failed to set up io layer with %d blocks.", cache_blocks); + return 0; + } + +@@ -1292,7 +1292,7 @@ int label_scan(struct cmd_context *cmd) + * data to invalidate.) + */ + if (!(iter = dev_iter_create(NULL, 0))) { +- log_error("Scanning failed to get devices."); ++ log_error("Failed to get device list."); + return 0; + } + while ((dev = dev_iter_get(cmd, iter))) { +diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh +index 77fe265a0..715c579b3 100644 +--- a/test/shell/devicesfile-basic.sh ++++ b/test/shell/devicesfile-basic.sh +@@ -107,6 +107,7 @@ not vgs --devicesfile test.devices $vg2 + # misspelled override name fails + not vgs --devicesfile doesnotexist $vg1 + not vgs --devicesfile doesnotexist $vg2 ++not vgs --devicesfile doesnotexist + + # devicesfile and devices cannot be used together + not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1 +diff --git a/tools/pvcreate.c b/tools/pvcreate.c +index 71eb060a3..a1ef0e9e1 100644 +--- a/tools/pvcreate.c ++++ b/tools/pvcreate.c +@@ -144,7 +144,8 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) + + cmd->create_edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(handle = init_processing_handle(cmd, NULL))) { + log_error("Failed to initialize processing handle."); +diff --git a/tools/pvremove.c b/tools/pvremove.c +index 2dfdbd016..5c39ee0c7 100644 +--- a/tools/pvremove.c ++++ b/tools/pvremove.c +@@ -45,7 +45,8 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv) + + clear_hint_file(cmd); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + /* When forcibly clearing a PV we don't care about a VG lock. */ + if (pp.force == DONT_PROMPT_OVERRIDE) +diff --git a/tools/pvscan.c b/tools/pvscan.c +index 1e47d754a..72c3279c3 100644 +--- a/tools/pvscan.c ++++ b/tools/pvscan.c +@@ -1407,7 +1407,8 @@ static int _pvscan_cache_all(struct cmd_context *cmd, int argc, char **argv, + * which we want 'pvscan --cache' to do, and that uses + * info from lvmcache, e.g. duplicate pv info. + */ +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_0; + + cmd->pvscan_recreate_hints = 0; + cmd->use_hints = 0; +diff --git a/tools/toollib.c b/tools/toollib.c +index d77092d89..544791808 100644 +--- a/tools/toollib.c ++++ b/tools/toollib.c +@@ -1655,7 +1655,10 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv, + + log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LABEL); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } + + if (argc) { + for (; opt < argc; opt++) { +@@ -2435,8 +2438,13 @@ int process_each_vg(struct cmd_context *cmd, + * Scan all devices to populate lvmcache with initial + * list of PVs and VGs. + */ +- if (!(read_flags & PROCESS_SKIP_SCAN)) +- lvmcache_label_scan(cmd); ++ if (!(read_flags & PROCESS_SKIP_SCAN)) { ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } ++ } ++ + + /* + * A list of all VGs on the system is needed when: +@@ -3987,7 +3995,10 @@ int process_each_lv(struct cmd_context *cmd, + * Scan all devices to populate lvmcache with initial + * list of PVs and VGs. + */ +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } + + /* + * A list of all VGs on the system is needed when: +@@ -4623,8 +4634,12 @@ int process_each_pv(struct cmd_context *cmd, + goto_out; + } + +- if (!(read_flags & PROCESS_SKIP_SCAN)) +- lvmcache_label_scan(cmd); ++ if (!(read_flags & PROCESS_SKIP_SCAN)) { ++ if (!lvmcache_label_scan(cmd)) { ++ ret_max = ECMD_FAILED; ++ goto_out; ++ } ++ } + + if (!lvmcache_get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) { + ret_max = ret; +diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c +index e49313d14..9fcba89d4 100644 +--- a/tools/vgcfgrestore.c ++++ b/tools/vgcfgrestore.c +@@ -132,7 +132,10 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) + + clear_hint_file(cmd); + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ unlock_vg(cmd, NULL, vg_name); ++ return_ECMD_FAILED; ++ } + + cmd->handles_unknown_segments = 1; + +diff --git a/tools/vgcreate.c b/tools/vgcreate.c +index dde3f1eac..14608777f 100644 +--- a/tools/vgcreate.c ++++ b/tools/vgcreate.c +@@ -84,7 +84,10 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) + + cmd->create_edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) { ++ unlock_vg(cmd, NULL, vp_new.vg_name); ++ return_ECMD_FAILED; ++ } + + if (lvmcache_vginfo_from_vgname(vp_new.vg_name, NULL)) { + unlock_vg(cmd, NULL, vp_new.vg_name); +diff --git a/tools/vgextend.c b/tools/vgextend.c +index 0856b4c78..fecd6bdd5 100644 +--- a/tools/vgextend.c ++++ b/tools/vgextend.c +@@ -160,7 +160,8 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv) + + cmd->edit_devices_file = 1; + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(handle = init_processing_handle(cmd, NULL))) { + log_error("Failed to initialize processing handle."); +diff --git a/tools/vgmerge.c b/tools/vgmerge.c +index 08615cd62..4ed4a8f0b 100644 +--- a/tools/vgmerge.c ++++ b/tools/vgmerge.c +@@ -72,7 +72,8 @@ static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to, + return ECMD_FAILED; + } + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (strcmp(vg_name_to, vg_name_from) > 0) + lock_vg_from_first = 1; +diff --git a/tools/vgsplit.c b/tools/vgsplit.c +index 5f113b363..c7f4b8af4 100644 +--- a/tools/vgsplit.c ++++ b/tools/vgsplit.c +@@ -559,7 +559,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv) + return ECMD_FAILED; + } + +- lvmcache_label_scan(cmd); ++ if (!lvmcache_label_scan(cmd)) ++ return_ECMD_FAILED; + + if (!(vginfo_to = lvmcache_vginfo_from_vgname(vg_name_to, NULL))) { + if (!validate_name(vg_name_to)) { +-- +2.34.3 + diff --git a/0007-make-generate.patch b/0007-make-generate.patch new file mode 100644 index 0000000..3e51442 --- /dev/null +++ b/0007-make-generate.patch @@ -0,0 +1,43 @@ +From a8588f39219a2794fad562b38e6dc63aee791f82 Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 11 Jul 2022 01:02:22 +0200 +Subject: [PATCH 7/7] make: generate + +(cherry picked from commit c0f8e6675c62332263acdc7c3c2f61eca20bd60f) +--- + man/pvdisplay.8_pregen | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/man/pvdisplay.8_pregen b/man/pvdisplay.8_pregen +index 23d41b29b..e7767d0c4 100644 +--- a/man/pvdisplay.8_pregen ++++ b/man/pvdisplay.8_pregen +@@ -61,6 +61,8 @@ and more, using a more compact and configurable output format. + .br + [ \fB--readonly\fP ] + .br ++[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ] ++.br + [ \fB--separator\fP \fIString\fP ] + .br + [ \fB--shared\fP ] +@@ -320,6 +322,16 @@ device-mapper kernel driver, so this option is unable to report whether + or not LVs are actually in use. + . + .HP ++\fB--reportformat\fP \fBbasic\fP|\fBjson\fP ++.br ++Overrides current output format for reports which is defined globally by ++the report/output_format setting in \fBlvm.conf\fP(5). ++\fBbasic\fP is the original format with columns and rows. ++If there is more than one report per command, each report is prefixed ++with the report name for identification. \fBjson\fP produces report ++output in JSON format. See \fBlvmreport\fP(7) for more information. ++. ++.HP + \fB-S\fP|\fB--select\fP \fIString\fP + .br + Select objects for processing and reporting based on specified criteria. +-- +2.34.3 + diff --git a/LVM2.2.03.11.tgz.asc b/LVM2.2.03.11.tgz.asc deleted file mode 100644 index ef62186..0000000 --- a/LVM2.2.03.11.tgz.asc +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (GNU/Linux) - -iQIcBAABAgAGBQJf+CGBAAoJELkRJDHlCQOfbcAQAIky3+aEOxnpeT5T2XFRvsCJ -Uk71G70q24JupybEEYvhehf3RmeQkLP3c0TeNMFweqzUwpZBIhpbymglhaNG2AZc -3Bbnl1SAGZ5IzdqacrKfCIas1b/UZMbRAhjcCFQ3oD0SApl+dED2RUacJCnlZxkE -NX3+MG4S6po84uQdHwZGtAw2+HQ0G5GwIETjxJHcQ+q8SZdWJRhKU25Z7UC1LI5u -648SmSlsy2KoNIOSM/sWwgz1MXSWnN0y1mBxfBrR7bdnrPW+ExumzTqZrECIuiyl -bbD3Me/wEfyk4XZt2SoZF9k0Hf3QcSULeTeJlHOqUfLRGKm9E9ngkR/yfb2De/zP -tMzvFyu/tiCfFRXmQbS7K8dFzUzs6KQCHIPuJYnv+BjxOW9gjeyK5JPgBCsOLu// -mEf64ttDDKmCx1qOEnMhxTckvSH8YedmbQRov3g0ZXE3syG4OrhT1DHTyAnv69/f -fNVhOjd4POAoQx2UQzftgU7f4LiMPrQyRiUnQ0DRxHSEYXnIngpqokaVodfvpJp5 -8YEuce9Xvq9JCplzKc1OXNtZQUHMybeyVzeenPVYvRV11ZbHzMAzwB6Byhwc9xgt -iKIuWpxMiPveKih3l/THoGOj19OUAN2XvWcGbOa6hTy6m/wsnoJQ0Xx5b5Ysfc1s -U60q2IDLJUS0H2R2raoc -=NE9u ------END PGP SIGNATURE----- diff --git a/LVM2.2.03.16.tgz.asc b/LVM2.2.03.16.tgz.asc new file mode 100644 index 0000000..60befb6 --- /dev/null +++ b/LVM2.2.03.16.tgz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEE1QGkeEQK4v0TChvouREkMeUJA58FAmKFHcYACgkQuREkMeUJ +A58CdQ//UthHUyGSHS2LiNKPhpr4vKuxstwlOclxHjvardZ1QW7ry5Ype5Elrnfb +GVot/9oZPzoYzuHaMp6E8rRTfdsmiuSU9mQ3sTDAzPcuB9QbiZUW9oTCLfACTRqK +bP8XdKVE/sJgllUFz93kQke69GntBuvrvXFzUF4yMSSRwvWMtZ4jTs2KSfCdFJUB +3r4d9ynxTdcskexYQ0fnXubl5FRokKlmi7k5G0n2BnI/eqMMMsJg8lGYiw7kmkPc +7cqE9FJzVhzEv3rLYz0+gc7/6JymAJAJcUD5jaToI3eyA6KhqauH03HZhc5JDtxL +nthpURhCETDp/St/DsXWffVCKXBKq5TIa44Hh/n1TgFKVvgshEwOCWMmsh4P1MKI +ilvwkjmpzGbVOAgFUIJnMPOpg5aQ8jatFDbzcFwUXpIXdfSS+0ghMyc4Vihh1sa0 +wAM7hYSvzjYAXPb+UjRrwRunmU36SgvUpg8ZI8ZxvFgLw57IAxqlx41MbQjtPg4B +3hI/ibtiWckVwROmga1daeLe696h4lrXjRCjj85EG8FsAuZpUikuSf1ym/3uF0aP +142Dd8lvWjfjl9nXDU8cl3Ke7JFfEtQUplswaaIpwKXv37dlwyfaCrgR/laLTs4V +xLh50C5Hxr1RPQwt1qPzM6tNYS+R3O8B56iWzcF8WIBiOOG5XWc= +=HIKn +-----END PGP SIGNATURE----- diff --git a/lvm2-2_03_12-WHATS_NEW-update.patch b/lvm2-2_03_12-WHATS_NEW-update.patch deleted file mode 100644 index ed16b64..0000000 --- a/lvm2-2_03_12-WHATS_NEW-update.patch +++ /dev/null @@ -1,15 +0,0 @@ - WHATS_NEW | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index ffefc9d..3953c7e 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,7 @@ - Version 2.03.12 - - =================================== -+ Fix problem with wiping of converted LVs. -+ Fix memleak in scanning (2.03.11). - Fix corner case allocation for thin-pools. - - Version 2.03.11 - 08th January 2021 diff --git a/lvm2-2_03_12-alloc-enhance-estimation-of-sufficient_pes_free.patch b/lvm2-2_03_12-alloc-enhance-estimation-of-sufficient_pes_free.patch deleted file mode 100644 index a60a2b8..0000000 --- a/lvm2-2_03_12-alloc-enhance-estimation-of-sufficient_pes_free.patch +++ /dev/null @@ -1,47 +0,0 @@ - WHATS_NEW | 10 ++++++++-- - lib/metadata/lv_manip.c | 10 +++++++--- - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 452a631..fe347f7 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,3 +1,7 @@ -+Version 2.03.12 - -+=================================== -+ Fix corner case allocation for thin-pools. -+ - Version 2.03.11 - 08th January 2021 - =================================== - Fix pvck handling MDA at offset different from 4096. -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index 7046436..443d32c 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -1850,11 +1850,13 @@ static uint32_t _mirror_log_extents(uint32_t region_size, uint32_t pe_size, uint - - /* Is there enough total space or should we give up immediately? */ - static int _sufficient_pes_free(struct alloc_handle *ah, struct dm_list *pvms, -- uint32_t allocated, uint32_t extents_still_needed) -+ uint32_t allocated, uint32_t log_still_needed, -+ uint32_t extents_still_needed) - { - uint32_t area_extents_needed = (extents_still_needed - allocated) * ah->area_count / ah->area_multiple; - uint32_t parity_extents_needed = (extents_still_needed - allocated) * ah->parity_count / ah->area_multiple; -- uint32_t metadata_extents_needed = ah->alloc_and_split_meta ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN + ah->log_len; /* One each */ -+ uint32_t metadata_extents_needed = (ah->alloc_and_split_meta ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN) + -+ (log_still_needed ? ah->log_len : 0); /* One each */ - uint64_t total_extents_needed = (uint64_t)area_extents_needed + parity_extents_needed + metadata_extents_needed; - uint32_t free_pes = pv_maps_size(pvms); - -@@ -3359,7 +3361,9 @@ static int _allocate(struct alloc_handle *ah, - old_allocated = alloc_state.allocated; - log_debug_alloc("Trying allocation using %s policy.", get_alloc_string(alloc)); - -- if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated, ah->new_extents)) -+ if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated, -+ alloc_state.log_area_count_still_needed, -+ ah->new_extents)) - goto_out; - - _init_alloc_parms(ah, &alloc_parms, alloc, prev_lvseg, diff --git a/lvm2-2_03_12-cache-reuse-code-for-metadata-min_max.patch b/lvm2-2_03_12-cache-reuse-code-for-metadata-min_max.patch deleted file mode 100644 index ce35731..0000000 --- a/lvm2-2_03_12-cache-reuse-code-for-metadata-min_max.patch +++ /dev/null @@ -1,107 +0,0 @@ - lib/metadata/cache_manip.c | 40 ++++++++++++++-------------------------- - lib/metadata/metadata-exported.h | 1 + - tools/lvconvert.c | 1 + - tools/lvcreate.c | 1 + - 4 files changed, 17 insertions(+), 26 deletions(-) - -diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c -index 2c4cc92..90ebd94 100644 ---- a/lib/metadata/cache_manip.c -+++ b/lib/metadata/cache_manip.c -@@ -204,6 +204,7 @@ int update_cache_pool_params(struct cmd_context *cmd, - unsigned attr, - uint32_t pool_data_extents, - uint32_t *pool_metadata_extents, -+ struct logical_volume *metadata_lv, - int *chunk_size_calc_method, uint32_t *chunk_size) - { - uint64_t min_meta_size; -@@ -252,39 +253,26 @@ int update_cache_pool_params(struct cmd_context *cmd, - if (!validate_cache_chunk_size(cmd, *chunk_size)) - return_0; - -- min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size); -+ if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) { -+ log_error("Size of %s data volume cannot be smaller than chunk size %s.", -+ segtype->name, display_size(cmd, *chunk_size)); -+ return 0; -+ } - -- /* Round up to extent size */ -- if (min_meta_size % extent_size) -- min_meta_size += extent_size - min_meta_size % extent_size; -+ min_meta_size = _cache_min_metadata_size((uint64_t) pool_data_extents * extent_size, *chunk_size); -+ min_meta_size = dm_round_up(min_meta_size, extent_size); - - if (!pool_metadata_size) - pool_metadata_size = min_meta_size; - -- if (pool_metadata_size > (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE)) { -- pool_metadata_size = 2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE; -- if (*pool_metadata_extents) -- log_warn("WARNING: Maximum supported pool metadata size is %s.", -- display_size(cmd, pool_metadata_size)); -- } else if (pool_metadata_size < min_meta_size) { -- if (*pool_metadata_extents) -- log_warn("WARNING: Minimum required pool metadata size is %s " -- "(needs extra %s).", -- display_size(cmd, min_meta_size), -- display_size(cmd, min_meta_size - pool_metadata_size)); -- pool_metadata_size = min_meta_size; -- } -- -- if (!(*pool_metadata_extents = -- extents_from_size(cmd, pool_metadata_size, extent_size))) -+ if (!update_pool_metadata_min_max(cmd, extent_size, -+ min_meta_size, -+ (2 * DEFAULT_CACHE_POOL_MAX_METADATA_SIZE), -+ &pool_metadata_size, -+ metadata_lv, -+ pool_metadata_extents)) - return_0; - -- if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) { -- log_error("Size of %s data volume cannot be smaller than chunk size %s.", -- segtype->name, display_size(cmd, *chunk_size)); -- return 0; -- } -- - log_verbose("Preferred pool metadata size %s.", - display_size(cmd, (uint64_t)*pool_metadata_extents * extent_size)); - -diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h -index 0e57722..c0fa564 100644 ---- a/lib/metadata/metadata-exported.h -+++ b/lib/metadata/metadata-exported.h -@@ -1319,6 +1319,7 @@ int update_cache_pool_params(struct cmd_context *cmd, - unsigned attr, - uint32_t pool_data_extents, - uint32_t *pool_metadata_extents, -+ struct logical_volume *metadata_lv, - int *chunk_size_calc_method, uint32_t *chunk_size); - int validate_lv_cache_chunk_size(struct logical_volume *pool_lv, uint32_t chunk_size); - int validate_lv_cache_create_pool(const struct logical_volume *pool_lv); -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index ce90279..416e8a7 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -3189,6 +3189,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - pool_segtype, target_attr, - lv->le_count, - &meta_extents, -+ metadata_lv, - &chunk_calc, - &chunk_size)) - goto_bad; -diff --git a/tools/lvcreate.c b/tools/lvcreate.c -index 1ee9e14..1ce561f 100644 ---- a/tools/lvcreate.c -+++ b/tools/lvcreate.c -@@ -403,6 +403,7 @@ static int _update_extents_params(struct volume_group *vg, - lp->segtype, lp->target_attr, - lp->extents, - &lp->pool_metadata_extents, -+ NULL, - &lp->thin_chunk_size_calc_policy, - &lp->chunk_size)) - return_0; diff --git a/lvm2-2_03_12-config-avoid-printing-spaces-before-end-of-line.patch b/lvm2-2_03_12-config-avoid-printing-spaces-before-end-of-line.patch deleted file mode 100644 index ffed82b..0000000 --- a/lvm2-2_03_12-config-avoid-printing-spaces-before-end-of-line.patch +++ /dev/null @@ -1,613 +0,0 @@ - conf/example.conf.in | 146 +++++++++++++++++++++++++------------------------- - conf/lvmlocal.conf.in | 4 +- - lib/config/config.c | 2 +- - 3 files changed, 76 insertions(+), 76 deletions(-) - -diff --git a/conf/example.conf.in b/conf/example.conf.in -index d149ed9..cd53147 100644 ---- a/conf/example.conf.in -+++ b/conf/example.conf.in -@@ -78,14 +78,14 @@ devices { - # routines to acquire this information. For example, this information - # is used to drive LVM filtering like MD component detection, multipath - # component detection, partition detection and others. -- # -+ # - # Accepted values: - # none - # No external device information source is used. - # udev - # Reuse existing udev database records. Applicable only if LVM is - # compiled with udev support. -- # -+ # - external_device_info_source = "none" - - # Configuration option devices/hints. -@@ -94,13 +94,13 @@ devices { - # scanning, and will only scan the listed PVs. Removing the hint file - # will cause lvm to generate a new one. Disable hints if PVs will - # be copied onto devices using non-lvm commands, like dd. -- # -+ # - # Accepted values: - # all - # Use all hints. - # none - # Use no hints. -- # -+ # - # This configuration option has an automatic default value. - # hints = "all" - -@@ -118,11 +118,11 @@ devices { - # Prefer the name with the least number of slashes. - # Prefer a name that is a symlink. - # Prefer the path with least value in lexicographical order. -- # -+ # - # Example - # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] -- # -- # This configuration option has an automatic default value. -+ # -+ # This configuration option does not have a default value defined. - # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] - - # Configuration option devices/filter. -@@ -140,7 +140,7 @@ devices { - # then the device is accepted. Be careful mixing 'a' and 'r' patterns, - # as the combination might produce unexpected results (test changes.) - # Run vgscan after changing the filter to regenerate the cache. -- # -+ # - # Example - # Accept every block device: - # filter = [ "a|.*|" ] -@@ -152,7 +152,7 @@ devices { - # filter = [ "a|loop|", "r|/dev/hdc|", "a|/dev/ide|", "r|.*|" ] - # Use anchors to be very specific: - # filter = [ "a|^/dev/hda8$|", "r|.*|" ] -- # -+ # - # This configuration option has an automatic default value. - # filter = [ "a|.*|" ] - -@@ -170,10 +170,10 @@ devices { - # List of additional acceptable block device types. - # These are of device type names from /proc/devices, followed by the - # maximum number of partitions. -- # -+ # - # Example - # types = [ "fd", 16 ] -- # -+ # - # This configuration option is advanced. - # This configuration option does not have a default value defined. - -@@ -215,7 +215,7 @@ devices { - # Configuration option devices/md_component_checks. - # The checks LVM should use to detect MD component devices. - # MD component devices are block devices used by MD software RAID. -- # -+ # - # Accepted values: - # auto - # LVM will skip scanning the end of devices when it has other -@@ -226,7 +226,7 @@ devices { - # full - # LVM will scan the start and end of devices for MD superblocks. - # This requires an extra read at the end of devices. -- # -+ # - # This configuration option has an automatic default value. - # md_component_checks = "auto" - -@@ -368,7 +368,7 @@ allocation { - # defined here, it will check whether any of them are attached to the - # PVs concerned and then seek to match those PV tags between existing - # extents and new extents. -- # -+ # - # Example - # Use the special tag "@*" as a wildcard to match any PV tag: - # cling_tag_list = [ "@*" ] -@@ -376,7 +376,7 @@ allocation { - # PVs are tagged with either @site1 or @site2 to indicate where - # they are situated: - # cling_tag_list = [ "@site1", "@site2" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option allocation/maximise_cling. -@@ -435,25 +435,25 @@ allocation { - - # Configuration option allocation/cache_metadata_format. - # Sets default metadata format for new cache. -- # -+ # - # Accepted values: - # 0 Automatically detected best available format - # 1 Original format - # 2 Improved 2nd. generation format -- # -+ # - # This configuration option has an automatic default value. - # cache_metadata_format = 0 - - # Configuration option allocation/cache_mode. - # The default cache mode used for new cache. -- # -+ # - # Accepted values: - # writethrough - # Data blocks are immediately written from the cache to disk. - # writeback - # Data blocks are written from the cache back to disk after some - # delay to improve performance. -- # -+ # - # This setting replaces allocation/cache_pool_cachemode. - # This configuration option has an automatic default value. - # cache_mode = "writethrough" -@@ -502,18 +502,18 @@ allocation { - - # Configuration option allocation/thin_pool_discards. - # The discards behaviour of thin pool volumes. -- # -+ # - # Accepted values: - # ignore - # nopassdown - # passdown -- # -+ # - # This configuration option has an automatic default value. - # thin_pool_discards = "passdown" - - # Configuration option allocation/thin_pool_chunk_size_policy. - # The chunk size calculation policy for thin pool volumes. -- # -+ # - # Accepted values: - # generic - # If thin_pool_chunk_size is defined, use it. Otherwise, calculate -@@ -525,7 +525,7 @@ allocation { - # the chunk size for performance based on device hints exposed in - # sysfs - the optimal_io_size. The chunk size is always at least - # 512KiB. -- # -+ # - # This configuration option has an automatic default value. - # thin_pool_chunk_size_policy = "generic" - -@@ -962,7 +962,7 @@ global { - # Configuration option global/mirror_segtype_default. - # The segment type used by the short mirroring option -m. - # The --type mirror|raid1 option overrides this setting. -- # -+ # - # Accepted values: - # mirror - # The original RAID1 implementation from LVM/DM. It is -@@ -982,16 +982,16 @@ global { - # handling a failure. This mirror implementation is not - # cluster-aware and cannot be used in a shared (active/active) - # fashion in a cluster. -- # -+ # - mirror_segtype_default = "@DEFAULT_MIRROR_SEGTYPE@" - - # Configuration option global/support_mirrored_mirror_log. - # Enable mirrored 'mirror' log type for testing. -- # -+ # - # This type is deprecated to create or convert to but can - # be enabled to test that activation of existing mirrored - # logs and conversion to disk/core works. -- # -+ # - # Not supported for regular operation! - # This configuration option has an automatic default value. - # support_mirrored_mirror_log = 0 -@@ -1002,7 +1002,7 @@ global { - # The --stripes/-i and --mirrors/-m options can both be specified - # during the creation of a logical volume to use both striping and - # mirroring for the LV. There are two different implementations. -- # -+ # - # Accepted values: - # raid10 - # LVM uses MD's RAID10 personality through DM. This is the -@@ -1012,7 +1012,7 @@ global { - # is done by creating a mirror LV on top of striped sub-LVs, - # effectively creating a RAID 0+1 array. The layering is suboptimal - # in terms of providing redundancy and performance. -- # -+ # - raid10_segtype_default = "@DEFAULT_RAID10_SEGTYPE@" - - # Configuration option global/sparse_segtype_default. -@@ -1020,7 +1020,7 @@ global { - # The --type snapshot|thin option overrides this setting. - # The combination of -V and -L options creates a sparse LV. There are - # two different implementations. -- # -+ # - # Accepted values: - # snapshot - # The original snapshot implementation from LVM/DM. It uses an old -@@ -1032,7 +1032,7 @@ global { - # bigger minimal chunk size (64KiB) and uses a separate volume for - # metadata. It has better performance, especially when more data - # is used. It also supports full snapshots. -- # -+ # - sparse_segtype_default = "@DEFAULT_SPARSE_SEGTYPE@" - - # Configuration option global/lvdisplay_shows_full_device_path. -@@ -1130,20 +1130,20 @@ global { - # causing problems. Features include: block_size, discards, - # discards_non_power_2, external_origin, metadata_resize, - # external_origin_extend, error_if_no_space. -- # -+ # - # Example - # thin_disabled_features = [ "discards", "block_size" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option global/cache_disabled_features. - # Features to not use in the cache driver. - # This can be helpful for testing, or to avoid using a feature that is - # causing problems. Features include: policy_mq, policy_smq, metadata2. -- # -+ # - # Example - # cache_disabled_features = [ "policy_smq" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option global/cache_check_executable. -@@ -1207,7 +1207,7 @@ global { - # or vgimport.) A VG on shared storage devices is accessible only to - # the host with a matching system ID. See 'man lvmsystemid' for - # information on limitations and correct usage. -- # -+ # - # Accepted values: - # none - # The host has no system ID. -@@ -1224,7 +1224,7 @@ global { - # file - # Use the contents of another file (system_id_file) to set the - # system ID. -- # -+ # - system_id_source = "none" - - # Configuration option global/system_id_file. -@@ -1350,7 +1350,7 @@ activation { - # If this list is defined, an LV is only activated if it matches an - # entry in this list. If this list is undefined, it imposes no limits - # on LV activation (all are allowed). -- # -+ # - # Accepted values: - # vgname - # The VG name is matched exactly and selects all LVs in the VG. -@@ -1364,10 +1364,10 @@ activation { - # or VG. See tags/hosttags. If any host tags exist but volume_list - # is not defined, a default single-entry list containing '@*' - # is assumed. -- # -+ # - # Example - # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option activation/auto_activation_volume_list. -@@ -1387,7 +1387,7 @@ activation { - # commands run directly by a user. A user may also use the 'a' flag - # directly to perform auto-activation. Also see pvscan(8) for more - # information about auto-activation. -- # -+ # - # Accepted values: - # vgname - # The VG name is matched exactly and selects all LVs in the VG. -@@ -1401,10 +1401,10 @@ activation { - # or VG. See tags/hosttags. If any host tags exist but volume_list - # is not defined, a default single-entry list containing '@*' - # is assumed. -- # -+ # - # Example - # auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option activation/read_only_volume_list. -@@ -1413,7 +1413,7 @@ activation { - # against this list, and if it matches, it is activated in read-only - # mode. This overrides the permission setting stored in the metadata, - # e.g. from --permission rw. -- # -+ # - # Accepted values: - # vgname - # The VG name is matched exactly and selects all LVs in the VG. -@@ -1427,10 +1427,10 @@ activation { - # or VG. See tags/hosttags. If any host tags exist but volume_list - # is not defined, a default single-entry list containing '@*' - # is assumed. -- # -+ # - # Example - # read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ] -- # -+ # - # This configuration option does not have a default value defined. - - # Configuration option activation/raid_region_size. -@@ -1453,13 +1453,13 @@ activation { - - # Configuration option activation/readahead. - # Setting to use when there is no readahead setting in metadata. -- # -+ # - # Accepted values: - # none - # Disable readahead. - # auto - # Use default value chosen by kernel. -- # -+ # - # This configuration option has an automatic default value. - # readahead = "auto" - -@@ -1471,7 +1471,7 @@ activation { - # performed by dmeventd automatically, and the steps perfomed by the - # manual command lvconvert --repair --use-policies. - # Automatic handling requires dmeventd to be monitoring the LV. -- # -+ # - # Accepted values: - # warn - # Use the system log to warn the user that a device in the RAID LV -@@ -1482,7 +1482,7 @@ activation { - # allocate - # Attempt to use any extra physical volumes in the VG as spares and - # replace faulty devices. -- # -+ # - raid_fault_policy = "warn" - - # Configuration option activation/mirror_image_fault_policy. -@@ -1494,7 +1494,7 @@ activation { - # determines the steps perfomed by dmeventd automatically, and the steps - # performed by the manual command lvconvert --repair --use-policies. - # Automatic handling requires dmeventd to be monitoring the LV. -- # -+ # - # Accepted values: - # remove - # Simply remove the faulty device and run without it. If the log -@@ -1519,7 +1519,7 @@ activation { - # the redundant nature of the mirror. This policy acts like - # 'remove' if no suitable device and space can be allocated for the - # replacement. -- # -+ # - mirror_image_fault_policy = "remove" - - # Configuration option activation/mirror_log_fault_policy. -@@ -1534,26 +1534,26 @@ activation { - # The minimum value is 50 (a smaller value is treated as 50.) - # Also see snapshot_autoextend_percent. - # Automatic extension requires dmeventd to be monitoring the LV. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 1G - # snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds - # 840M, it is extended to 1.44G: - # snapshot_autoextend_threshold = 70 -- # -+ # - snapshot_autoextend_threshold = 100 - - # Configuration option activation/snapshot_autoextend_percent. - # Auto-extending a snapshot adds this percent extra space. - # The amount of additional space added to a snapshot is this - # percent of its current size. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 1G - # snapshot exceeds 700M, it is extended to 1.2G, and when it exceeds - # 840M, it is extended to 1.44G: - # snapshot_autoextend_percent = 20 -- # -+ # - snapshot_autoextend_percent = 20 - - # Configuration option activation/thin_pool_autoextend_threshold. -@@ -1562,26 +1562,26 @@ activation { - # The minimum value is 50 (a smaller value is treated as 50.) - # Also see thin_pool_autoextend_percent. - # Automatic extension requires dmeventd to be monitoring the LV. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 1G - # thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds - # 840M, it is extended to 1.44G: - # thin_pool_autoextend_threshold = 70 -- # -+ # - thin_pool_autoextend_threshold = 100 - - # Configuration option activation/thin_pool_autoextend_percent. - # Auto-extending a thin pool adds this percent extra space. - # The amount of additional space added to a thin pool is this - # percent of its current size. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 1G - # thin pool exceeds 700M, it is extended to 1.2G, and when it exceeds - # 840M, it is extended to 1.44G: - # thin_pool_autoextend_percent = 20 -- # -+ # - thin_pool_autoextend_percent = 20 - - # Configuration option activation/vdo_pool_autoextend_threshold. -@@ -1590,13 +1590,13 @@ activation { - # The minimum value is 50 (a smaller value is treated as 50.) - # Also see vdo_pool_autoextend_percent. - # Automatic extension requires dmeventd to be monitoring the LV. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 10G - # VDO pool exceeds 7G, it is extended to 12G, and when it exceeds - # 8.4G, it is extended to 14.4G: - # vdo_pool_autoextend_threshold = 70 -- # -+ # - # This configuration option has an automatic default value. - # vdo_pool_autoextend_threshold = 100 - -@@ -1604,7 +1604,7 @@ activation { - # Auto-extending a VDO pool adds this percent extra space. - # The amount of additional space added to a VDO pool is this - # percent of its current size. -- # -+ # - # Example - # Using 70% autoextend threshold and 20% autoextend size, when a 10G - # VDO pool exceeds 7G, it is extended to 12G, and when it exceeds -@@ -1623,10 +1623,10 @@ activation { - # pages corresponding to lines that match are not pinned. On some - # systems, locale-archive was found to make up over 80% of the memory - # used by the process. -- # -+ # - # Example - # mlock_filter = [ "locale/locale-archive", "gconv/gconv-modules.cache" ] -- # -+ # - # This configuration option is advanced. - # This configuration option does not have a default value defined. - -@@ -1667,7 +1667,7 @@ activation { - # Configuration option activation/activation_mode. - # How LVs with missing devices are activated. - # The --activationmode option overrides this setting. -- # -+ # - # Accepted values: - # complete - # Only allow activation of an LV if all of the Physical Volumes it -@@ -1682,7 +1682,7 @@ activation { - # could cause data loss with a portion of the LV inaccessible. - # This setting should not normally be used, but may sometimes - # assist with data recovery. -- # -+ # - activation_mode = "degraded" - - # Configuration option activation/lock_start_list. -@@ -1730,7 +1730,7 @@ activation { - # Configuration option metadata/pvmetadatacopies. - # Number of copies of metadata to store on each PV. - # The --pvmetadatacopies option overrides this setting. -- # -+ # - # Accepted values: - # 2 - # Two copies of the VG metadata are stored on the PV, one at the -@@ -1740,7 +1740,7 @@ activation { - # 0 - # No copies of VG metadata are stored on the PV. This may be - # useful for VGs containing large numbers of PVs. -- # -+ # - # This configuration option is advanced. - # This configuration option has an automatic default value. - # pvmetadatacopies = 1 -@@ -1890,7 +1890,7 @@ activation { - # sequences are copied verbatim. Each special character sequence is - # introduced by the '%' character and such sequence is then - # substituted with a value as described below. -- # -+ # - # Accepted values: - # %a - # The abbreviated name of the day of the week according to the -@@ -2013,7 +2013,7 @@ activation { - # The timezone name or abbreviation. - # %% - # A literal '%' character. -- # -+ # - # This configuration option has an automatic default value. - # time_format = "%Y-%m-%d %T %z" - -@@ -2282,12 +2282,12 @@ dmeventd { - # applied to the local machine as a 'host tag'. If this subsection is - # empty (has no host_list), then the subsection name is always applied - # as a 'host tag'. -- # -+ # - # Example - # The host tag foo is given to all hosts, and the host tag - # bar is given to the hosts named machine1 and machine2. - # tags { foo { } bar { host_list = [ "machine1", "machine2" ] } } -- # -+ # - # This configuration section has variable name. - # This configuration section has an automatic default value. - # tag { -diff --git a/conf/lvmlocal.conf.in b/conf/lvmlocal.conf.in -index 04414bf..12214ea 100644 ---- a/conf/lvmlocal.conf.in -+++ b/conf/lvmlocal.conf.in -@@ -28,13 +28,13 @@ local { - # main configuration file, e.g. lvm.conf. When used, it must be set to - # a unique value among all hosts sharing access to the storage, - # e.g. a host name. -- # -+ # - # Example - # Set no system ID: - # system_id = "" - # Set the system_id to a specific name: - # system_id = "host1" -- # -+ # - # This configuration option has an automatic default value. - # system_id = "" - -diff --git a/lib/config/config.c b/lib/config/config.c -index a25b7db..f9ca566 100644 ---- a/lib/config/config.c -+++ b/lib/config/config.c -@@ -1738,7 +1738,7 @@ static int _out_prefix_fn(const struct dm_config_node *cn, const char *line, voi - continue; - commentline[0] = '\0'; - } -- fprintf(out->fp, "%s# %s\n", line, commentline); -+ fprintf(out->fp, "%s#%s%s\n", line, commentline[0] ? " " : "", commentline); - /* withsummary prints only the first comment line. */ - if (!out->tree_spec->withcomments) - break; diff --git a/lvm2-2_03_12-dev_get_primary_dev-fix-invalid-path-check.patch b/lvm2-2_03_12-dev_get_primary_dev-fix-invalid-path-check.patch deleted file mode 100644 index add3525..0000000 --- a/lvm2-2_03_12-dev_get_primary_dev-fix-invalid-path-check.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b3719266bd5e3a9e6737d6bda60e543121ddf343 Mon Sep 17 00:00:00 2001 -From: David Teigland -Date: Tue, 9 Feb 2021 09:47:08 -0600 -Subject: [PATCH] dev_get_primary_dev: fix invalid path check - -Fix commit bee9f4efdd81 "filter-mpath: work with nvme devices" -which removed setting the path for readlink. - -(cherry picked from commit f74f94c2ddb1d33d75d325c959344a566a621fd5) - -Conflicts: - lib/device/dev-type.c ---- - lib/device/dev-type.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c -index 379afa8..1342e97 100644 ---- a/lib/device/dev-type.c -+++ b/lib/device/dev-type.c -@@ -434,7 +434,7 @@ static int _has_sys_partition(struct device *dev) - int minor = (int) MINOR(dev->dev); - - /* check if dev is a partition */ -- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition", -+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/partition", - dm_sysfs_dir(), major, minor) < 0) { - log_error("dm_snprintf partition failed"); - return 0; -@@ -660,8 +660,13 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result) - * - basename ../../block/md0/md0 = md0 - * Parent's 'dev' sysfs attribute = /sys/block/md0/dev - */ -- if ((size = readlink(dirname(path), temp_path, sizeof(temp_path) - 1)) < 0) { -- log_sys_error("readlink", path); -+ if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", -+ dm_sysfs_dir(), major, minor) < 0) { -+ log_warn("WARNING: %s: major:minor sysfs path is too long.", dev_name(dev)); -+ return 0; -+ } -+ if ((size = readlink(path, temp_path, sizeof(temp_path) - 1)) < 0) { -+ log_warn("WARNING: Readlink of %s failed.", path); - goto out; - } - --- -1.8.3.1 - diff --git a/lvm2-2_03_12-devs-remove-invalid-path-name-aliases.patch b/lvm2-2_03_12-devs-remove-invalid-path-name-aliases.patch deleted file mode 100644 index 0f00653..0000000 --- a/lvm2-2_03_12-devs-remove-invalid-path-name-aliases.patch +++ /dev/null @@ -1,255 +0,0 @@ - lib/device/dev-cache.c | 161 ++++++++++++++++++++++++++++++++++++---------- - test/shell/dev-aliases.sh | 53 +++++++++++++++ - 2 files changed, 179 insertions(+), 35 deletions(-) - create mode 100644 test/shell/dev-aliases.sh - -diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c -index d5f18ff..8082efa 100644 ---- a/lib/device/dev-cache.c -+++ b/lib/device/dev-cache.c -@@ -1428,60 +1428,151 @@ struct device *dev_hash_get(const char *name) - return (struct device *) dm_hash_lookup(_cache.names, name); - } - -+static void _remove_alias(struct device *dev, const char *name) -+{ -+ struct dm_str_list *strl; -+ -+ dm_list_iterate_items(strl, &dev->aliases) { -+ if (!strcmp(strl->str, name)) { -+ dm_list_del(&strl->list); -+ return; -+ } -+ } -+} -+ -+/* -+ * Check that paths for this dev still refer to the same dev_t. This is known -+ * to drop invalid paths in the case where lvm deactivates an LV, which causes -+ * that LV path to go away, but that LV path is not removed from dev-cache (it -+ * probably should be). Later a new path to a different LV is added to -+ * dev-cache, where the new LV has the same major:minor as the previously -+ * deactivated LV. The new LV will find the existing struct dev, and that -+ * struct dev will have dev->aliases entries that refer to the name of the old -+ * deactivated LV. Those old paths are all invalid and are dropped here. -+ */ -+ -+static void _verify_aliases(struct device *dev, const char *newname) -+{ -+ struct dm_str_list *strl, *strl2; -+ struct stat st; -+ -+ dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { -+ /* newname was just stat'd and added by caller */ -+ if (newname && !strcmp(strl->str, newname)) -+ continue; -+ -+ if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) { -+ log_debug("Drop invalid path %s for %d:%d (new path %s).", -+ strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: ""); -+ dm_hash_remove(_cache.names, strl->str); -+ dm_list_del(&strl->list); -+ } -+ } -+} -+ - struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) - { -- struct stat buf; -- struct device *d = (struct device *) dm_hash_lookup(_cache.names, name); -- int info_available = 0; -- int ret = 1; -+ struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name); -+ struct stat st; -+ int ret; - -- if (d && (d->flags & DEV_REGULAR)) -- return d; -+ /* -+ * DEV_REGULAR means that is "dev" is actually a file, not a device. -+ * FIXME: I don't think dev-cache is used for files any more and this -+ * can be dropped? -+ */ -+ if (dev && (dev->flags & DEV_REGULAR)) -+ return dev; -+ -+ /* -+ * The requested path is invalid, remove any dev-cache -+ * info for it. -+ */ -+ if (stat(name, &st)) { -+ if (dev) { -+ log_print("Device path %s is invalid for %d:%d %s.", -+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); - -- /* If the entry's wrong, remove it */ -- if (stat(name, &buf) < 0) { -- if (d) - dm_hash_remove(_cache.names, name); -- log_sys_very_verbose("stat", name); -- d = NULL; -- } else -- info_available = 1; - -- if (d && (buf.st_rdev != d->dev)) { -- dm_hash_remove(_cache.names, name); -- d = NULL; -- } -+ _remove_alias(dev, name); - -- if (!d) { -- _insert(name, info_available ? &buf : NULL, 0, obtain_device_list_from_udev()); -- d = (struct device *) dm_hash_lookup(_cache.names, name); -- if (!d) { -- log_debug_devs("Device name not found in dev_cache repeat dev_cache_scan for %s", name); -- dev_cache_scan(); -- d = (struct device *) dm_hash_lookup(_cache.names, name); -+ /* Remove any other names in dev->aliases that are incorrect. */ -+ _verify_aliases(dev, NULL); - } -+ return NULL; - } - -- if (!d) -+ if (!S_ISBLK(st.st_mode)) { -+ log_debug("Not a block device %s.", name); - return NULL; -+ } - -- if (d && (d->flags & DEV_REGULAR)) -- return d; -+ /* -+ * dev-cache has incorrect info for the requested path. -+ * Remove incorrect info and then add new dev-cache entry. -+ */ -+ if (dev && (st.st_rdev != dev->dev)) { -+ log_print("Device path %s does not match %d:%d %s.", -+ name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); -+ -+ dm_hash_remove(_cache.names, name); -+ -+ _remove_alias(dev, name); -+ -+ /* Remove any other names in dev->aliases that are incorrect. */ -+ _verify_aliases(dev, NULL); -+ -+ /* Add new dev-cache entry next. */ -+ dev = NULL; -+ } -+ -+ /* -+ * Either add a new struct dev for st_rdev and name, -+ * or add name as a new alias for an existing struct dev -+ * for st_rdev. -+ */ -+ if (!dev) { -+ _insert_dev(name, st.st_rdev); - -- if (f && !(d->flags & DEV_REGULAR)) { -- ret = f->passes_filter(cmd, f, d, NULL); -+ /* Get the struct dev that was just added. */ -+ dev = (struct device *) dm_hash_lookup(_cache.names, name); - -- if (ret == -EAGAIN) { -- log_debug_devs("get device by name defer filter %s", dev_name(d)); -- d->flags |= DEV_FILTER_AFTER_SCAN; -- ret = 1; -+ if (!dev) { -+ log_error("Failed to get device %s", name); -+ return NULL; - } -+ -+ _verify_aliases(dev, name); - } - -- if (f && !(d->flags & DEV_REGULAR) && !ret) -+ /* -+ * The caller passed a filter if they only want the dev if it -+ * passes filters. -+ */ -+ -+ if (!f) -+ return dev; -+ -+ ret = f->passes_filter(cmd, f, dev, NULL); -+ -+ /* -+ * This might happen if this function is called before -+ * filters can do i/o. I don't think this will happen -+ * any longer and this EAGAIN case can be removed. -+ */ -+ if (ret == -EAGAIN) { -+ log_debug_devs("dev_cache_get filter deferred %s", dev_name(dev)); -+ dev->flags |= DEV_FILTER_AFTER_SCAN; -+ ret = 1; -+ } -+ -+ if (!ret) { -+ log_debug_devs("dev_cache_get filter excludes %s", dev_name(dev)); - return NULL; -+ } - -- return d; -+ return dev; - } - - static struct device *_dev_cache_seek_devt(dev_t dev) -diff --git a/test/shell/dev-aliases.sh b/test/shell/dev-aliases.sh -new file mode 100644 -index 0000000..c97cd5d ---- /dev/null -+++ b/test/shell/dev-aliases.sh -@@ -0,0 +1,53 @@ -+#!/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_LVMPOLLD=1 -+ -+. lib/inittest -+ -+aux prepare_devs 3 -+ -+vgcreate $vg $dev1 $dev2 $dev3 -+ -+# -+# This lvconvert command will deactivate LV1, then internally create a new -+# lv, lvol0, as a poolmetadataspare, then activate lvol0 to zero it. -+# lvol0 will get the same major:minor that LV1 had. When the code gets -+# the struct dev for lvol0, the new path to lvol0 is added to the -+# dev-cache with it's major:minor. That major:minor already exists in -+# dev-cache and has the stale LV1 as an alias. So the path to lvol0 is -+# added as an alias to the existing struct dev (with the correct -+# major:minor), but that struct dev has the stale LV1 path on its aliases -+# list. The code will now validate all the aliases before returning the -+# dev for lvol0, and will find that the LV1 path is stale and remove it -+# from the aliases. That will prevent the stale path from being used for -+# the dev in place of the new path. -+# -+# The preferred_name is set to /dev/mapper so that if the stale path still -+# exists, that stale path would be used as the name for the dev, and the -+# wiping code would fail to open that stale name. -+# -+ -+lvcreate -n $lv1 -L32M $vg $dev1 -+lvcreate -n $lv2 -L16M $vg $dev2 -+lvconvert -y --type cache-pool --poolmetadata $lv2 --cachemode writeback $vg/$lv1 --config='devices { preferred_names=["/dev/mapper/"] }' -+lvremove -y $vg/$lv1 -+ -+lvcreate -n $lv1 -L32M $vg $dev1 -+lvcreate -n $lv2 -L16M $vg $dev2 -+lvconvert -y --type cache-pool --poolmetadata $lv2 $vg/$lv1 -+lvremove -y $vg/$lv1 -+ -+# TODO: add more validation of dev aliases being specified as command -+# args in combination with various preferred_names settings. -+ -+vgremove -ff $vg diff --git a/lvm2-2_03_12-filter-mpath-work-with-nvme-devices.patch b/lvm2-2_03_12-filter-mpath-work-with-nvme-devices.patch deleted file mode 100644 index 3778134..0000000 --- a/lvm2-2_03_12-filter-mpath-work-with-nvme-devices.patch +++ /dev/null @@ -1,494 +0,0 @@ - lib/device/dev-type.c | 81 +++++++++++++++++++---- - lib/device/dev-type.h | 2 + - lib/device/device.h | 1 + - lib/filters/filter-mpath.c | 156 ++++++++++++++++++++++++++++++--------------- - 4 files changed, 177 insertions(+), 63 deletions(-) - -diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c -index 896821d..379afa8 100644 ---- a/lib/device/dev-type.c -+++ b/lib/device/dev-type.c -@@ -21,6 +21,7 @@ - #include "lib/metadata/metadata.h" - #include "lib/device/bcache.h" - #include "lib/label/label.h" -+#include "lib/commands/toolcontext.h" - - #ifdef BLKID_WIPING_SUPPORT - #include -@@ -67,6 +68,31 @@ int dev_is_pmem(struct device *dev) - return is_pmem ? 1 : 0; - } - -+/* -+ * An nvme device has major number 259 (BLKEXT), minor number , -+ * and reading /sys/dev/block/259:/device/dev shows a character -+ * device cmajor:cminor where cmajor matches the major number of the -+ * nvme character device entry in /proc/devices. Checking all of that -+ * is excessive and unnecessary compared to just comparing /dev/name*. -+ */ -+ -+int dev_is_nvme(struct dev_types *dt, struct device *dev) -+{ -+ struct dm_str_list *strl; -+ -+ if (dev->flags & DEV_IS_NVME) -+ return 1; -+ -+ dm_list_iterate_items(strl, &dev->aliases) { -+ if (!strncmp(strl->str, "/dev/nvme", 9)) { -+ log_debug("Found nvme device %s", dev_name(dev)); -+ dev->flags |= DEV_IS_NVME; -+ return 1; -+ } -+ } -+ return 0; -+} -+ - int dev_is_lv(struct device *dev) - { - FILE *fp; -@@ -302,6 +328,9 @@ int dev_subsystem_part_major(struct dev_types *dt, struct device *dev) - - const char *dev_subsystem_name(struct dev_types *dt, struct device *dev) - { -+ if (dev->flags & DEV_IS_NVME) -+ return "NVME"; -+ - if (MAJOR(dev->dev) == dt->device_mapper_major) - return "DM"; - -@@ -348,7 +377,6 @@ int major_is_scsi_device(struct dev_types *dt, int major) - return (dt->dev_type_array[major].flags & PARTITION_SCSI_DEVICE) ? 1 : 0; - } - -- - static int _loop_is_with_partscan(struct device *dev) - { - FILE *fp; -@@ -398,6 +426,28 @@ struct partition { - uint32_t nr_sects; - } __attribute__((packed)); - -+static int _has_sys_partition(struct device *dev) -+{ -+ char path[PATH_MAX]; -+ struct stat info; -+ int major = (int) MAJOR(dev->dev); -+ int minor = (int) MINOR(dev->dev); -+ -+ /* check if dev is a partition */ -+ if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition", -+ dm_sysfs_dir(), major, minor) < 0) { -+ log_error("dm_snprintf partition failed"); -+ return 0; -+ } -+ -+ if (stat(path, &info) == -1) { -+ if (errno != ENOENT) -+ log_sys_error("stat", path); -+ return 0; -+ } -+ return 1; -+} -+ - static int _is_partitionable(struct dev_types *dt, struct device *dev) - { - int parts = major_max_partitions(dt, MAJOR(dev->dev)); -@@ -414,6 +464,13 @@ static int _is_partitionable(struct dev_types *dt, struct device *dev) - _loop_is_with_partscan(dev)) - return 1; - -+ if (dev_is_nvme(dt, dev)) { -+ /* If this dev is already a partition then it's not partitionable. */ -+ if (_has_sys_partition(dev)) -+ return 0; -+ return 1; -+ } -+ - if ((parts <= 1) || (MINOR(dev->dev) % parts)) - return 0; - -@@ -557,11 +614,18 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result) - char path[PATH_MAX]; - char temp_path[PATH_MAX]; - char buffer[64]; -- struct stat info; - FILE *fp = NULL; - int parts, residue, size, ret = 0; - - /* -+ * /dev/nvme devs don't use the major:minor numbering like -+ * block dev types that have their own major number, so -+ * the calculation based on minor number doesn't work. -+ */ -+ if (dev_is_nvme(dt, dev)) -+ goto sys_partition; -+ -+ /* - * Try to get the primary dev out of the - * list of known device types first. - */ -@@ -576,23 +640,14 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result) - goto out; - } - -+ sys_partition: - /* - * If we can't get the primary dev out of the list of known device - * types, try to look at sysfs directly then. This is more complex - * way and it also requires certain sysfs layout to be present - * which might not be there in old kernels! - */ -- -- /* check if dev is a partition */ -- if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition", -- sysfs_dir, major, minor) < 0) { -- log_error("dm_snprintf partition failed"); -- goto out; -- } -- -- if (stat(path, &info) == -1) { -- if (errno != ENOENT) -- log_sys_error("stat", path); -+ if (!_has_sys_partition(dev)) { - *result = dev->dev; - ret = 1; - goto out; /* dev is not a partition! */ -diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h -index fdf7791..8b94b79 100644 ---- a/lib/device/dev-type.h -+++ b/lib/device/dev-type.h -@@ -95,6 +95,8 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev); - - int dev_is_pmem(struct device *dev); - -+int dev_is_nvme(struct dev_types *dt, struct device *dev); -+ - int dev_is_lv(struct device *dev); - - int get_fs_block_size(struct device *dev, uint32_t *fs_block_size); -diff --git a/lib/device/device.h b/lib/device/device.h -index a58bff8..816db31 100644 ---- a/lib/device/device.h -+++ b/lib/device/device.h -@@ -38,6 +38,7 @@ - #define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */ - #define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */ - #define DEV_UDEV_INFO_MISSING 0x00040000 /* we have no udev info for this device */ -+#define DEV_IS_NVME 0x00080000 /* set if dev is nvme */ - - /* - * Support for external device info. -diff --git a/lib/filters/filter-mpath.c b/lib/filters/filter-mpath.c -index 85d1625..40e7df6 100644 ---- a/lib/filters/filter-mpath.c -+++ b/lib/filters/filter-mpath.c -@@ -16,6 +16,7 @@ - #include "lib/misc/lib.h" - #include "lib/filters/filter.h" - #include "lib/activate/activate.h" -+#include "lib/commands/toolcontext.h" - #ifdef UDEV_SYNC_SUPPORT - #include - #include "lib/device/dev-ext-udev-constants.h" -@@ -27,7 +28,6 @@ - - #define MPATH_PREFIX "mpath-" - -- - struct mpath_priv { - struct dm_pool *mem; - struct dev_filter f; -@@ -35,6 +35,9 @@ struct mpath_priv { - struct dm_hash_table *hash; - }; - -+/* -+ * given "/dev/foo" return "foo" -+ */ - static const char *_get_sysfs_name(struct device *dev) - { - const char *name; -@@ -53,6 +56,11 @@ static const char *_get_sysfs_name(struct device *dev) - return name; - } - -+/* -+ * given major:minor -+ * readlink translates /sys/dev/block/major:minor to /sys/.../foo -+ * from /sys/.../foo return "foo" -+ */ - static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno, - char *buf, size_t buf_size) - { -@@ -102,27 +110,28 @@ static int _get_sysfs_string(const char *path, char *buffer, int max_size) - return r; - } - --static int _get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor) -+static int _get_sysfs_dm_mpath(struct dev_types *dt, const char *sysfs_dir, const char *holder_name) - { -- char path[PATH_MAX], buffer[64]; -+ char path[PATH_MAX]; -+ char buffer[128]; - -- if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev", sysfs_dir, kname) < 0) { -+ if (dm_snprintf(path, sizeof(path), "%sblock/%s/dm/uuid", sysfs_dir, holder_name) < 0) { - log_error("Sysfs path string is too long."); - return 0; - } - -+ buffer[0] = '\0'; -+ - if (!_get_sysfs_string(path, buffer, sizeof(buffer))) - return_0; - -- if (sscanf(buffer, "%d:%d", major, minor) != 2) { -- log_error("Failed to parse major minor from %s", buffer); -- return 0; -- } -+ if (!strncmp(buffer, MPATH_PREFIX, 6)) -+ return 1; - -- return 1; -+ return 0; - } - --static int _get_parent_mpath(const char *dir, char *name, int max_size) -+static int _get_holder_name(const char *dir, char *name, int max_size) - { - struct dirent *d; - DIR *dr; -@@ -155,7 +164,7 @@ static int _get_parent_mpath(const char *dir, char *name, int max_size) - } - - #ifdef UDEV_SYNC_SUPPORT --static int _udev_dev_is_mpath(struct device *dev) -+static int _udev_dev_is_mpath_component(struct device *dev) - { - const char *value; - struct dev_ext *ext; -@@ -174,95 +183,148 @@ static int _udev_dev_is_mpath(struct device *dev) - return 0; - } - #else --static int _udev_dev_is_mpath(struct device *dev) -+static int _udev_dev_is_mpath_component(struct device *dev) - { - return 0; - } - #endif - --static int _native_dev_is_mpath(struct dev_filter *f, struct device *dev) -+static int _native_dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev) - { - struct mpath_priv *mp = (struct mpath_priv *) f->private; - struct dev_types *dt = mp->dt; -- const char *part_name, *name; -- struct stat info; -- char path[PATH_MAX], parent_name[PATH_MAX]; -+ const char *part_name; -+ const char *name; /* e.g. "sda" for "/dev/sda" */ -+ char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */ -+ char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */ -+ char dm_dev_path[PATH_MAX]; /* e.g. "/dev/dm-1" */ -+ char holder_name[128] = { 0 }; /* e.g. "dm-1" */ - const char *sysfs_dir = dm_sysfs_dir(); -- int major = MAJOR(dev->dev); -- int minor = MINOR(dev->dev); -+ int dev_major = MAJOR(dev->dev); -+ int dev_minor = MINOR(dev->dev); -+ int dm_dev_major; -+ int dm_dev_minor; -+ struct stat info; - dev_t primary_dev; - long look; - -- /* Limit this filter only to SCSI devices */ -- if (!major_is_scsi_device(dt, MAJOR(dev->dev))) -+ /* Limit this filter to SCSI or NVME devices */ -+ if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev)) - return 0; - - switch (dev_get_primary_dev(dt, dev, &primary_dev)) { -+ - case 2: /* The dev is partition. */ - part_name = dev_name(dev); /* name of original dev for log_debug msg */ -- if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, parent_name, sizeof(parent_name)))) -+ -+ /* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */ -+ if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path)))) - return_0; -+ - log_debug_devs("%s: Device is a partition, using primary " - "device %s for mpath component detection", - part_name, name); - break; -+ - case 1: /* The dev is already a primary dev. Just continue with the dev. */ -+ -+ /* gets "foo" for "/dev/foo" */ - if (!(name = _get_sysfs_name(dev))) - return_0; - break; -+ - default: /* 0, error. */ -- log_warn("Failed to get primary device for %d:%d.", major, minor); -+ log_warn("Failed to get primary device for %d:%d.", dev_major, dev_minor); - return 0; - } - -- if (dm_snprintf(path, sizeof(path), "%s/block/%s/holders", sysfs_dir, name) < 0) { -+ if (dm_snprintf(holders_path, sizeof(holders_path), "%sblock/%s/holders", sysfs_dir, name) < 0) { - log_warn("Sysfs path to check mpath is too long."); - return 0; - } - - /* also will filter out partitions */ -- if (stat(path, &info)) -+ if (stat(holders_path, &info)) - return 0; - - if (!S_ISDIR(info.st_mode)) { -- log_warn("Path %s is not a directory.", path); -+ log_warn("Path %s is not a directory.", holders_path); - return 0; - } - -- if (!_get_parent_mpath(path, parent_name, sizeof(parent_name))) -+ /* -+ * If holders dir contains an entry such as "dm-1", then this sets -+ * holder_name to "dm-1". -+ * -+ * If holders dir is empty, return 0 (this is generally where -+ * devs that are not mpath components return.) -+ */ -+ if (!_get_holder_name(holders_path, holder_name, sizeof(holder_name))) - return 0; - -- if (!_get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor)) -- return_0; -+ if (dm_snprintf(dm_dev_path, sizeof(dm_dev_path), "%s/%s", cmd->dev_dir, holder_name) < 0) { -+ log_warn("dm device path to check mpath is too long."); -+ return 0; -+ } - -- if (major != dt->device_mapper_major) -+ /* -+ * stat "/dev/dm-1" which is the holder of the dev we're checking -+ * dm_dev_major:dm_dev_minor come from stat("/dev/dm-1") -+ */ -+ if (stat(dm_dev_path, &info)) { -+ log_debug("filter-mpath %s holder %s stat result %d", -+ dev_name(dev), dm_dev_path, errno); - return 0; -+ } -+ dm_dev_major = (int)MAJOR(info.st_rdev); -+ dm_dev_minor = (int)MINOR(info.st_rdev); -+ -+ if (dm_dev_major != dt->device_mapper_major) { -+ log_debug_devs("filter-mpath %s holder %s %d:%d does not have dm major", -+ dev_name(dev), dm_dev_path, dm_dev_major, dm_dev_minor); -+ return 0; -+ } - -- /* Avoid repeated detection of multipath device and use first checked result */ -- look = (long) dm_hash_lookup_binary(mp->hash, &minor, sizeof(minor)); -+ /* -+ * Save the result of checking that "/dev/dm-1" is an mpath device -+ * to avoid repeating it for each path component. -+ * The minor number of "/dev/dm-1" is added to the hash table with -+ * const value 2 meaning that dm minor 1 (for /dev/dm-1) is a multipath dev -+ * and const value 1 meaning that dm minor 1 is not a multipath dev. -+ */ -+ look = (long) dm_hash_lookup_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor)); - if (look > 0) { -- log_debug_devs("%s(%u:%u): already checked as %sbeing mpath.", -- parent_name, major, minor, (look > 1) ? "" : "not "); -+ log_debug_devs("filter-mpath %s holder %s %u:%u already checked as %sbeing mpath.", -+ dev_name(dev), holder_name, dm_dev_major, dm_dev_minor, (look > 1) ? "" : "not "); - return (look > 1) ? 1 : 0; - } - -- if (lvm_dm_prefix_check(major, minor, MPATH_PREFIX)) { -- (void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)2); -+ /* -+ * Returns 1 if /sys/block//dm/uuid indicates that -+ * is a dm device with dm uuid prefix mpath-. -+ * When true, will be something like "dm-1". -+ * -+ * (Is a hash table worth it to avoid reading one sysfs file?) -+ */ -+ if (_get_sysfs_dm_mpath(dt, sysfs_dir, holder_name)) { -+ log_debug_devs("filter-mpath %s holder %s %u:%u ignore mpath component", -+ dev_name(dev), holder_name, dm_dev_major, dm_dev_minor); -+ (void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)2); - return 1; - } - -- (void) dm_hash_insert_binary(mp->hash, &minor, sizeof(minor), (void*)1); -+ (void) dm_hash_insert_binary(mp->hash, &dm_dev_minor, sizeof(dm_dev_minor), (void*)1); - - return 0; - } - --static int _dev_is_mpath(struct dev_filter *f, struct device *dev) -+static int _dev_is_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev) - { - if (dev->ext.src == DEV_EXT_NONE) -- return _native_dev_is_mpath(f, dev); -+ return _native_dev_is_mpath_component(cmd, f, dev); - - if (dev->ext.src == DEV_EXT_UDEV) -- return _udev_dev_is_mpath(dev); -+ return _udev_dev_is_mpath_component(dev); - - log_error(INTERNAL_ERROR "Missing hook for mpath recognition " - "using external device info source %s", dev_ext_name(dev)); -@@ -272,11 +334,11 @@ static int _dev_is_mpath(struct dev_filter *f, struct device *dev) - - #define MSG_SKIPPING "%s: Skipping mpath component device" - --static int _ignore_mpath(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) -+static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) - { - dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT; - -- if (_dev_is_mpath(f, dev) == 1) { -+ if (_dev_is_mpath_component(cmd, f, dev) == 1) { - if (dev->ext.src == DEV_EXT_NONE) - log_debug_devs(MSG_SKIPPING, dev_name(dev)); - else -@@ -303,8 +365,8 @@ static void _destroy(struct dev_filter *f) - struct dev_filter *mpath_filter_create(struct dev_types *dt) - { - const char *sysfs_dir = dm_sysfs_dir(); -- struct dm_pool *mem; - struct mpath_priv *mp; -+ struct dm_pool *mem; - struct dm_hash_table *hash; - - if (!*sysfs_dir) { -@@ -328,19 +390,13 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt) - goto bad; - } - -- if (!(mp = dm_pool_zalloc(mem, sizeof(*mp)))) { -- log_error("mpath filter allocation failed."); -- goto bad; -- } -- -- mp->f.passes_filter = _ignore_mpath; -+ mp->f.passes_filter = _ignore_mpath_component; - mp->f.destroy = _destroy; - mp->f.use_count = 0; - mp->f.private = mp; - mp->f.name = "mpath"; -- -- mp->mem = mem; - mp->dt = dt; -+ mp->mem = mem; - mp->hash = hash; - - log_debug_devs("mpath filter initialised."); diff --git a/lvm2-2_03_12-integrity-fix-segfault-on-error-path-when-replacing-.patch b/lvm2-2_03_12-integrity-fix-segfault-on-error-path-when-replacing-.patch deleted file mode 100644 index d4ece0d..0000000 --- a/lvm2-2_03_12-integrity-fix-segfault-on-error-path-when-replacing-.patch +++ /dev/null @@ -1,24 +0,0 @@ - lib/metadata/integrity_manip.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c -index 53ab1b3..abf90d8 100644 ---- a/lib/metadata/integrity_manip.c -+++ b/lib/metadata/integrity_manip.c -@@ -773,9 +773,13 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting - bad: - log_error("Failed to add integrity."); - -- for (s = 0; s < revert_meta_lvs; s++) { -- if (!lv_remove(imeta_lvs[s])) -- log_error("New integrity metadata LV may require manual removal."); -+ if (revert_meta_lvs) { -+ for (s = 0; s < DEFAULT_RAID_MAX_IMAGES; s++) { -+ if (!imeta_lvs[s]) -+ continue; -+ if (!lv_remove(imeta_lvs[s])) -+ log_error("New integrity metadata LV may require manual removal."); -+ } - } - - if (!vg_write(vg) || !vg_commit(vg)) diff --git a/lvm2-2_03_12-label_scan-fix-missing-free-of-filtered_devs.patch b/lvm2-2_03_12-label_scan-fix-missing-free-of-filtered_devs.patch deleted file mode 100644 index b5bccfb..0000000 --- a/lvm2-2_03_12-label_scan-fix-missing-free-of-filtered_devs.patch +++ /dev/null @@ -1,19 +0,0 @@ - lib/label/label.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/lib/label/label.c b/lib/label/label.c -index e067a6b..e6dd4a1 100644 ---- a/lib/label/label.c -+++ b/lib/label/label.c -@@ -1243,6 +1243,11 @@ int label_scan(struct cmd_context *cmd) - free(devl); - } - -+ dm_list_iterate_items_safe(devl, devl2, &filtered_devs) { -+ dm_list_del(&devl->list); -+ free(devl); -+ } -+ - /* - * If hints were not available/usable, then we scanned all devs, - * and we now know which are PVs. Save this list of PVs we've diff --git a/lvm2-2_03_12-lvcreate-use-lv_passes_readonly_filter.patch b/lvm2-2_03_12-lvcreate-use-lv_passes_readonly_filter.patch deleted file mode 100644 index bb28cd7..0000000 --- a/lvm2-2_03_12-lvcreate-use-lv_passes_readonly_filter.patch +++ /dev/null @@ -1,66 +0,0 @@ - WHATS_NEW | 4 ++++ - lib/activate/activate.c | 5 +++++ - lib/activate/activate.h | 2 ++ - lib/metadata/lv_manip.c | 6 ++++++ - 4 files changed, 17 insertions(+) - -diff --git a/WHATS_NEW b/WHATS_NEW -index 3953c7e..c8f869c 100644 ---- a/WHATS_NEW -+++ b/WHATS_NEW -@@ -1,5 +1,9 @@ - Version 2.03.12 - - =================================== -+ Check if lvcreate passes read_only_volume_list with tags and skips zeroing. -+ Limit pool metadata spare to 16GiB. -+ Improves conversion and allocation of pool metadata. -+ Support thin pool metadata 15.88GiB, adds 64MiB, thin_pool_crop_metadata=0. - Fix problem with wiping of converted LVs. - Fix memleak in scanning (2.03.11). - Fix corner case allocation for thin-pools. -diff --git a/lib/activate/activate.c b/lib/activate/activate.c -index 7ed6441..de866fb 100644 ---- a/lib/activate/activate.c -+++ b/lib/activate/activate.c -@@ -466,6 +466,11 @@ static int _passes_readonly_filter(struct cmd_context *cmd, - return _lv_passes_volumes_filter(cmd, lv, cn, activation_read_only_volume_list_CFG); - } - -+int lv_passes_readonly_filter(const struct logical_volume *lv) -+{ -+ return _passes_readonly_filter(lv->vg->cmd, lv); -+} -+ - int library_version(char *version, size_t size) - { - if (!activation()) -diff --git a/lib/activate/activate.h b/lib/activate/activate.h -index 3f4d128..53c8631 100644 ---- a/lib/activate/activate.h -+++ b/lib/activate/activate.h -@@ -208,6 +208,8 @@ int lvs_in_vg_opened(const struct volume_group *vg); - - int lv_is_active(const struct logical_volume *lv); - -+int lv_passes_readonly_filter(const struct logical_volume *lv); -+ - /* Check is any component LV is active */ - const struct logical_volume *lv_component_is_active(const struct logical_volume *lv); - const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv); -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index 445c4ad..5ff64a3 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -7976,6 +7976,12 @@ static int _should_wipe_lv(struct lvcreate_params *lp, - first_seg(first_seg(lv)->pool_lv)->zero_new_blocks)) - return 0; - -+ if (warn && (lv_passes_readonly_filter(lv))) { -+ log_warn("WARNING: Read-only activated logical volume %s not zeroed.", -+ display_lvname(lv)); -+ return 0; -+ } -+ - /* Cannot zero read-only volume */ - if ((lv->status & LVM_WRITE) && - (lp->zero || lp->wipe_signatures)) diff --git a/lvm2-2_03_12-lvm-Fix-editline-compilation.patch b/lvm2-2_03_12-lvm-Fix-editline-compilation.patch deleted file mode 100644 index d643f76..0000000 --- a/lvm2-2_03_12-lvm-Fix-editline-compilation.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 51d4b6069e5767467b4264b7182943a0c73b4c92 Mon Sep 17 00:00:00 2001 -From: Marian Csontos -Date: Mon, 22 Mar 2021 10:50:42 +0100 -Subject: [PATCH] lvm: Fix editline compilation - ---- - configure | 2 +- - configure.ac | 4 ++-- - tools/lvm.c | 1 - - 3 files changed, 3 insertions(+), 4 deletions(-) - -diff --git a/configure b/configure -index 4c38cbe..0be9f13 100755 ---- a/configure -+++ b/configure -@@ -13404,7 +13404,7 @@ $as_echo_n "checking whether to enable readline... " >&6; } - $as_echo "$READLINE" >&6; } - - if test "$EDITLINE" = yes; then -- for ac_header in editline/readline.h editline/history.h -+ for ac_header in editline/readline.h - do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` - ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -diff --git a/configure.ac b/configure.ac -index ee21b87..b92be0d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1420,7 +1420,7 @@ if test "$EDITLINE" == yes; then - PKG_CHECK_MODULES([EDITLINE], [libedit], [ - AC_DEFINE([EDITLINE_SUPPORT], 1, - [Define to 1 to include the LVM editline shell.])], AC_MSG_ERROR( --[libedit could not be found which is required for the --enable-readline option.]) -+[libedit could not be found which is required for the --enable-editline option.]) - ) - fi - -@@ -1557,7 +1557,7 @@ AC_MSG_CHECKING(whether to enable readline) - AC_MSG_RESULT($READLINE) - - if test "$EDITLINE" = yes; then -- AC_CHECK_HEADERS(editline/readline.h editline/history.h,,hard_bailout) -+ AC_CHECK_HEADERS(editline/readline.h,,hard_bailout) - fi - AC_MSG_CHECKING(whether to enable editline) - AC_MSG_RESULT($EDITLINE) -diff --git a/tools/lvm.c b/tools/lvm.c -index 79b1210..cc67e92 100644 ---- a/tools/lvm.c -+++ b/tools/lvm.c -@@ -33,7 +33,6 @@ int main(int argc, char **argv) - # endif - # elif defined(EDITLINE_SUPPORT) - # include --# include - # endif - - static struct cmdline_context *_cmdline; --- -1.8.3.1 - diff --git a/lvm2-2_03_12-lvmlockd-sscanf-buffer-size-warnings.patch b/lvm2-2_03_12-lvmlockd-sscanf-buffer-size-warnings.patch deleted file mode 100644 index 9bc2f48..0000000 --- a/lvm2-2_03_12-lvmlockd-sscanf-buffer-size-warnings.patch +++ /dev/null @@ -1,29 +0,0 @@ - daemons/lvmlockd/lvmlockd-core.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c -index fea8ee6..c4abf66 100644 ---- a/daemons/lvmlockd/lvmlockd-core.c -+++ b/daemons/lvmlockd/lvmlockd-core.c -@@ -896,8 +896,9 @@ static int read_adopt_file(struct list_head *vg_lockd) - goto fail; - - memset(vg_uuid, 0, sizeof(vg_uuid)); -+ memset(lm_type_str, 0, sizeof(lm_type_str)); - -- if (sscanf(adopt_line, "VG: %63s %64s %16s %64s", -+ if (sscanf(adopt_line, "VG: %63s %64s %15s %64s", - vg_uuid, ls->vg_name, lm_type_str, ls->vg_args) != 4) { - goto fail; - } -@@ -916,8 +917,9 @@ static int read_adopt_file(struct list_head *vg_lockd) - r->type = LD_RT_LV; - - memset(vg_uuid, 0, sizeof(vg_uuid)); -+ memset(mode, 0, sizeof(mode)); - -- if (sscanf(adopt_line, "LV: %64s %64s %s %8s %u", -+ if (sscanf(adopt_line, "LV: %64s %64s %s %7s %u", - vg_uuid, r->name, r->lv_args, mode, &r->version) != 5) { - goto fail; - } diff --git a/lvm2-2_03_12-make-generate.patch b/lvm2-2_03_12-make-generate.patch deleted file mode 100644 index 2f4f682..0000000 --- a/lvm2-2_03_12-make-generate.patch +++ /dev/null @@ -1,18 +0,0 @@ - man/lvconvert.8_pregen | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen -index a47ccac..170eec8 100644 ---- a/man/lvconvert.8_pregen -+++ b/man/lvconvert.8_pregen -@@ -772,6 +772,10 @@ Add a cache to an LV, using a specified cache device. - .br - .RS 4 - .ad l -+[ \fB-c\fP|\fB--chunksize\fP \fISize\fP[k|UNIT] ] -+.ad b -+.br -+.ad l - [ \fB--cachesize\fP \fISize\fP[m|UNIT] ] - .ad b - .br diff --git a/lvm2-2_03_12-man-update-lvmthin.patch b/lvm2-2_03_12-man-update-lvmthin.patch deleted file mode 100644 index f61660f..0000000 --- a/lvm2-2_03_12-man-update-lvmthin.patch +++ /dev/null @@ -1,86 +0,0 @@ - man/lvmthin.7_main | 37 +++++++++++++++++++++++++------------ - 1 file changed, 25 insertions(+), 12 deletions(-) - -diff --git a/man/lvmthin.7_main b/man/lvmthin.7_main -index ce23431..e6f1d63 100644 ---- a/man/lvmthin.7_main -+++ b/man/lvmthin.7_main -@@ -394,7 +394,7 @@ the pmspare LV. - \& - - If thin pool metadata is damaged, it may be repairable. --Checking and repairing thin pool metadata is analagous to -+Checking and repairing thin pool metadata is analogous to - running fsck/repair on a file system. - - When a thin pool LV is activated, lvm runs the thin_check command -@@ -437,14 +437,24 @@ copy to the VG's pmspare LV. - If step 1 is successful, the thin pool metadata LV is replaced - with the pmspare LV containing the corrected metadata. - The previous thin pool metadata LV, containing the damaged metadata, --becomes visible with the new name ThinPoolLV_tmetaN (where N is 0,1,...). -- --If the repair works, the thin pool LV and its thin LVs can be activated, --and the LV containing the damaged thin pool metadata can be removed. --It may be useful to move the new metadata LV (previously pmspare) to a --better PV. -- --If the repair does not work, the thin pool LV and its thin LVs are lost. -+becomes visible with the new name ThinPoolLV_metaN (where N is 0,1,...). -+ -+If the repair works, the thin pool LV and its thin LVs can be activated. -+User should manually check if repaired thin pool kernel metadata -+has all data for all lvm2 known LVs by individual activation of -+every thin LV. When all works, user should continue with fsck of -+all filesystems present these such volumes. -+Once the thin pool is considered fully functional user may remove ThinPoolLV_metaN -+(the LV containing the damaged thin pool metadata) for possible -+space reuse. -+For a better performance it may be useful to pvmove the new repaired metadata LV -+(written to previous pmspare volume) to a better PV (i.e. SSD) -+ -+If the repair operation fails, the thin pool LV and its thin LVs -+are not accessible and it may be necessary to restore their content -+from a backup. In such case the content of unmodified original damaged -+ThinPoolLV_metaN volume can be used by your support for more -+advanced recovery methods. - - If metadata is manually restored with thin_repair directly, - the pool metadata LV can be manually swapped with another LV -@@ -452,6 +462,9 @@ containing new metadata: - - .B lvconvert --thinpool VG/ThinPoolLV --poolmetadata VG/NewThinMetaLV - -+Note: Thin pool metadata is compact so even small corruptions -+in them may result in significant portions of mappings to be lost. -+It is recommended to use fast resilient storage for them. - - .SS Activation of thin snapshots - -@@ -549,7 +562,7 @@ Command to extend thin pool data space: - .fi - - Other methods of increasing free data space in a thin pool LV --include removing a thin LV and its related snapsots, or running -+include removing a thin LV and its related snapshots, or running - fstrim on the file system using a thin LV. - - -@@ -689,7 +702,7 @@ with two configuration settings: - .B thin_pool_autoextend_threshold - .br - is a percentage full value that defines when the thin pool LV should be --extended. Setting this to 100 disables automatic extention. The minimum -+extended. Setting this to 100 disables automatic extension. The minimum - value is 50. - - .BR lvm.conf (5) -@@ -716,7 +729,7 @@ the --ignoremonitoring option can be used. With this option, the command - will not ask dmeventd to monitor the thin pool LV. - - .IP \[bu] --Setting thin_pool_autoextend_threshould to 100 disables automatic -+Setting thin_pool_autoextend_threshold to 100 disables automatic - extension of thin pool LVs, even if they are being monitored by dmeventd. - - .P diff --git a/lvm2-2_03_12-pool-limit-pmspare-to-16GiB.patch b/lvm2-2_03_12-pool-limit-pmspare-to-16GiB.patch deleted file mode 100644 index b41b370..0000000 --- a/lvm2-2_03_12-pool-limit-pmspare-to-16GiB.patch +++ /dev/null @@ -1,39 +0,0 @@ - lib/metadata/pool_manip.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c -index b67882e..1975cb4 100644 ---- a/lib/metadata/pool_manip.c -+++ b/lib/metadata/pool_manip.c -@@ -697,6 +697,8 @@ static struct logical_volume *_alloc_pool_metadata_spare(struct volume_group *vg - int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents, - struct dm_list *pvh, int poolmetadataspare) - { -+ /* Max usable size of any spare volume is currently 16GiB rouned to extent size */ -+ const uint64_t MAX_SIZE = (UINT64_C(2 * 16) * 1024 * 1024 + vg->extent_size - 1) / vg->extent_size; - struct logical_volume *lv = vg->pool_metadata_spare_lv; - uint32_t seg_mirrors; - struct lv_segment *seg; -@@ -706,8 +708,11 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents, - /* Find maximal size of metadata LV */ - dm_list_iterate_items(lvl, &vg->lvs) - if (lv_is_pool_metadata(lvl->lv) && -- (lvl->lv->le_count > extents)) -+ (lvl->lv->le_count > extents)) { - extents = lvl->lv->le_count; -+ if (extents >= MAX_SIZE) -+ break; -+ } - - if (!poolmetadataspare) { - /* TODO: Not showing when lvm.conf would define 'n' ? */ -@@ -718,6 +723,9 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents, - return 1; - } - -+ if (extents > MAX_SIZE) -+ extents = MAX_SIZE; -+ - if (!lv) { - if (!_alloc_pool_metadata_spare(vg, extents, pvh)) - return_0; diff --git a/lvm2-2_03_12-pools-fix-removal-of-spare-volume.patch b/lvm2-2_03_12-pools-fix-removal-of-spare-volume.patch deleted file mode 100644 index bec2210..0000000 --- a/lvm2-2_03_12-pools-fix-removal-of-spare-volume.patch +++ /dev/null @@ -1,92 +0,0 @@ - lib/metadata/lv_manip.c | 48 ++++++++++++++++++++++++------------------------ - 1 file changed, 24 insertions(+), 24 deletions(-) - -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index 443d32c..c740ba2 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -1470,6 +1470,8 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete) - struct logical_volume *external_lv = NULL; - int is_raid10 = 0; - uint32_t data_copies = 0; -+ struct lv_list *lvl; -+ int is_last_pool = lv_is_pool(lv); - - if (!dm_list_empty(&lv->segments)) { - seg = first_seg(lv); -@@ -1581,6 +1583,28 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete) - !lv_update_and_reload(external_lv)) - return_0; - -+ /* When removing last pool, automatically drop the spare volume */ -+ if (is_last_pool && lv->vg->pool_metadata_spare_lv) { -+ /* TODO: maybe use a list of pools or a counter to avoid linear search through VG */ -+ dm_list_iterate_items(lvl, &lv->vg->lvs) -+ if (lv_is_thin_type(lvl->lv) || -+ lv_is_cache_type(lvl->lv)) { -+ is_last_pool = 0; -+ break; -+ } -+ -+ if (is_last_pool) { -+ /* This is purely internal LV volume, no question */ -+ if (!deactivate_lv(lv->vg->cmd, lv->vg->pool_metadata_spare_lv)) { -+ log_error("Unable to deactivate spare logical volume %s.", -+ display_lvname(lv->vg->pool_metadata_spare_lv)); -+ return 0; -+ } -+ if (!lv_remove(lv->vg->pool_metadata_spare_lv)) -+ return_0; -+ } -+ } -+ - return 1; - } - -@@ -6433,10 +6457,8 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, - struct logical_volume *lock_lv = lv; - struct lv_segment *cache_seg = NULL; - int ask_discard; -- struct lv_list *lvl; - struct seg_list *sl; - struct lv_segment *seg = first_seg(lv); -- int is_last_pool = lv_is_pool(lv); - - vg = lv->vg; - -@@ -6558,9 +6580,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, - */ - struct logical_volume *cachevol_lv = first_seg(lv)->pool_lv; - -- if (lv_is_cache_pool(cachevol_lv)) -- is_last_pool = 1; -- - if (!archive(vg)) - return_0; - -@@ -6667,25 +6686,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv, - return 0; - } - -- if (is_last_pool && vg->pool_metadata_spare_lv) { -- /* When removed last pool, also remove the spare */ -- dm_list_iterate_items(lvl, &vg->lvs) -- if (lv_is_pool_metadata(lvl->lv)) { -- is_last_pool = 0; -- break; -- } -- if (is_last_pool) { -- /* This is purely internal LV volume, no question */ -- if (!deactivate_lv(cmd, vg->pool_metadata_spare_lv)) { -- log_error("Unable to deactivate spare logical volume %s.", -- display_lvname(vg->pool_metadata_spare_lv)); -- return 0; -- } -- if (!lv_remove(vg->pool_metadata_spare_lv)) -- return_0; -- } -- } -- - /* store it on disks */ - if (!vg_write(vg) || !vg_commit(vg)) - return_0; diff --git a/lvm2-2_03_12-pvck-fix-warning-and-exit-code-for-non-4k-mda1-offse.patch b/lvm2-2_03_12-pvck-fix-warning-and-exit-code-for-non-4k-mda1-offse.patch deleted file mode 100644 index 63020bd..0000000 --- a/lvm2-2_03_12-pvck-fix-warning-and-exit-code-for-non-4k-mda1-offse.patch +++ /dev/null @@ -1,24 +0,0 @@ - tools/pvck.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/tools/pvck.c b/tools/pvck.c -index c36e182..88350de 100644 ---- a/tools/pvck.c -+++ b/tools/pvck.c -@@ -1140,9 +1140,13 @@ static int _dump_label_and_pv_header(struct cmd_context *cmd, uint64_t labelsect - *mda1_offset = xlate64(dlocn->offset); - *mda1_size = xlate64(dlocn->size); - -- if (*mda1_offset != 4096) { -- log_print("CHECK: pv_header.disk_locn[%d].offset expected 4096 # for first mda", di); -- bad++; -+ /* -+ * mda1 offset is page size from machine that created it, -+ * warn if it's not one of the expected page sizes. -+ */ -+ if ((*mda1_offset != 4096) && (*mda1_offset != 8192) && (*mda1_offset != 65536)) { -+ log_print("WARNING: pv_header.disk_locn[%d].offset %llu is unexpected # for first mda", -+ di, (unsigned long long)*mda1_offset); - } - } else { - *mda2_offset = xlate64(dlocn->offset); diff --git a/lvm2-2_03_12-test-check-read_only_volume_list-tagging-works.patch b/lvm2-2_03_12-test-check-read_only_volume_list-tagging-works.patch deleted file mode 100644 index bdcc15b..0000000 --- a/lvm2-2_03_12-test-check-read_only_volume_list-tagging-works.patch +++ /dev/null @@ -1,19 +0,0 @@ - test/shell/tags.sh | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/test/shell/tags.sh b/test/shell/tags.sh -index fd1b332..5b636a8 100644 ---- a/test/shell/tags.sh -+++ b/test/shell/tags.sh -@@ -52,6 +52,11 @@ check lv_field @firstlvtag1 tags "firstlvtag1" - not check lv_field @secondlvtag1 tags "firstlvtag1" - check lv_field $vg1/$lv2 tags "secondlvtag1" - not check lv_field $vg1/$lv1 tags "secondlvtag1" -+ -+# LV is not zeroed when tag matches read only volume list -+lvcreate -l1 $vg1 --addtag "RO" --config "activation/read_only_volume_list = [ \"@RO\" ]" 2>&1 | tee out -+grep "not zeroed" out -+ - vgremove -f $vg1 - - # lvchange with --addtag and --deltag diff --git a/lvm2-2_03_12-tests-check-16G-thin-pool-metadata-size.patch b/lvm2-2_03_12-tests-check-16G-thin-pool-metadata-size.patch deleted file mode 100644 index ae05b76..0000000 --- a/lvm2-2_03_12-tests-check-16G-thin-pool-metadata-size.patch +++ /dev/null @@ -1,98 +0,0 @@ - test/shell/thin-16g.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - create mode 100644 test/shell/thin-16g.sh - -diff --git a/test/shell/thin-16g.sh b/test/shell/thin-16g.sh -new file mode 100644 -index 0000000..ee7e22e ---- /dev/null -+++ b/test/shell/thin-16g.sh -@@ -0,0 +1,88 @@ -+#!/usr/bin/env bash -+ -+# Copyright (C) 2021 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 usability of 16g thin pool metadata LV -+ -+ -+SKIP_WITH_LVMPOLLD=1 -+ -+. lib/inittest -+ -+aux have_thin 1 0 0 || skip -+ -+aux prepare_vg 1 50000 -+ -+lvcreate -T -L10 --poolmetadatasize 16g $vg/pool -+check lv_field $vg/pool_tmeta size "<15.88g" -+lvremove -f $vg -+ -+# Cropped way -+lvcreate -T -L10 --poolmetadatasize 16g --config 'allocation/thin_pool_crop_metadata=1' $vg/pool -+check lv_field $vg/pool_tmeta size "15.81g" -+lvremove -f $vg -+ -+lvcreate -L16G -n meta $vg -+lvcreate -L10 -n pool $vg -+lvconvert --yes --thinpool $vg/pool --poolmetadata meta -+# Uncropped size 33554432 sectors - 16GiB -+dmsetup table ${vg}-pool_tmeta | grep 33554432 -+lvremove -f $vg -+ -+# Uses 20G metadata volume, but crops the size in DM table -+lvcreate -L20G -n meta $vg -+lvcreate -L10 -n pool $vg -+lvconvert --yes --thinpool $vg/pool --poolmetadata meta --config 'allocation/thin_pool_crop_metadata=1' -+check lv_field $vg/lvol0_pmspare size "16.00g" -+# Size should be cropped to 33161216 sectors ~15.81GiB -+dmsetup table ${vg}-pool_tmeta | grep 33161216 -+ -+# Also size remains unchanged with activation has no cropping, -+# but metadata have no CROP_METADATA flag set -+lvchange -an $vg -+lvchange -ay $vg -+# Size still stays cropped to 33161216 sectors ~15.81GiB -+dmsetup table ${vg}-pool_tmeta | grep 33161216 -+lvremove -f $vg -+ -+# Minimal size is 2M -+lvcreate -L1M -n meta $vg -+lvcreate -L10 -n pool $vg -+not lvconvert --yes --thinpool $vg/pool --poolmetadata meta -+lvremove -f $vg -+ -+# Uses 20G metadata volume, but crops the size in DM table -+lvcreate -L1 --poolmetadatasize 10G -T $vg/pool -+lvresize -L+10G $vg/pool_tmeta --config 'allocation/thin_pool_crop_metadata=1' -+check lv_field $vg/lvol0_pmspare size "15.81g" -+# Size should be cropped to 33161216 sectors ~15.81GiB -+dmsetup table ${vg}-pool_tmeta | grep 33161216 -+ -+# Without cropping we can grop to ~15.88GiB -+lvresize -L+10G $vg/pool_tmeta -+check lv_field $vg/lvol0_pmspare size "<15.88g" -+lvremove -f $vg -+ -+# User has already 'bigger' metadata and wants them uncropped -+lvcreate -L16G -n meta $vg -+lvcreate -L10 -n pool $vg -+lvconvert --yes --thinpool $vg/pool --poolmetadata meta --config 'allocation/thin_pool_crop_metadata=1' -+ -+# No change with cropping -+lvresize -l+1 $vg/pool_tmeta --config 'allocation/thin_pool_crop_metadata=1' -+dmsetup table ${vg}-pool_tmeta | grep 33161216 -+ -+# Resizes to 'uncropped' size 16GiB with ANY size -+lvresize -l+1 $vg/pool_tmeta -+dmsetup table ${vg}-pool_tmeta | grep 33554432 -+check lv_field $vg/pool_tmeta size "16.00g" -+ -+vgremove -ff $vg diff --git a/lvm2-2_03_12-tests-check-full-zeroing-of-thin-pool-metadata.patch b/lvm2-2_03_12-tests-check-full-zeroing-of-thin-pool-metadata.patch deleted file mode 100644 index d7edcc7..0000000 --- a/lvm2-2_03_12-tests-check-full-zeroing-of-thin-pool-metadata.patch +++ /dev/null @@ -1,78 +0,0 @@ - test/shell/thin-zero-meta.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 68 insertions(+) - create mode 100644 test/shell/thin-zero-meta.sh - -diff --git a/test/shell/thin-zero-meta.sh b/test/shell/thin-zero-meta.sh -new file mode 100644 -index 0000000..6a15a73 ---- /dev/null -+++ b/test/shell/thin-zero-meta.sh -@@ -0,0 +1,68 @@ -+#!/usr/bin/env bash -+ -+# Copyright (C) 2021 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 how zeroing of thin-pool metadata works -+ -+SKIP_WITH_LVMLOCKD=1 -+SKIP_WITH_LVMPOLLD=1 -+ -+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false} -+ -+. lib/inittest -+ -+# -+# Main -+# -+aux have_thin 1 3 0 || skip -+aux have_cache 1 3 0 || skip -+ -+aux prepare_vg 3 40000 -+ -+# Create mostly-zero devs only front of it has some 'real' back-end -+aux zero_dev "$dev1" "$(( $(get first_extent_sector "$dev1") + 8192 )):" -+aux zero_dev "$dev2" "$(( $(get first_extent_sector "$dev2") + 8192 )):" -+aux zero_dev "$dev3" "$(( $(get first_extent_sector "$dev3") + 8192 )):" -+ -+# Prepare randomly filled 4M LV on dev2 -+lvcreate -L16G -n $lv1 $vg "$dev2" -+dd if=/dev/urandom of="$DM_DEV_DIR/$vg/$lv1" bs=1M count=4 oflag=direct || true -+lvremove -f $vg -+ -+for i in 0 1 -+do -+ aux lvmconf "allocation/zero_metadata = $i" -+ -+ # Lvm2 should allocate metadata on dev2 -+ lvcreate -T -L10G --poolmetadatasize 16G $vg/pool "$dev1" "$dev2" -+ lvchange -an $vg -+ -+ lvs -ao+seg_pe_ranges $vg -+ lvchange -ay $vg/pool_tmeta --yes -+ -+ # Skip past 1.2M which is 'created' by thin-pool initialization -+ hexdump -C -n 200 -s 2000000 "$DM_DEV_DIR/$vg/pool_tmeta" | tee out -+ -+ # When fully zeroed, it should be zero - so almost no output from hexdump -+ case "$i" in -+ 0) test $(wc -l < out) -ge 10 ;; # should not be zeroed -+ 1) test $(wc -l < out) -le 10 ;; # should be zeroed -+ esac -+ -+ lvremove -f $vg/pool -+done -+ -+# Check lvm2 spots error during full zeroing of metadata device -+aux error_dev "$dev2" "$(( $(get first_extent_sector "$dev2") + 32 )):" -+not lvcreate -T -L10G --poolmetadatasize 16G $vg/pool "$dev1" "$dev2" |& tee err -+grep "Failed to initialize logical volume" err -+ -+vgremove -ff $vg diff --git a/lvm2-2_03_12-tests-check-support-for-online-vdo-rename.patch b/lvm2-2_03_12-tests-check-support-for-online-vdo-rename.patch deleted file mode 100644 index 6c5ad63..0000000 --- a/lvm2-2_03_12-tests-check-support-for-online-vdo-rename.patch +++ /dev/null @@ -1,128 +0,0 @@ - test/shell/lvcreate-vdo-cache.sh | 17 +------- - test/shell/lvrename-vdo.sh | 88 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 90 insertions(+), 15 deletions(-) - create mode 100644 test/shell/lvrename-vdo.sh - -diff --git a/test/shell/lvcreate-vdo-cache.sh b/test/shell/lvcreate-vdo-cache.sh -index c31cccc..6cf8437 100644 ---- a/test/shell/lvcreate-vdo-cache.sh -+++ b/test/shell/lvcreate-vdo-cache.sh -@@ -32,22 +32,9 @@ export MKE2FS_CONFIG="$TESTDIR/lib/mke2fs.conf" - - aux prepare_vg 1 9000 - --lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1 -- -+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool - # Test caching VDOPoolLV --lvcreate -H -L10 $vg/vpool1 -- --# Current VDO target driver cannot handle online rename --# once this will be supported - update this test --not lvrename $vg/vpool1 $vg/vpool 2>&1 | tee out --grep "Cannot rename" out -- --lvchange -an $vg -- --# Ofline should work --lvrename $vg/vpool1 $vg/vpool -- --lvchange -ay $vg -+lvcreate -H -L10 $vg/vpool - - mkfs.ext4 -E nodiscard "$DM_DEV_DIR/$vg/$lv1" - -diff --git a/test/shell/lvrename-vdo.sh b/test/shell/lvrename-vdo.sh -new file mode 100644 -index 0000000..1417d9f ---- /dev/null -+++ b/test/shell/lvrename-vdo.sh -@@ -0,0 +1,88 @@ -+#!/usr/bin/env bash -+ -+# Copyright (C) 2021 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 -+ -+# Check online renaming of VDO devices works -+ -+ -+SKIP_WITH_LVMPOLLD=1 -+ -+. lib/inittest -+ -+# -+# Main -+# -+ -+aux have_vdo 6 2 1 || skip -+aux have_cache 1 3 0 || skip -+aux have_raid 1 3 0 || skip -+ -+aux prepare_vg 2 5000 -+ -+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1 -+lvrename $vg/vpool1 vpool2 -+check lv_exists $vg $lv1 vpool2 vpool2_vdata -+ -+lvremove -ff $vg -+ -+# With version >= 6.2.3 online rename should work -+if aux have_vdo 6 2 3 ; then -+ -+### CACHE #### -+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1 -+lvcreate -H -L10 $vg/vpool1 -+lvrename $vg/vpool1 $vg/vpool2 -+check lv_exists $vg vpool2 vpool2_vdata -+lvremove -ff $vg -+ -+### RAID #### -+lvcreate --type raid1 -L4G --nosync --name vpool1 $vg -+lvconvert --yes --type vdo-pool $vg/vpool1 -+lvrename $vg/vpool1 $vg/vpool2 -+check lv_exists $vg vpool2 vpool2_vdata vpool2_vdata_rimage_0 -+lvremove -ff $vg -+ -+fi # >= 6.2.3 -+ -+# Check when VDO target does not support online resize -+aux lvmconf "global/vdo_disabled_features = [ \"online_rename\" ]" -+ -+ -+### CACHE #### -+lvcreate --vdo -L4G -V2G --name $lv1 $vg/vpool1 -+lvcreate -H -L10 $vg/vpool1 -+ -+# VDO target driver cannot handle online rename -+not lvrename $vg/vpool1 $vg/vpool2 2>&1 | tee out -+grep "Cannot rename" out -+ -+# Ofline should work -+lvchange -an $vg -+lvrename $vg/vpool1 $vg/vpool2 -+lvchange -ay $vg -+check lv_exists $vg $lv1 vpool2 vpool2_vdata -+lvremove -ff $vg -+ -+ -+### RAID #### -+lvcreate --type raid1 -L4G --nosync --name vpool1 $vg -+lvconvert --yes --type vdo-pool $vg/vpool1 -+not lvrename $vg/vpool1 $vg/vpool2 2>&1 | tee out -+grep "Cannot rename" out -+ -+# Ofline should work -+lvchange -an $vg -+lvrename $vg/vpool1 $vg/vpool2 -+lvchange -ay $vg -+check lv_exists $vg vpool2 vpool2_vdata vpool2_vdata_rimage_0 -+lvremove -ff $vg -+ -+vgremove -ff $vg diff --git a/lvm2-2_03_12-tests-check-thin-pool-corner-case-allocs.patch b/lvm2-2_03_12-tests-check-thin-pool-corner-case-allocs.patch deleted file mode 100644 index 04962b8..0000000 --- a/lvm2-2_03_12-tests-check-thin-pool-corner-case-allocs.patch +++ /dev/null @@ -1,47 +0,0 @@ - test/shell/lvcreate-thin-limits.sh | 30 ++++++++++++++++++++++++++---- - 1 file changed, 26 insertions(+), 4 deletions(-) - -diff --git a/test/shell/lvcreate-thin-limits.sh b/test/shell/lvcreate-thin-limits.sh -index 6a9c33d..5dcc160 100644 ---- a/test/shell/lvcreate-thin-limits.sh -+++ b/test/shell/lvcreate-thin-limits.sh -@@ -27,13 +27,35 @@ aux can_use_16T || skip - aux have_thin 1 0 0 || skip - which mkfs.ext4 || skip - --aux prepare_pvs 1 16777216 -+# 16T device -+aux prepare_pvs 2 8388608 - get_devs - --vgcreate $SHARED -s 4K "$vg" "${DEVICES[@]}" -+# gives 16777215M device -+vgcreate $SHARED -s 4M "$vg" "${DEVICES[@]}" - --not lvcreate -T -L15.995T --poolmetadatasize 5G $vg/pool -+# For 1st. pass only single PV -+lvcreate -l100%PV --name $lv1 $vg "$dev2" - --lvs -ao+seg_pe_ranges $vg -+for i in 1 0 -+do -+ SIZE=$(get vg_field "$vg" vg_free --units m) -+ SIZE=${SIZE%%\.*} -+ -+ # ~16T - 2 * 5G + something -> should not fit -+ not lvcreate -Zn -T -L$(( SIZE - 2 * 5 * 1024 + 1 )) --poolmetadatasize 5G $vg/pool -+ -+ check vg_field "$vg" lv_count "$i" -+ -+ # Should fit data + metadata + pmspare -+ lvcreate -Zn -T -L$(( SIZE - 2 * 5 * 1024 )) --poolmetadatasize 5G $vg/pool -+ -+ check vg_field "$vg" vg_free "0" -+ -+ lvs -ao+seg_pe_ranges $vg -+ -+ # Remove everything for 2nd. pass -+ lvremove -ff $vg -+done - - vgremove -ff $vg diff --git a/lvm2-2_03_12-tests-update-thin-and-cache-checked-messages.patch b/lvm2-2_03_12-tests-update-thin-and-cache-checked-messages.patch deleted file mode 100644 index f4ccd37..0000000 --- a/lvm2-2_03_12-tests-update-thin-and-cache-checked-messages.patch +++ /dev/null @@ -1,77 +0,0 @@ - test/shell/lvconvert-thin.sh | 2 +- - test/shell/lvcreate-cache.sh | 12 +++++------- - test/shell/lvcreate-thin-big.sh | 10 +++++----- - 3 files changed, 11 insertions(+), 13 deletions(-) - -diff --git a/test/shell/lvconvert-thin.sh b/test/shell/lvconvert-thin.sh -index 1319655..ee85691 100644 ---- a/test/shell/lvconvert-thin.sh -+++ b/test/shell/lvconvert-thin.sh -@@ -128,7 +128,7 @@ lvcreate -L1T -n $lv1 $vg - lvcreate -L32G -n $lv2 $vg - # Warning about bigger then needed - lvconvert --yes --thinpool $vg/$lv1 --poolmetadata $vg/$lv2 2>&1 | tee err --grep "WARNING: Maximum" err -+grep -i "maximum" err - lvremove -f $vg - - -diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh -index 2c46e21..4d9d75e 100644 ---- a/test/shell/lvcreate-cache.sh -+++ b/test/shell/lvcreate-cache.sh -@@ -27,7 +27,6 @@ aux prepare_vg 5 80000 - - aux lvmconf 'global/cache_disabled_features = [ "policy_smq" ]' - -- - ####################### - # Cache_Pool creation # - ####################### -@@ -173,17 +172,16 @@ dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel - - lvremove -f $vg - -- - # Check minimum cache pool metadata size --lvcreate -l 1 --type cache-pool --poolmetadatasize 1 $vg 2>out --grep "WARNING: Minimum" out -+lvcreate -l 1 --type cache-pool --poolmetadatasize 1 $vg 2>&1 | tee out -+grep -i "minimal" out -+ - - # FIXME: This test is failing in allocator with smaller VG sizes --lvcreate -l 1 --type cache-pool --poolmetadatasize 17G $vg 2>out --grep "WARNING: Maximum" out -+lvcreate -l 1 --type cache-pool --poolmetadatasize 17G $vg 2>&1 | tee out -+grep -i "maximum" out - - lvremove -f $vg -- - ######################################## - # Cache conversion and r/w permissions # - ######################################## -diff --git a/test/shell/lvcreate-thin-big.sh b/test/shell/lvcreate-thin-big.sh -index 0b622b7..2549035 100644 ---- a/test/shell/lvcreate-thin-big.sh -+++ b/test/shell/lvcreate-thin-big.sh -@@ -31,14 +31,14 @@ vgcreate $SHARED -s 64K "$vg" "${DEVICES[@]}" - - # Size 0 is not valid - invalid lvcreate -L4M --chunksize 128 --poolmetadatasize 0 -T $vg/pool1 2>out --lvcreate -Zn -L4M --chunksize 128 --poolmetadatasize 16k -T $vg/pool1 2>out --grep "WARNING: Minimum" out -+lvcreate -Zn -L4M --chunksize 128 --poolmetadatasize 16k -T $vg/pool1 2>&1 >out -+grep -i "minimal" out - # FIXME: metadata allocation fails, if PV doesn't have at least 16GB - # i.e. pool metadata device cannot be multisegment --lvcreate -Zn -L4M --chunksize 64k --poolmetadatasize 17G -T $vg/pool2 2>out --grep "WARNING: Maximum" out -+lvcreate -Zn -L4M --chunksize 64k --poolmetadatasize 17G -T $vg/pool2 2>&1 >out -+grep "maximum" out - check lv_field $vg/pool1_tmeta size "2.00m" --check lv_field $vg/pool2_tmeta size "15.81g" -+check lv_field $vg/pool2_tmeta size "<15.88g" - - # Check we do report correct percent values. - lvcreate --type zero -L3G $vg -n pool3 diff --git a/lvm2-2_03_12-thin-improve-16g-support-for-thin-pool-metadata.patch b/lvm2-2_03_12-thin-improve-16g-support-for-thin-pool-metadata.patch deleted file mode 100644 index 8347ad4..0000000 --- a/lvm2-2_03_12-thin-improve-16g-support-for-thin-pool-metadata.patch +++ /dev/null @@ -1,694 +0,0 @@ - conf/example.conf.in | 7 +++ - device_mapper/all.h | 16 +++++-- - device_mapper/libdm-deptree.c | 39 ++++++++++++----- - lib/activate/dev_manager.c | 8 ++-- - lib/config/config_settings.h | 5 +++ - lib/config/defaults.h | 2 + - lib/format_text/flags.c | 1 + - lib/metadata/lv_manip.c | 31 ++++++++++++++ - lib/metadata/merge.c | 2 + - lib/metadata/metadata-exported.h | 11 +++++ - lib/metadata/metadata.h | 13 ++++++ - lib/metadata/pool_manip.c | 46 ++++++++++++++++++++ - lib/metadata/thin_manip.c | 92 ++++++++++++++++++++++++++-------------- - lib/thin/thin.c | 22 +++++++--- - man/lvmthin.7_main | 10 ++++- - tools/lvconvert.c | 4 ++ - tools/lvcreate.c | 2 + - 17 files changed, 256 insertions(+), 55 deletions(-) - -diff --git a/conf/example.conf.in b/conf/example.conf.in -index d149ed9..107a071 100644 ---- a/conf/example.conf.in -+++ b/conf/example.conf.in -@@ -494,6 +494,13 @@ allocation { - # This configuration option has an automatic default value. - # thin_pool_metadata_require_separate_pvs = 0 - -+ # Configuration option allocation/thin_pool_crop_metadata. -+ # Older version of lvm2 cropped pool's metadata size to 15.81 GiB. -+ # This is slightly less then the actual maximum 15.88 GiB. -+ # For compatibility with older version and use of cropped size set to 1. -+ # This configuration option has an automatic default value. -+ # thin_pool_crop_metadata = 0 -+ - # Configuration option allocation/thin_pool_zero. - # Thin pool data chunks are zeroed before they are first used. - # Zeroing with a larger thin pool chunk size reduces performance. -diff --git a/device_mapper/all.h b/device_mapper/all.h -index 1080d25..489ca1c 100644 ---- a/device_mapper/all.h -+++ b/device_mapper/all.h -@@ -1072,10 +1072,10 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node, - #define DM_THIN_MIN_DATA_BLOCK_SIZE (UINT32_C(128)) - #define DM_THIN_MAX_DATA_BLOCK_SIZE (UINT32_C(2097152)) - /* -- * Max supported size for thin pool metadata device (17112760320 bytes) -- * Limitation is hardcoded into the kernel and bigger device size -- * is not accepted. -+ * Max supported size for thin pool metadata device (17045913600 bytes) - * drivers/md/dm-thin-metadata.h THIN_METADATA_MAX_SECTORS -+ * But here DM_THIN_MAX_METADATA_SIZE got defined incorrectly -+ * Correct size is (UINT64_C(255) * ((1 << 14) - 64) * (4096 / (1 << 9))) - */ - #define DM_THIN_MAX_METADATA_SIZE (UINT64_C(255) * (1 << 14) * (4096 / (1 << 9)) - 256 * 1024) - -@@ -1088,6 +1088,16 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node, - uint64_t low_water_mark, - unsigned skip_block_zeroing); - -+int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node, -+ uint64_t size, -+ uint64_t transaction_id, -+ const char *metadata_uuid, -+ const char *pool_uuid, -+ uint32_t data_block_size, -+ uint64_t low_water_mark, -+ unsigned skip_block_zeroing, -+ unsigned crop_metadata); -+ - /* Supported messages for thin provision target */ - typedef enum { - DM_THIN_MESSAGE_CREATE_SNAP, /* device_id, origin_id */ -diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c -index 6ce956f..5b60dc9 100644 ---- a/device_mapper/libdm-deptree.c -+++ b/device_mapper/libdm-deptree.c -@@ -3979,6 +3979,24 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node, - uint64_t low_water_mark, - unsigned skip_block_zeroing) - { -+ return dm_tree_node_add_thin_pool_target_v1(node, size, transaction_id, -+ metadata_uuid, pool_uuid, -+ data_block_size, -+ low_water_mark, -+ skip_block_zeroing, -+ 1); -+} -+ -+int dm_tree_node_add_thin_pool_target_v1(struct dm_tree_node *node, -+ uint64_t size, -+ uint64_t transaction_id, -+ const char *metadata_uuid, -+ const char *pool_uuid, -+ uint32_t data_block_size, -+ uint64_t low_water_mark, -+ unsigned skip_block_zeroing, -+ unsigned crop_metadata) -+{ - struct load_segment *seg, *mseg; - uint64_t devsize = 0; - -@@ -4005,17 +4023,18 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node, - if (!_link_tree_nodes(node, seg->metadata)) - return_0; - -- /* FIXME: more complex target may need more tweaks */ -- dm_list_iterate_items(mseg, &seg->metadata->props.segs) { -- devsize += mseg->size; -- if (devsize > DM_THIN_MAX_METADATA_SIZE) { -- log_debug_activation("Ignoring %" PRIu64 " of device.", -- devsize - DM_THIN_MAX_METADATA_SIZE); -- mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE); -- devsize = DM_THIN_MAX_METADATA_SIZE; -- /* FIXME: drop remaining segs */ -+ if (crop_metadata) -+ /* FIXME: more complex target may need more tweaks */ -+ dm_list_iterate_items(mseg, &seg->metadata->props.segs) { -+ devsize += mseg->size; -+ if (devsize > DM_THIN_MAX_METADATA_SIZE) { -+ log_debug_activation("Ignoring %" PRIu64 " of device.", -+ devsize - DM_THIN_MAX_METADATA_SIZE); -+ mseg->size -= (devsize - DM_THIN_MAX_METADATA_SIZE); -+ devsize = DM_THIN_MAX_METADATA_SIZE; -+ /* FIXME: drop remaining segs */ -+ } - } -- } - - if (!(seg->pool = dm_tree_find_node_by_uuid(node->dtree, pool_uuid))) { - log_error("Missing pool uuid %s.", pool_uuid); -diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c -index 8d27bd3..9a25482 100644 ---- a/lib/activate/dev_manager.c -+++ b/lib/activate/dev_manager.c -@@ -261,7 +261,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, - int dmtask; - int with_flush; /* TODO: arg for _info_run */ - void *target = NULL; -- uint64_t target_start, target_length, start, length; -+ uint64_t target_start, target_length, start, length, length_crop = 0; - char *target_name, *target_params; - const char *devname; - -@@ -297,7 +297,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, - /* Uses max DM_THIN_MAX_METADATA_SIZE sectors for metadata device */ - if (lv_is_thin_pool_metadata(seg_status->seg->lv) && - (length > DM_THIN_MAX_METADATA_SIZE)) -- length = DM_THIN_MAX_METADATA_SIZE; -+ length_crop = DM_THIN_MAX_METADATA_SIZE; - - /* Uses virtual size with headers for VDO pool device */ - if (lv_is_vdo_pool(seg_status->seg->lv)) -@@ -310,7 +310,9 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, - target = dm_get_next_target(dmt, target, &target_start, - &target_length, &target_name, &target_params); - -- if ((start == target_start) && (length == target_length)) -+ if ((start == target_start) && -+ ((length == target_length) || -+ (length_crop && (length_crop == target_length)))) - break; /* Keep target_params when matching segment is found */ - - target_params = NULL; /* Marking this target_params unusable */ -diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h -index 3c4032e..cb4e23a 100644 ---- a/lib/config/config_settings.h -+++ b/lib/config/config_settings.h -@@ -628,6 +628,11 @@ cfg(allocation_cache_pool_max_chunks_CFG, "cache_pool_max_chunks", allocation_CF - cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL, 0, NULL, - "Thin pool metadata and data will always use different PVs.\n") - -+cfg(allocation_thin_pool_crop_metadata_CFG, "thin_pool_crop_metadata", allocation_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_CROP_METADATA, vsn(2, 3, 12), NULL, 0, NULL, -+ "Older version of lvm2 cropped pool's metadata size to 15.81 GiB.\n" -+ "This is slightly less then the actual maximum 15.88 GiB.\n" -+ "For compatibility with older version and use of cropped size set to 1.\n") -+ - cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL, 0, NULL, - "Thin pool data chunks are zeroed before they are first used.\n" - "Zeroing with a larger thin pool chunk size reduces performance.\n") -diff --git a/lib/config/defaults.h b/lib/config/defaults.h -index 708a575..bcc20cc 100644 ---- a/lib/config/defaults.h -+++ b/lib/config/defaults.h -@@ -118,6 +118,8 @@ - #define DEFAULT_THIN_REPAIR_OPTION1 "" - #define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1 - #define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0 -+#define DEFAULT_THIN_POOL_CROP_METADATA 0 -+#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB (UINT64_C(255) * ((1 << 14) - 64) * 4) /* KB */ /* 0x3f8040 blocks */ - #define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */ - #define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */ - #define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024) /* KB */ -diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c -index bc93a5d..4cee14a 100644 ---- a/lib/format_text/flags.c -+++ b/lib/format_text/flags.c -@@ -72,6 +72,7 @@ static const struct flag _lv_flags[] = { - {LV_ACTIVATION_SKIP, "ACTIVATION_SKIP", COMPATIBLE_FLAG}, - {LV_ERROR_WHEN_FULL, "ERROR_WHEN_FULL", COMPATIBLE_FLAG}, - {LV_METADATA_FORMAT, "METADATA_FORMAT", SEGTYPE_FLAG}, -+ {LV_CROP_METADATA, "CROP_METADATA", SEGTYPE_FLAG}, - {LV_CACHE_VOL, "CACHE_VOL", COMPATIBLE_FLAG}, - {LV_CACHE_USES_CACHEVOL, "CACHE_USES_CACHEVOL", SEGTYPE_FLAG}, - {LV_NOSCAN, NULL, 0}, -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index 443d32c..445c4ad 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -5384,6 +5384,8 @@ static int _lvresize_adjust_extents(struct logical_volume *lv, - uint32_t existing_extents; - uint32_t seg_size = 0; - uint32_t new_extents; -+ uint64_t max_metadata_size; -+ thin_crop_metadata_t crop; - int reducing = 0; - - seg_last = last_seg(lv); -@@ -5544,6 +5546,33 @@ static int _lvresize_adjust_extents(struct logical_volume *lv, - return 1; - } - } -+ } else if (lv_is_thin_pool_metadata(lv)) { -+ if (!(seg = get_only_segment_using_this_lv(lv))) -+ return_0; -+ -+ max_metadata_size = get_thin_pool_max_metadata_size(cmd, vg->profile, &crop); -+ -+ if (((uint64_t)lp->extents * vg->extent_size) > max_metadata_size) { -+ lp->extents = (max_metadata_size + vg->extent_size - 1) / vg->extent_size; -+ log_print_unless_silent("Reached maximum pool metadata size %s (%" PRIu32 " extents).", -+ display_size(vg->cmd, max_metadata_size), lp->extents); -+ } -+ -+ if (existing_logical_extents >= lp->extents) -+ lp->extents = existing_logical_extents; -+ -+ crop = get_thin_pool_crop_metadata(cmd, crop, (uint64_t)lp->extents * vg->extent_size); -+ -+ if (seg->crop_metadata != crop) { -+ seg->crop_metadata = crop; -+ seg->lv->status |= LV_CROP_METADATA; -+ /* Crop change require reload even if there no size change */ -+ lp->size_changed = 1; -+ log_print_unless_silent("Thin pool will use metadata without cropping."); -+ } -+ -+ if (!(seg_size = lp->extents - existing_logical_extents)) -+ return 1; /* No change in metadata size */ - } - } else { /* If reducing, find stripes, stripesize & size of last segment */ - if (lp->stripes || lp->stripe_size || lp->mirrors) -@@ -8388,6 +8417,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, - first_seg(lv)->chunk_size = lp->chunk_size; - first_seg(lv)->zero_new_blocks = lp->zero_new_blocks; - first_seg(lv)->discards = lp->discards; -+ if ((first_seg(lv)->crop_metadata = lp->crop_metadata) == THIN_CROP_METADATA_NO) -+ lv->status |= LV_CROP_METADATA; - if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->thin_chunk_size_calc_policy)) { - stack; - goto revert_new_lv; -diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c -index 0aa2293..eff59ae 100644 ---- a/lib/metadata/merge.c -+++ b/lib/metadata/merge.c -@@ -495,6 +495,8 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg, - seg_error("sets discards"); - if (!dm_list_empty(&seg->thin_messages)) - seg_error("sets thin_messages list"); -+ if (seg->lv->status & LV_CROP_METADATA) -+ seg_error("sets CROP_METADATA flag"); - } - - if (seg_is_thin_volume(seg)) { -diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h -index 54dc29f..0e57722 100644 ---- a/lib/metadata/metadata-exported.h -+++ b/lib/metadata/metadata-exported.h -@@ -143,6 +143,7 @@ - - #define LV_REMOVE_AFTER_RESHAPE UINT64_C(0x0400000000000000) /* LV needs to be removed after a shrinking reshape */ - #define LV_METADATA_FORMAT UINT64_C(0x0800000000000000) /* LV has segments with metadata format */ -+#define LV_CROP_METADATA UINT64_C(0x0000000000000400) /* LV - also VG CLUSTERED */ - - #define LV_RESHAPE UINT64_C(0x1000000000000000) /* Ongoing reshape (number of stripes, stripesize or raid algorithm change): - used as SEGTYPE_FLAG to prevent activation on old runtime */ -@@ -326,6 +327,12 @@ typedef enum { - } thin_discards_t; - - typedef enum { -+ THIN_CROP_METADATA_UNSELECTED = 0, /* 'auto' selects */ -+ THIN_CROP_METADATA_NO, -+ THIN_CROP_METADATA_YES, -+} thin_crop_metadata_t; -+ -+typedef enum { - CACHE_MODE_UNSELECTED = 0, - CACHE_MODE_WRITETHROUGH, - CACHE_MODE_WRITEBACK, -@@ -502,6 +509,7 @@ struct lv_segment { - uint64_t transaction_id; /* For thin_pool, thin */ - thin_zero_t zero_new_blocks; /* For thin_pool */ - thin_discards_t discards; /* For thin_pool */ -+ thin_crop_metadata_t crop_metadata; /* For thin_pool */ - struct dm_list thin_messages; /* For thin_pool */ - struct logical_volume *external_lv; /* For thin */ - struct logical_volume *pool_lv; /* For thin, cache */ -@@ -885,6 +893,8 @@ int update_thin_pool_params(struct cmd_context *cmd, - unsigned attr, - uint32_t pool_data_extents, - uint32_t *pool_metadata_extents, -+ struct logical_volume *metadata_lv, -+ unsigned *crop_metadata, - int *chunk_size_calc_method, uint32_t *chunk_size, - thin_discards_t *discards, thin_zero_t *zero_new_blocks); - -@@ -1011,6 +1021,7 @@ struct lvcreate_params { - - uint64_t permission; /* all */ - unsigned error_when_full; /* when segment supports it */ -+ thin_crop_metadata_t crop_metadata; - uint32_t read_ahead; /* all */ - int approx_alloc; /* all */ - alloc_policy_t alloc; /* all */ -diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h -index 2c22450..0f230e4 100644 ---- a/lib/metadata/metadata.h -+++ b/lib/metadata/metadata.h -@@ -512,8 +512,21 @@ int pool_below_threshold(const struct lv_segment *pool_seg); - int pool_check_overprovisioning(const struct logical_volume *lv); - int create_pool(struct logical_volume *pool_lv, const struct segment_type *segtype, - struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size); -+uint64_t get_thin_pool_max_metadata_size(struct cmd_context *cmd, struct profile *profile, -+ thin_crop_metadata_t *crop); -+thin_crop_metadata_t get_thin_pool_crop_metadata(struct cmd_context *cmd, -+ thin_crop_metadata_t crop, -+ uint64_t metadata_size); - uint64_t estimate_thin_pool_metadata_size(uint32_t data_extents, uint32_t extent_size, uint32_t chunk_size); - -+int update_pool_metadata_min_max(struct cmd_context *cmd, -+ uint32_t extent_size, -+ uint64_t min_metadata_size, /* required min */ -+ uint64_t max_metadata_size, /* writable max */ -+ uint64_t *metadata_size, /* current calculated */ -+ struct logical_volume *metadata_lv, /* name of converted LV or NULL */ -+ uint32_t *metadata_extents); /* resulting extent count */ -+ - /* - * Begin skeleton for external LVM library - */ -diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c -index a9dc611..b67882e 100644 ---- a/lib/metadata/pool_manip.c -+++ b/lib/metadata/pool_manip.c -@@ -742,6 +742,52 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents, - return 1; - } - -+int update_pool_metadata_min_max(struct cmd_context *cmd, -+ uint32_t extent_size, -+ uint64_t min_metadata_size, /* required min */ -+ uint64_t max_metadata_size, /* writable max */ -+ uint64_t *metadata_size, /* current calculated */ -+ struct logical_volume *metadata_lv, /* name of converted LV or NULL */ -+ uint32_t *metadata_extents) /* resulting extent count */ -+{ -+ max_metadata_size = dm_round_up(max_metadata_size, extent_size); -+ min_metadata_size = dm_round_up(min_metadata_size, extent_size); -+ -+ if (*metadata_size > max_metadata_size) { -+ if (metadata_lv) { -+ log_print_unless_silent("Size %s of pool metadata volume %s is bigger then maximum usable size %s.", -+ display_size(cmd, *metadata_size), -+ display_lvname(metadata_lv), -+ display_size(cmd, max_metadata_size)); -+ } else { -+ if (*metadata_extents) -+ log_print_unless_silent("Reducing pool metadata size %s to maximum usable size %s.", -+ display_size(cmd, *metadata_size), -+ display_size(cmd, max_metadata_size)); -+ *metadata_size = max_metadata_size; -+ } -+ } else if (*metadata_size < min_metadata_size) { -+ if (metadata_lv) { -+ log_error("Can't use volume %s with size %s as pool metadata. Minimal required size is %s.", -+ display_lvname(metadata_lv), -+ display_size(cmd, *metadata_size), -+ display_size(cmd, min_metadata_size)); -+ return 0; -+ } else { -+ if (*metadata_extents) -+ log_print_unless_silent("Extending pool metadata size %s to required minimal size %s.", -+ display_size(cmd, *metadata_size), -+ display_size(cmd, min_metadata_size)); -+ *metadata_size = min_metadata_size; -+ } -+ } -+ -+ if (!(*metadata_extents = extents_from_size(cmd, *metadata_size, extent_size))) -+ return_0; -+ -+ return 1; -+} -+ - int vg_set_pool_metadata_spare(struct logical_volume *lv) - { - char new_name[NAME_LEN]; -diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c -index 4591dd7..451c382 100644 ---- a/lib/metadata/thin_manip.c -+++ b/lib/metadata/thin_manip.c -@@ -610,9 +610,9 @@ static uint64_t _estimate_metadata_size(uint32_t data_extents, uint32_t extent_s - } - - /* Estimate maximal supportable thin pool data size for given chunk_size */ --static uint64_t _estimate_max_data_size(uint32_t chunk_size) -+static uint64_t _estimate_max_data_size(uint64_t max_metadata_size, uint32_t chunk_size) - { -- return chunk_size * (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2) * SECTOR_SIZE / UINT64_C(64); -+ return max_metadata_size * chunk_size * SECTOR_SIZE / UINT64_C(64); - } - - /* Estimate thin pool chunk size from data and metadata size (in sector units) */ -@@ -662,6 +662,38 @@ int get_default_allocation_thin_pool_chunk_size(struct cmd_context *cmd, struct - return 1; - } - -+/* Return max supported metadata size with selected cropping */ -+uint64_t get_thin_pool_max_metadata_size(struct cmd_context *cmd, struct profile *profile, -+ thin_crop_metadata_t *crop) -+{ -+ *crop = find_config_tree_bool(cmd, allocation_thin_pool_crop_metadata_CFG, profile) ? -+ THIN_CROP_METADATA_YES : THIN_CROP_METADATA_NO; -+ -+ return (*crop == THIN_CROP_METADATA_NO) ? -+ (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE_V1_KB) : (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE); -+} -+ -+/* -+ * With existing crop method, check if the metadata_size would need cropping. -+ * If not, set UNSELECTED, otherwise print some verbose info about selected cropping -+ */ -+thin_crop_metadata_t get_thin_pool_crop_metadata(struct cmd_context *cmd, -+ thin_crop_metadata_t crop, -+ uint64_t metadata_size) -+{ -+ const uint64_t crop_size = (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE); -+ -+ if (metadata_size > crop_size) { -+ if (crop == THIN_CROP_METADATA_NO) -+ log_verbose("Using metadata size without cropping."); -+ else -+ log_verbose("Cropping metadata size to %s.", display_size(cmd, crop_size)); -+ } else -+ crop = THIN_CROP_METADATA_UNSELECTED; -+ -+ return crop; -+} -+ - int update_thin_pool_params(struct cmd_context *cmd, - struct profile *profile, - uint32_t extent_size, -@@ -669,10 +701,13 @@ int update_thin_pool_params(struct cmd_context *cmd, - unsigned attr, - uint32_t pool_data_extents, - uint32_t *pool_metadata_extents, -+ struct logical_volume *metadata_lv, -+ thin_crop_metadata_t *crop_metadata, - int *chunk_size_calc_method, uint32_t *chunk_size, - thin_discards_t *discards, thin_zero_t *zero_new_blocks) - { -- uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size; -+ uint64_t pool_metadata_size; -+ uint64_t max_metadata_size; - uint32_t estimate_chunk_size; - uint64_t max_pool_data_size; - const char *str; -@@ -702,7 +737,9 @@ int update_thin_pool_params(struct cmd_context *cmd, - *zero_new_blocks = find_config_tree_bool(cmd, allocation_thin_pool_zero_CFG, profile) - ? THIN_ZERO_YES : THIN_ZERO_NO; - -- if (!pool_metadata_size) { -+ max_metadata_size = get_thin_pool_max_metadata_size(cmd, profile, crop_metadata); -+ -+ if (!*pool_metadata_extents) { - if (!*chunk_size) { - if (!get_default_allocation_thin_pool_chunk_size(cmd, profile, - chunk_size, -@@ -723,20 +760,20 @@ int update_thin_pool_params(struct cmd_context *cmd, - } else { - pool_metadata_size = _estimate_metadata_size(pool_data_extents, extent_size, *chunk_size); - -- if (pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) { -+ if (pool_metadata_size > max_metadata_size) { - /* Suggest bigger chunk size */ - estimate_chunk_size = - _estimate_chunk_size(pool_data_extents, extent_size, -- (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2), attr); -+ max_metadata_size, attr); - log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.", - display_size(cmd, estimate_chunk_size)); - } - } - - /* Round up to extent size silently */ -- if (pool_metadata_size % extent_size) -- pool_metadata_size += extent_size - pool_metadata_size % extent_size; -+ pool_metadata_size = dm_round_up(pool_metadata_size, extent_size); - } else { -+ pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size; - estimate_chunk_size = _estimate_chunk_size(pool_data_extents, extent_size, - pool_metadata_size, attr); - -@@ -751,7 +788,19 @@ int update_thin_pool_params(struct cmd_context *cmd, - } - } - -- max_pool_data_size = _estimate_max_data_size(*chunk_size); -+ /* Use not rounded max for data size */ -+ max_pool_data_size = _estimate_max_data_size(max_metadata_size, *chunk_size); -+ -+ if (!update_pool_metadata_min_max(cmd, extent_size, -+ 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE, -+ max_metadata_size, -+ &pool_metadata_size, -+ metadata_lv, -+ pool_metadata_extents)) -+ return_0; -+ -+ *crop_metadata = get_thin_pool_crop_metadata(cmd, *crop_metadata, pool_metadata_size); -+ - if ((max_pool_data_size / extent_size) < pool_data_extents) { - log_error("Selected chunk size %s cannot address more then %s of thin pool data space.", - display_size(cmd, *chunk_size), display_size(cmd, max_pool_data_size)); -@@ -764,22 +813,6 @@ int update_thin_pool_params(struct cmd_context *cmd, - if (!validate_thin_pool_chunk_size(cmd, *chunk_size)) - return_0; - -- if (pool_metadata_size > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) { -- pool_metadata_size = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -- if (*pool_metadata_extents) -- log_warn("WARNING: Maximum supported pool metadata size is %s.", -- display_size(cmd, pool_metadata_size)); -- } else if (pool_metadata_size < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) { -- pool_metadata_size = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; -- if (*pool_metadata_extents) -- log_warn("WARNING: Minimum supported pool metadata size is %s.", -- display_size(cmd, pool_metadata_size)); -- } -- -- if (!(*pool_metadata_extents = -- extents_from_size(cmd, pool_metadata_size, extent_size))) -- return_0; -- - if ((uint64_t) *chunk_size > (uint64_t) pool_data_extents * extent_size) { - log_error("Size of %s data volume cannot be smaller than chunk size %s.", - segtype->name, display_size(cmd, *chunk_size)); -@@ -958,12 +991,5 @@ int validate_thin_pool_chunk_size(struct cmd_context *cmd, uint32_t chunk_size) - - uint64_t estimate_thin_pool_metadata_size(uint32_t data_extents, uint32_t extent_size, uint32_t chunk_size) - { -- uint64_t sz = _estimate_metadata_size(data_extents, extent_size, chunk_size); -- -- if (sz > (2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE)) -- sz = 2 * DEFAULT_THIN_POOL_MAX_METADATA_SIZE; -- else if (sz < (2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE)) -- sz = 2 * DEFAULT_THIN_POOL_MIN_METADATA_SIZE; -- -- return sz; -+ return _estimate_metadata_size(data_extents, extent_size, chunk_size); - } -diff --git a/lib/thin/thin.c b/lib/thin/thin.c -index ba0da71..51bc269 100644 ---- a/lib/thin/thin.c -+++ b/lib/thin/thin.c -@@ -86,6 +86,7 @@ static int _thin_pool_text_import(struct lv_segment *seg, - struct logical_volume *pool_data_lv, *pool_metadata_lv; - const char *discards_str = NULL; - uint32_t zero = 0; -+ uint32_t crop = 0; - - if (!dm_config_get_str(sn, "metadata", &lv_name)) - return SEG_LOG_ERROR("Metadata must be a string in"); -@@ -131,6 +132,13 @@ static int _thin_pool_text_import(struct lv_segment *seg, - - seg->zero_new_blocks = (zero) ? THIN_ZERO_YES : THIN_ZERO_NO; - -+ if (dm_config_has_node(sn, "crop_metadata")) { -+ if (!dm_config_get_uint32(sn, "crop_metadata", &crop)) -+ return SEG_LOG_ERROR("Could not read crop_metadata for"); -+ seg->crop_metadata = (crop) ? THIN_CROP_METADATA_YES : THIN_CROP_METADATA_NO; -+ seg->lv->status |= LV_CROP_METADATA; -+ } -+ - /* Read messages */ - for (; sn; sn = sn->sib) - if (!(sn->v) && !_thin_pool_add_message(seg, sn->key, sn->child)) -@@ -177,6 +185,9 @@ static int _thin_pool_text_export(const struct lv_segment *seg, struct formatter - return 0; - } - -+ if (seg->crop_metadata != THIN_CROP_METADATA_UNSELECTED) -+ outf(f, "crop_metadata = %u", (seg->crop_metadata == THIN_CROP_METADATA_YES) ? 1 : 0); -+ - dm_list_iterate_items(tmsg, &seg->thin_messages) { - /* Extra validation */ - switch (tmsg->type) { -@@ -307,11 +318,12 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, - else - low_water_mark = 0; - -- if (!dm_tree_node_add_thin_pool_target(node, len, -- seg->transaction_id, -- metadata_dlid, pool_dlid, -- seg->chunk_size, low_water_mark, -- (seg->zero_new_blocks == THIN_ZERO_YES) ? 0 : 1)) -+ if (!dm_tree_node_add_thin_pool_target_v1(node, len, -+ seg->transaction_id, -+ metadata_dlid, pool_dlid, -+ seg->chunk_size, low_water_mark, -+ (seg->zero_new_blocks == THIN_ZERO_YES) ? 0 : 1, -+ (seg->crop_metadata == THIN_CROP_METADATA_YES) ? 1 : 0)) - return_0; - - if (attr & THIN_FEATURE_DISCARDS) { -diff --git a/man/lvmthin.7_main b/man/lvmthin.7_main -index e6f1d63..3ce34a5 100644 ---- a/man/lvmthin.7_main -+++ b/man/lvmthin.7_main -@@ -1104,7 +1104,7 @@ The default value is shown by: - The amount of thin metadata depends on how many blocks are shared between - thin LVs (i.e. through snapshots). A thin pool with many snapshots may - need a larger metadata LV. Thin pool metadata LV sizes can be from 2MiB --to 16GiB. -+to approximately 16GiB. - - When using lvcreate to create what will become a thin metadata LV, the - size is specified with the -L|--size option. -@@ -1119,6 +1119,14 @@ needed, so it is recommended to start with a size of 1GiB which should be - enough for all practical purposes. A thin pool metadata LV can later be - manually or automatically extended if needed. - -+Configurable setting -+.BR lvm.conf (5) -+.BR allocation / thin_pool_crop_metadata -+gives control over cropping to 15.81GiB to stay backward compatible with older -+versions of lvm2. With enabled cropping there can be observed some problems when -+using volumes above this size with thin tools (i.e. thin_repair). -+Cropping should be enabled only when compatibility is required. -+ - - .SS Create a thin snapshot of an external, read only LV - -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index 7b74afb..ce90279 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -3032,6 +3032,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - const char *policy_name; - struct dm_config_tree *policy_settings = NULL; - int pool_metadata_spare; -+ thin_crop_metadata_t crop_metadata; - thin_discards_t discards; - thin_zero_t zero_new_blocks; - int r = 0; -@@ -3196,6 +3197,8 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - pool_segtype, target_attr, - lv->le_count, - &meta_extents, -+ metadata_lv, -+ &crop_metadata, - &chunk_calc, - &chunk_size, - &discards, &zero_new_blocks)) -@@ -3401,6 +3404,7 @@ static int _lvconvert_to_pool(struct cmd_context *cmd, - goto_bad; - } else { - seg->transaction_id = 0; -+ seg->crop_metadata = crop_metadata; - seg->chunk_size = chunk_size; - seg->discards = discards; - seg->zero_new_blocks = zero_new_blocks; -diff --git a/tools/lvcreate.c b/tools/lvcreate.c -index e384291..1ee9e14 100644 ---- a/tools/lvcreate.c -+++ b/tools/lvcreate.c -@@ -391,6 +391,8 @@ static int _update_extents_params(struct volume_group *vg, - lp->segtype, lp->target_attr, - lp->extents, - &lp->pool_metadata_extents, -+ NULL, -+ &lp->crop_metadata, - &lp->thin_chunk_size_calc_policy, - &lp->chunk_size, - &lp->discards, diff --git a/lvm2-2_03_12-vdo-support-online-rename.patch b/lvm2-2_03_12-vdo-support-online-rename.patch deleted file mode 100644 index ab2bc0e..0000000 --- a/lvm2-2_03_12-vdo-support-online-rename.patch +++ /dev/null @@ -1,194 +0,0 @@ - conf/example.conf.in | 10 ++++++++++ - lib/config/config_settings.h | 9 +++++++++ - lib/metadata/lv_manip.c | 14 +++++++++++--- - lib/metadata/segtype.h | 2 ++ - lib/vdo/vdo.c | 46 ++++++++++++++++++++++++++++++++++++-------- - 5 files changed, 70 insertions(+), 11 deletions(-) - -diff --git a/conf/example.conf.in b/conf/example.conf.in -index cd53147..d02965e 100644 ---- a/conf/example.conf.in -+++ b/conf/example.conf.in -@@ -1195,6 +1195,16 @@ global { - # This configuration option has an automatic default value. - # vdo_format_options = [ "" ] - -+ # Configuration option global/vdo_disabled_features. -+ # Features to not use in the vdo driver. -+ # This can be helpful for testing, or to avoid using a feature that is -+ # causing problems. Features include: online_rename -+ # -+ # Example -+ # vdo_disabled_features = [ "online_rename" ] -+ # -+ # This configuration option does not have a default value defined. -+ - # Configuration option global/fsadm_executable. - # The full path to the fsadm command. - # LVM uses this command to help with lvresize -r operations. -diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h -index 3c4032e..f844594 100644 ---- a/lib/config/config_settings.h -+++ b/lib/config/config_settings.h -@@ -1206,6 +1206,15 @@ cfg(global_vdo_format_executable_CFG, "vdo_format_executable", global_CFG_SECTIO - cfg_array(global_vdo_format_options_CFG, "vdo_format_options", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_VDO_FORMAT_OPTIONS_CONFIG, VDO_1ST_VSN, NULL, 0, NULL, - "List of options passed added to standard vdoformat command.\n") - -+cfg_array(global_vdo_disabled_features_CFG, "vdo_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 3, 11), NULL, 0, NULL, -+ "Features to not use in the vdo driver.\n" -+ "This can be helpful for testing, or to avoid using a feature that is\n" -+ "causing problems. Features include: online_rename\n" -+ "#\n" -+ "Example\n" -+ "vdo_disabled_features = [ \"online_rename\" ]\n" -+ "#\n") -+ - cfg(global_fsadm_executable_CFG, "fsadm_executable", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FSADM_PATH, vsn(2, 2, 170), "@FSADM_PATH@", 0, NULL, - "The full path to the fsadm command.\n" - "LVM uses this command to help with lvresize -r operations.\n") -diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c -index c740ba2..6c71263 100644 ---- a/lib/metadata/lv_manip.c -+++ b/lib/metadata/lv_manip.c -@@ -4738,6 +4738,8 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv, - struct lv_names lv_names = { .old = lv->name }; - int old_lv_is_historical = lv_is_historical(lv); - int historical; -+ unsigned attrs; -+ const struct segment_type *segtype; - - /* - * rename is not allowed on sub LVs except for pools -@@ -4763,9 +4765,15 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv, - } - - if (lv_is_vdo_pool(lv) && lv_is_active(lv_lock_holder(lv))) { -- log_error("Cannot rename active VDOPOOL volume %s.", -- display_lvname(lv)); -- return 0; -+ segtype = first_seg(lv)->segtype; -+ if (!segtype->ops->target_present || -+ !segtype->ops->target_present(lv->vg->cmd, NULL, &attrs) || -+ !(attrs & VDO_FEATURE_ONLINE_RENAME)) { -+ log_error("Cannot rename active VDOPOOL volume %s, " -+ "VDO target feature support is missing.", -+ display_lvname(lv)); -+ return 0; -+ } - } - - if (update_mda && !archive(vg)) -diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h -index 08ddc35..2714a6b 100644 ---- a/lib/metadata/segtype.h -+++ b/lib/metadata/segtype.h -@@ -349,6 +349,8 @@ int init_cache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib) - int init_vdo_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); - #endif - -+#define VDO_FEATURE_ONLINE_RENAME (1U << 0) /* version 6.2.3 */ -+ - int init_writecache_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); - - int init_integrity_segtypes(struct cmd_context *cmd, struct segtype_library *seglib); -diff --git a/lib/vdo/vdo.c b/lib/vdo/vdo.c -index c43a5dc..bb7c784 100644 ---- a/lib/vdo/vdo.c -+++ b/lib/vdo/vdo.c -@@ -25,6 +25,7 @@ - #include "lib/metadata/segtype.h" - #include "base/memory/zalloc.h" - -+static const char _vdo_module[] = MODULE_NAME_VDO; - static unsigned _feature_mask; - - static int _bad_field(const char *field) -@@ -391,18 +392,21 @@ static int _vdo_target_present(struct cmd_context *cmd, - static const struct feature { - uint32_t maj; - uint32_t min; -+ uint32_t patchlevel; - unsigned vdo_feature; - const char *feature; - } _features[] = { -- { 1, 1, 0, "" }, -- //{ 9, 9, VDO_FEATURE_RESIZE, "resize" }, -+ { 6, 2, 3, VDO_FEATURE_ONLINE_RENAME, "online_rename" }, - }; -- //static const char _lvmconf[] = "global/vdo_disabled_features"; -+ static const char _lvmconf[] = "global/vdo_disabled_features"; - static int _vdo_checked = 0; - static int _vdo_present = 0; - static unsigned _vdo_attrs = 0; - uint32_t i, maj, min, patchlevel; - const struct segment_type *segtype; -+ const struct dm_config_node *cn; -+ const struct dm_config_value *cv; -+ const char *str; - - if (!activation()) - return 0; -@@ -419,8 +423,8 @@ static int _vdo_target_present(struct cmd_context *cmd, - } - - if (maj < 6 || (maj == 6 && min < 2)) { -- log_warn("WARNING: VDO target version %u.%u.%u is too old.", -- maj, min, patchlevel); -+ log_warn("WARNING: Target %s version %u.%u.%u is too old.", -+ _vdo_module, maj, min, patchlevel); - return 0; - } - -@@ -437,15 +441,41 @@ static int _vdo_target_present(struct cmd_context *cmd, - /* Prepare for adding supported features */ - for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) - if ((maj > _features[i].maj) || -- (maj == _features[i].maj && min >= _features[i].min)) -+ ((maj == _features[i].maj) && (min > _features[i].min)) || -+ ((maj == _features[i].maj) && (min == _features[i].min) && (patchlevel >= _features[i].patchlevel))) - _vdo_attrs |= _features[i].vdo_feature; - else - log_very_verbose("Target %s does not support %s.", -- TARGET_NAME_VDO, -+ _vdo_module, - _features[i].feature); - } - - if (attributes) { -+ if (!_feature_mask) { -+ /* Support runtime lvm.conf changes, N.B. avoid 32 feature */ -+ if ((cn = find_config_tree_array(cmd, global_vdo_disabled_features_CFG, NULL))) { -+ for (cv = cn->v; cv; cv = cv->next) { -+ if (cv->type != DM_CFG_STRING) { -+ log_warn("WARNING: Ignoring invalid string in config file %s.", -+ _lvmconf); -+ continue; -+ } -+ str = cv->v.str; -+ if (!*str) -+ continue; -+ for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) -+ if (strcasecmp(str, _features[i].feature) == 0) -+ _feature_mask |= _features[i].vdo_feature; -+ } -+ } -+ _feature_mask = ~_feature_mask; -+ for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) -+ if ((_vdo_attrs & _features[i].vdo_feature) && -+ !(_feature_mask & _features[i].vdo_feature)) -+ log_very_verbose("Target %s %s support disabled by %s.", -+ _vdo_module, -+ _features[i].feature, _lvmconf); -+ } - *attributes = _vdo_attrs & _feature_mask; - } - -@@ -456,7 +486,7 @@ static int _vdo_modules_needed(struct dm_pool *mem, - const struct lv_segment *seg __attribute__((unused)), - struct dm_list *modules) - { -- if (!str_list_add(mem, modules, MODULE_NAME_VDO)) { -+ if (!str_list_add(mem, modules, _vdo_module)) { - log_error("String list allocation failed for VDO module."); - return 0; - } diff --git a/lvm2-2_03_12-writecache-use-cleaner-message-instead-of-table-relo.patch b/lvm2-2_03_12-writecache-use-cleaner-message-instead-of-table-relo.patch deleted file mode 100644 index 9f08576..0000000 --- a/lvm2-2_03_12-writecache-use-cleaner-message-instead-of-table-relo.patch +++ /dev/null @@ -1,45 +0,0 @@ - lib/metadata/writecache_manip.c | 10 +++++++--- - tools/lvconvert.c | 2 ++ - 2 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/lib/metadata/writecache_manip.c b/lib/metadata/writecache_manip.c -index 5004aa9..8150d07 100644 ---- a/lib/metadata/writecache_manip.c -+++ b/lib/metadata/writecache_manip.c -@@ -75,7 +75,7 @@ static int _get_writecache_kernel_status(struct cmd_context *cmd, - return 0; - } - -- if (!lv_info_with_seg_status(cmd, first_seg(lv), &status, 1, 1)) { -+ if (!lv_info_with_seg_status(cmd, first_seg(lv), &status, 0, 0)) { - log_error("Failed to get device mapper status for %s", display_lvname(lv)); - goto fail; - } -@@ -434,8 +434,12 @@ int lv_writecache_set_cleaner(struct logical_volume *lv) - seg->writecache_settings.cleaner_set = 1; - - if (lv_is_active(lv)) { -- if (!lv_update_and_reload(lv)) { -- log_error("Failed to update VG and reload LV."); -+ if (!vg_write(lv->vg) || !vg_commit(lv->vg)) { -+ log_error("Failed to update VG."); -+ return 0; -+ } -+ if (!lv_writecache_message(lv, "cleaner")) { -+ log_error("Failed to set writecache cleaner for %s.", display_lvname(lv)); - return 0; - } - } else { -diff --git a/tools/lvconvert.c b/tools/lvconvert.c -index 4323965..7b74afb 100644 ---- a/tools/lvconvert.c -+++ b/tools/lvconvert.c -@@ -5720,6 +5720,8 @@ static int _lvconvert_detach_writecache_when_clean(struct cmd_context *cmd, - return 0; - } - -+ log_debug("detach writecache check clean reading vg %s", id->vg_name); -+ - vg = vg_read(cmd, id->vg_name, NULL, READ_FOR_UPDATE, lockd_state, &error_flags, NULL); - - if (!vg) { diff --git a/lvm2-set-default-preferred_names.patch b/lvm2-set-default-preferred_names.patch deleted file mode 100644 index 95259f4..0000000 --- a/lvm2-set-default-preferred_names.patch +++ /dev/null @@ -1,37 +0,0 @@ - conf/example.conf.in | 7 ++++--- - lib/config/config_settings.h | 2 +- - 2 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/conf/example.conf.in b/conf/example.conf.in -index a5eba01..8fa126b 100644 ---- a/conf/example.conf.in -+++ b/conf/example.conf.in -@@ -118,11 +118,12 @@ devices { - # Prefer the name with the least number of slashes. - # Prefer a name that is a symlink. - # Prefer the path with least value in lexicographical order. -- # -- # Example -+ # -+ # Example: - # preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ] - # -- # This configuration option does not have a default value defined. -+ # This configuration option has an automatic default value. -+ # 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 efa86e7..b3b6c77 100644 ---- a/lib/config/config_settings.h -+++ b/lib/config/config_settings.h -@@ -269,7 +269,7 @@ cfg(devices_hints_CFG, "hints", devices_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_ - " Use no hints.\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/lvm2.spec b/lvm2.spec index 60de829..a4e6feb 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -1,8 +1,6 @@ -%global device_mapper_version 1.02.175 +%global device_mapper_version 1.02.185 %global enable_cache 1 -%global enable_cluster 1 -%global enable_cmirror 1 %global enable_lvmdbusd 1 %global enable_lvmlockd 1 %global enable_lvmpolld 1 @@ -14,7 +12,7 @@ %global enable_integrity 1 %global system_release_version 23 -%global systemd_version 189-3 +%global systemd_version 247-1 %global dracut_version 002-18 %global util_linux_version 2.24 %global bash_version 4.0 @@ -30,8 +28,6 @@ %if 0%{?rhel} && 0%{?rhel} <= 8 %ifnarch i686 x86_64 ppc64le s390x - %global enable_cluster 0 - %global enable_cmirror 0 %global enable_lockd_dlm 0 %endif @@ -48,44 +44,18 @@ Name: lvm2 %if 0%{?rhel} Epoch: %{rhel} %endif -Version: 2.03.11 -Release: 9%{?dist} +Version: 2.03.16 +Release: 1%{?dist} License: GPLv2 URL: https://sourceware.org/lvm2/ Source0: https://sourceware.org/pub/lvm2/releases/LVM2.%{version}.tgz -Patch0: lvm2-set-default-preferred_names.patch -Patch3: lvm2-2_03_12-lvmlockd-sscanf-buffer-size-warnings.patch -# BZ 1915497: -Patch4: lvm2-2_03_12-alloc-enhance-estimation-of-sufficient_pes_free.patch -Patch5: lvm2-2_03_12-tests-check-thin-pool-corner-case-allocs.patch -Patch6: lvm2-2_03_12-tests-check-full-zeroing-of-thin-pool-metadata.patch -# BZ 1915580: -Patch7: lvm2-2_03_12-integrity-fix-segfault-on-error-path-when-replacing-.patch -# BZ 1872695: -Patch8: lvm2-2_03_12-devs-remove-invalid-path-name-aliases.patch -Patch9: lvm2-2_03_12-make-generate.patch -Patch10: lvm2-2_03_12-label_scan-fix-missing-free-of-filtered_devs.patch -# BZ 1917920: -Patch11: lvm2-2_03_12-pvck-fix-warning-and-exit-code-for-non-4k-mda1-offse.patch -Patch12: lvm2-2_03_12-WHATS_NEW-update.patch -# BZ 1921214: -Patch13: lvm2-2_03_12-writecache-use-cleaner-message-instead-of-table-relo.patch -# BZ 1909699: -Patch14: lvm2-2_03_12-man-update-lvmthin.patch -Patch15: lvm2-2_03_12-thin-improve-16g-support-for-thin-pool-metadata.patch -Patch16: lvm2-2_03_12-pool-limit-pmspare-to-16GiB.patch -Patch17: lvm2-2_03_12-cache-reuse-code-for-metadata-min_max.patch -Patch18: lvm2-2_03_12-tests-check-16G-thin-pool-metadata-size.patch -Patch19: lvm2-2_03_12-tests-update-thin-and-cache-checked-messages.patch -# BZ 1914389: -Patch20: lvm2-2_03_12-lvcreate-use-lv_passes_readonly_filter.patch -Patch21: lvm2-2_03_12-test-check-read_only_volume_list-tagging-works.patch -# BZ 1859659: -Patch22: lvm2-2_03_12-filter-mpath-work-with-nvme-devices.patch -# BZ 1925871: -Patch23: lvm2-2_03_12-dev_get_primary_dev-fix-invalid-path-check.patch -# Fix editline compilation: -Patch24: lvm2-2_03_12-lvm-Fix-editline-compilation.patch +Patch1: 0001-devices-file-move-clean-up-after-command-is-run.patch +Patch2: 0002-devices-file-fail-if-devicesfile-filename-doesn-t-ex.patch +Patch3: 0003-filter-mpath-handle-other-wwid-types-in-blacklist.patch +Patch4: 0004-filter-mpath-get-wwids-from-sysfs-vpd_pg83.patch +Patch5: 0005-pvdisplay-restore-reportformat-option.patch +Patch6: 0006-exit-with-error-when-devicesfile-name-doesn-t-exist.patch +Patch7: 0007-make-generate.patch BuildRequires: make BuildRequires: gcc @@ -97,10 +67,7 @@ BuildRequires: libblkid-devel >= %{util_linux_version} BuildRequires: ncurses-devel BuildRequires: libedit-devel BuildRequires: libaio-devel -%if %{enable_cluster} -BuildRequires: corosynclib-devel >= %{corosync_version} -%endif -%if %{enable_cluster} || %{enable_lockd_dlm} +%if %{enable_lockd_dlm} BuildRequires: dlm-devel >= %{dlm_version} %endif BuildRequires: module-init-tools @@ -142,29 +109,13 @@ or more physical volumes and creating one or more logical volumes %prep %setup -q -n LVM2.%{version} -%patch0 -p1 -b .backup0 +%patch1 -p1 -b .backup1 +%patch2 -p1 -b .backup2 %patch3 -p1 -b .backup3 %patch4 -p1 -b .backup4 %patch5 -p1 -b .backup5 %patch6 -p1 -b .backup6 %patch7 -p1 -b .backup7 -%patch8 -p1 -b .backup8 -%patch9 -p1 -b .backup9 -%patch10 -p1 -b .backup10 -%patch11 -p1 -b .backup11 -%patch12 -p1 -b .backup12 -%patch13 -p1 -b .backup13 -%patch14 -p1 -b .backup14 -%patch15 -p1 -b .backup15 -%patch16 -p1 -b .backup16 -%patch17 -p1 -b .backup17 -%patch18 -p1 -b .backup18 -%patch19 -p1 -b .backup19 -%patch20 -p1 -b .backup20 -%patch21 -p1 -b .backup21 -%patch22 -p1 -b .backup22 -%patch23 -p1 -b .backup23 -%patch24 -p1 -b .backup24 %build %global _default_pid_dir /run @@ -191,16 +142,6 @@ or more physical volumes and creating one or more logical volumes --enable-cmdlib \ --enable-dmeventd \ --enable-blkid_wiping \ - --disable-readline \ - --enable-editline \ -%if %{enable_cluster} - --with-cluster=internal \ - %if %{enable_cmirror} - --enable-cmirrord \ - %endif -%else - --with-cluster=internal \ -%endif --with-udevdir=%{_udevdir} --enable-udev_sync \ %if %{enable_thin} --with-thin=internal \ @@ -232,7 +173,11 @@ or more physical volumes and creating one or more logical volumes %if %{enable_integrity} --with-integrity=internal \ %endif - --disable-silent-rules + --with-default-use-devices-file=1 \ + --disable-silent-rules \ + --enable-app-machineid \ + --enable-editline \ + --disable-readline %make_build @@ -293,10 +238,12 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_sbindir}/fsadm %{_sbindir}/lvm %{_sbindir}/lvmconfig +%{_sbindir}/lvmdevices %{_sbindir}/lvmdump %if %{enable_lvmpolld} %{_sbindir}/lvmpolld %endif +%{_sbindir}/lvm_import_vdo # Other files %{_sbindir}/lvchange @@ -333,6 +280,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_sbindir}/vgextend %{_sbindir}/vgimport %{_sbindir}/vgimportclone +%{_sbindir}/vgimportdevices %{_sbindir}/vgmerge %{_sbindir}/vgmknodes %{_sbindir}/vgreduce @@ -342,6 +290,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_sbindir}/vgscan %{_sbindir}/vgsplit %{_mandir}/man5/lvm.conf.5.gz +%{_mandir}/man7/lvmautoactivation.7.gz %{_mandir}/man7/lvmcache.7.gz %{_mandir}/man7/lvmraid.7.gz %{_mandir}/man7/lvmreport.7.gz @@ -355,9 +304,9 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_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/lvmdevices.8.gz %{_mandir}/man8/lvm-dumpconfig.8.gz %{_mandir}/man8/lvmdiskscan.8.gz %{_mandir}/man8/lvmdump.8.gz @@ -379,6 +328,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_mandir}/man8/pvresize.8.gz %{_mandir}/man8/pvs.8.gz %{_mandir}/man8/pvscan.8.gz +%{_mandir}/man8/lvm_import_vdo.8.gz %{_mandir}/man8/vgcfgbackup.8.gz %{_mandir}/man8/vgcfgrestore.8.gz %{_mandir}/man8/vgchange.8.gz @@ -390,6 +340,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_mandir}/man8/vgextend.8.gz %{_mandir}/man8/vgimport.8.gz %{_mandir}/man8/vgimportclone.8.gz +%{_mandir}/man8/vgimportdevices.8.gz %{_mandir}/man8/vgmerge.8.gz %{_mandir}/man8/vgmknodes.8.gz %{_mandir}/man8/vgreduce.8.gz @@ -399,7 +350,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_mandir}/man8/vgscan.8.gz %{_mandir}/man8/vgsplit.8.gz %{_udevdir}/11-dm-lvm.rules -%{_udevdir}/69-dm-lvm-metad.rules +%{_udevdir}/69-dm-lvm.rules %if %{enable_lvmpolld} %{_mandir}/man8/lvmpolld.8.gz %{_mandir}/man8/lvm-lvpoll.8.gz @@ -427,8 +378,7 @@ systemctl start lvm2-lvmpolld.socket >/dev/null 2>&1 || : %{_tmpfilesdir}/%{name}.conf %{_unitdir}/blk-availability.service %{_unitdir}/lvm2-monitor.service -%{_unitdir}/lvm2-pvscan@.service -%{_prefix}/lib/systemd/system-generators/lvm2-activation-generator +#%%{_unitdir}/lvm-vgchange@.service # vgchange is now part of udev rule %if %{enable_lvmpolld} %{_unitdir}/lvm2-lvmpolld.socket %{_unitdir}/lvm2-lvmpolld.service @@ -524,55 +474,6 @@ LVM commands use lvmlockd to coordinate access to shared storage. %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 -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 -%{_sbindir}/cmirrord -%{_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 -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 -%{_unitdir}/lvm2-cmirrord.service - -%endif -%endif - ############################################################################## # LVM D-Bus daemon ############################################################################## @@ -766,6 +667,18 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Mon Sep 26 2022 Marian Csontos - 2.03.16-1 +- Update to upstream version 2.03.16. +- Devices file feature - see lvmdevices(8). +- Changes in udev support: + - obtain_device_list_from_udev defaults to 0. + - see devices/external_device_info_source, + devices/obtain_device_list_from_udev, and devices/multipath_wwids_file help + in lvm.conf +- Remove service based autoactivation. global/event_activation = 0 is NOOP. + - see lvmautoactivation(7). +- Many fixes and improvements, see WHATS_NEW and WHATS_NEW_DM for more. + * Thu Jul 21 2022 Fedora Release Engineering - 2.03.11-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild