diff --git a/0017-device_id-nvme-devices-may-use-alternate-wwids.patch b/0017-device_id-nvme-devices-may-use-alternate-wwids.patch new file mode 100644 index 0000000..995e6e0 --- /dev/null +++ b/0017-device_id-nvme-devices-may-use-alternate-wwids.patch @@ -0,0 +1,805 @@ +From 5f10e49c729eb6b723891426ceec59af2fe66c09 Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Fri, 6 Dec 2024 15:02:20 -0600 +Subject: [PATCH 1/3] device_id: nvme devices may use alternate wwids + +Device quirks may cause sysfs wwid file to change what it +displays, from a bogus eui... string to an nvme... string. + +The old wwid may be saved in system.devices, so recognizing +the device requires finding the old value from libnvme. + +After matching the old bogus value using libnvme, system.devices +is updated with the current sysfs wwid value. + +(cherry picked from commit d952358636887348c390784a8ca5efb87b26784f) +--- + lib/Makefile.in | 1 + + lib/device/dev-mpath.c | 6 +- + lib/device/dev-type.c | 6 +- + lib/device/dev-type.h | 2 +- + lib/device/device.h | 16 ++- + lib/device/device_id.c | 174 +++++++++++++++++++++++--- + lib/device/device_id.h | 11 +- + lib/device/nvme.c | 273 +++++++++++++++++++++++++++++++++++++++++ + lib/device/parse_vpd.c | 8 +- + 9 files changed, 464 insertions(+), 33 deletions(-) + create mode 100644 lib/device/nvme.c + +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 50c7a1fd2..8eab625aa 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -43,6 +43,7 @@ SOURCES =\ + device/filesystem.c \ + device/online.c \ + device/parse_vpd.c \ ++ device/nvme.c \ + device/dev_util.c \ + display/display.c \ + error/errseg.c \ +diff --git a/lib/device/dev-mpath.c b/lib/device/dev-mpath.c +index 72501e345..7450244b0 100644 +--- a/lib/device/dev-mpath.c ++++ b/lib/device/dev-mpath.c +@@ -595,7 +595,7 @@ static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev, + */ + lookup: + dm_list_iterate_items(dw, &dev->wwids) { +- if (dw->type == 1 || dw->type == 2 || dw->type == 3) ++ if (dw->scsi_type == 1 || dw->scsi_type == 2 || dw->scsi_type == 3) + wwid = &dw->id[4]; + else + wwid = dw->id; +@@ -615,7 +615,7 @@ lookup: + goto lookup; + + if (!(dev->flags & DEV_ADDED_SYS_WWID) && dev_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf), &dw)) { +- if (dw->type == 1 || dw->type == 2 || dw->type == 3) ++ if (dw->scsi_type == 1 || dw->scsi_type == 2 || dw->scsi_type == 3) + wwid = &dw->id[4]; + else + wwid = dw->id; +@@ -642,7 +642,7 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *h + /* + * multipath only uses SCSI or NVME devices + */ +- if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev)) ++ if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dev)) + return 0; + + /* +diff --git a/lib/device/dev-type.c b/lib/device/dev-type.c +index c29fb21a8..7c6c10e01 100644 +--- a/lib/device/dev-type.c ++++ b/lib/device/dev-type.c +@@ -46,7 +46,7 @@ + * is excessive and unnecessary compared to just comparing /dev/name*. + */ + +-int dev_is_nvme(struct dev_types *dt, struct device *dev) ++int dev_is_nvme(struct device *dev) + { + return (dev->flags & DEV_IS_NVME) ? 1 : 0; + } +@@ -562,7 +562,7 @@ 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 (dev_is_nvme(dev)) { + /* If this dev is already a partition then it's not partitionable. */ + if (_has_sys_partition(dev)) + return 0; +@@ -790,7 +790,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result) + * 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)) ++ if (dev_is_nvme(dev)) + goto sys_partition; + + /* +diff --git a/lib/device/dev-type.h b/lib/device/dev-type.h +index 60e5789f7..4708dd3e2 100644 +--- a/lib/device/dev-type.h ++++ b/lib/device/dev-type.h +@@ -98,7 +98,7 @@ int dev_is_rotational(struct dev_types *dt, struct device *dev); + + int dev_is_pmem(struct dev_types *dt, struct device *dev); + +-int dev_is_nvme(struct dev_types *dt, struct device *dev); ++int dev_is_nvme(struct device *dev); + + int dev_is_lv(struct cmd_context *cmd, struct device *dev); + +diff --git a/lib/device/device.h b/lib/device/device.h +index af5e8a934..d5979e90b 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -41,6 +41,8 @@ + #define DEV_MATCHED_USE_ID 0x00080000 /* matched an entry from cmd->use_devices */ + #define DEV_SCAN_FOUND_NOLABEL 0x00100000 /* label_scan read, passed filters, but no lvm label */ + #define DEV_SCAN_NOT_READ 0x00200000 /* label_scan not able to read dev */ ++#define DEV_ADDED_NVME_WWIDS 0x00400000 /* wwids have been ready from libnvme */ ++#define DEV_UPDATE_USE_ID 0x00800000 /* update system.devices entry to use preferred wwid */ + + /* + * Support for external device info. +@@ -70,8 +72,12 @@ struct dev_ext { + #define DEV_ID_TYPE_WWID_NAA 9 + #define DEV_ID_TYPE_WWID_EUI 10 + #define DEV_ID_TYPE_WWID_T10 11 ++/* reserve 12 for "scsi name string" if we decide to add that */ ++#define DEV_ID_TYPE_NVME_EUI64 13 ++#define DEV_ID_TYPE_NVME_NGUID 14 ++#define DEV_ID_TYPE_NVME_UUID 15 + +-/* Max length of WWID_NAA, WWID_EUI, WWID_T10 */ ++/* Max length of SCSI or NVME WWID */ + #define DEV_WWID_SIZE 128 + + /* +@@ -79,12 +85,14 @@ struct dev_ext { + * /sys/dev/block/%d:%d/device/wwid + * /sys/dev/block/%d:%d/wwid + * /sys/dev/block/%d:%d/device/vpd_pg83 ++ * or libnvme + */ + + struct dev_wwid { +- struct dm_list list; /* dev->wwids */ +- int type; /* 1,2,3 for NAA,EUI,T10 */ +- char id[DEV_WWID_SIZE]; /* includes prefix naa.,eui.,t10. */ ++ struct dm_list list; /* dev->wwids */ ++ uint16_t scsi_type; /* 1,2,3 for SCSI NAA,EUI,T10 */ ++ uint16_t nvme_type; /* 1,2,3 for NVME EUI64,NGUID,UUID */ ++ char id[DEV_WWID_SIZE]; /* includes prefix e.g. naa.,eui.,t10. */ + }; + + /* +diff --git a/lib/device/device_id.c b/lib/device/device_id.c +index 06788db32..34524f718 100644 +--- a/lib/device/device_id.c ++++ b/lib/device/device_id.c +@@ -568,7 +568,7 @@ static int _dev_has_lvmlv_uuid(struct cmd_context *cmd, struct device *dev, char + * The numbers 1,2,3 for NAA,EUI,T10 are part of the standard + * and are used in the vpd data. + */ +-static int _wwid_type_num(char *id) ++static int _scsi_wwid_type_num(char *id) + { + if (!strncmp(id, "naa.", 4)) + return 3; +@@ -580,9 +580,9 @@ static int _wwid_type_num(char *id) + return 0; /* any unrecognized, non-standard prefix */ + } + +-int wwid_type_to_idtype(int wwid_type) ++int scsi_type_to_idtype(int scsi_type) + { +- switch (wwid_type) { ++ switch (scsi_type) { + case 3: return DEV_ID_TYPE_WWID_NAA; + case 2: return DEV_ID_TYPE_WWID_EUI; + case 1: return DEV_ID_TYPE_WWID_T10; +@@ -591,7 +591,7 @@ int wwid_type_to_idtype(int wwid_type) + } + } + +-int idtype_to_wwid_type(int idtype) ++int idtype_to_scsi_type(int idtype) + { + switch (idtype) { + case DEV_ID_TYPE_WWID_NAA: return 3; +@@ -602,6 +602,45 @@ int idtype_to_wwid_type(int idtype) + } + } + ++/* ++ * libnvme only returns the standard identifiers UUID/NGUID/EUI64 ++ * sysfs wwid file will return "nvme." identifier when one of the ++ * others is not available. ++ */ ++static int _nvme_wwid_type_num(char *id) ++{ ++ if (!strncmp(id, "uuid.", 5)) ++ return 3; /* UUID is 16 bytes */ ++ else if (!strncmp(id, "eui.", 4)) { ++ if (strlen(id) > 15) ++ return 2; /* NGUID is 16 bytes */ ++ return 1; /* EUI64 is 8 bytes */ ++ } ++ return 0; /* any other prefix, including "nvme.", which must come from sysfs wwid file */ ++} ++ ++int nvme_type_to_idtype(int nvme_type) ++{ ++ switch (nvme_type) { ++ case 3: return DEV_ID_TYPE_NVME_UUID; ++ case 2: return DEV_ID_TYPE_NVME_NGUID; ++ case 1: return DEV_ID_TYPE_NVME_EUI64; ++ case 0: return DEV_ID_TYPE_SYS_WWID; ++ default: return -1; ++ } ++} ++ ++int idtype_to_nvme_type(int idtype) ++{ ++ switch (idtype) { ++ case DEV_ID_TYPE_NVME_UUID: return 3; ++ case DEV_ID_TYPE_NVME_NGUID: return 2; ++ case DEV_ID_TYPE_NVME_EUI64: return 1; ++ case DEV_ID_TYPE_SYS_WWID: return 0; ++ default: return -1; ++ } ++} ++ + void free_wwids(struct dm_list *ids) + { + struct dev_wwid *dw, *safe; +@@ -620,22 +659,41 @@ void free_wwids(struct dm_list *ids) + * in /etc/multipath/wwids. + */ + +-struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids) ++struct dev_wwid *dev_add_wwid(char *id, int dw_type, int is_nvme, struct dm_list *ids) + { + struct dev_wwid *dw; ++ uint16_t scsi_type = 0; ++ uint16_t nvme_type = 0; ++ ++ if (is_nvme) ++ nvme_type = dw_type ?: _nvme_wwid_type_num(id); ++ else ++ scsi_type = dw_type ?: _scsi_wwid_type_num(id); + +- if (!id_type) +- id_type = _wwid_type_num(id); ++ /* nvme_type/scsi_type will be 0 for any sysfs wwid string that ++ doesn't begin with a prefix recognized by lvm, e.g. that ++ comes from sysfs wwid. */ + + if (!(dw = zalloc(sizeof(*dw)))) + return_NULL; + /* Copy id string with upto DEV_WWID_SIZE characters */ + dm_strncpy(dw->id, id, sizeof(dw->id)); +- dw->type = id_type; ++ dw->scsi_type = scsi_type; ++ dw->nvme_type = nvme_type; + dm_list_add(ids, &dw->list); + return dw; + } + ++struct dev_wwid *dev_add_scsi_wwid(char *id, int dw_type, struct dm_list *ids) ++{ ++ return dev_add_wwid(id, dw_type, 0, ids); ++} ++ ++struct dev_wwid *dev_add_nvme_wwid(char *id, int dw_type, struct dm_list *ids) ++{ ++ return dev_add_wwid(id, dw_type, 1, ids); ++} ++ + #define VPD_SIZE 4096 + + int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev) +@@ -693,9 +751,13 @@ int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev, + else + format_general_id((const char *)buf, sizeof(buf), (unsigned char *)outbuf, outbufsize); + ++ /* We don't currently add the sysfs wwid to dev->wwids for nvme, it's not needed. */ ++ if (dev_is_nvme(dev)) ++ return 1; ++ + /* Note, if wwids are also read from vpd, this same wwid will be added again. */ + +- if (!(dw = dev_add_wwid(buf, 0, &dev->wwids))) ++ if (!(dw = dev_add_wwid(buf, 0, dev_is_nvme(dev), &dev->wwids))) + return_0; + if (dw_out) + *dw_out = dw; +@@ -809,7 +871,17 @@ char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_ + if (!(dev->flags & DEV_ADDED_VPD_WWIDS)) + dev_read_vpd_wwids(cmd, dev); + dm_list_iterate_items(dw, &dev->wwids) { +- if (idtype_to_wwid_type(idtype) == dw->type) ++ if (idtype_to_scsi_type(idtype) == dw->scsi_type) ++ return strdup(dw->id); ++ } ++ return NULL; ++ case DEV_ID_TYPE_NVME_EUI64: ++ case DEV_ID_TYPE_NVME_NGUID: ++ case DEV_ID_TYPE_NVME_UUID: ++ if (!(dev->flags & DEV_ADDED_NVME_WWIDS)) ++ dev_read_nvme_wwids(dev); ++ dm_list_iterate_items(dw, &dev->wwids) { ++ if (idtype_to_nvme_type(idtype) == dw->nvme_type) + return strdup(dw->id); + } + return NULL; +@@ -823,6 +895,9 @@ char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_ + */ + if ((idtype != DEV_ID_TYPE_SYS_WWID) && + (idtype != DEV_ID_TYPE_SYS_SERIAL) && ++ (idtype != DEV_ID_TYPE_NVME_EUI64) && ++ (idtype != DEV_ID_TYPE_NVME_NGUID) && ++ (idtype != DEV_ID_TYPE_NVME_UUID) && + (idtype != DEV_ID_TYPE_WWID_NAA) && + (idtype != DEV_ID_TYPE_WWID_EUI) && + (idtype != DEV_ID_TYPE_WWID_T10)) { +@@ -1043,6 +1118,9 @@ static const char _dev_id_types[][16] = { + [DEV_ID_TYPE_WWID_NAA] = "wwid_naa", + [DEV_ID_TYPE_WWID_EUI] = "wwid_eui", + [DEV_ID_TYPE_WWID_T10] = "wwid_t10", ++ [DEV_ID_TYPE_NVME_EUI64] = "nvme_eui64", ++ [DEV_ID_TYPE_NVME_NGUID] = "nvme_nguid", ++ [DEV_ID_TYPE_NVME_UUID] = "nvme_uuid", + }; + + static int _is_idtype(uint16_t idtype) { +@@ -1107,6 +1185,17 @@ static const char *_dev_idname(struct device *dev, uint16_t idtype) + return NULL; + } + ++static struct dev_id *get_dev_id(struct device *dev, uint16_t idtype) ++{ ++ struct dev_id *id; ++ ++ dm_list_iterate_items(id, &dev->ids) { ++ if (id->idtype == idtype) ++ return id; ++ } ++ return NULL; ++} ++ + static int _dev_has_id(struct device *dev, uint16_t idtype, const char *idname) + { + struct dev_id *id; +@@ -2564,33 +2653,63 @@ static int _match_du_to_dev(struct cmd_context *cmd, struct dev_use *du, struct + */ + + /* ++ * SCSI: + * Make the du match this device if the dev has a vpd_pg83 wwid + * that matches du->idname, even if the sysfs wwid for dev did + * not match the du->idname. This could happen if sysfs changes + * which wwid it reports (there are often multiple), or if lvm in + * the future selects a sys_wwid value from vpd_pg83 data rather + * than from the sysfs wwid. +- * + * TODO: update the df entry IDTYPE somewhere? ++ * ++ * NVME: ++ * For some nvme drives (faulty hw, flagged with quirk), the sysfs wwid ++ * file changed to reporting a new/correct wwid. The du->idname may ++ * still have the wwid from the old sysfs wwid, so we need to look ++ * at the old wwids that can be found from libnvme. ++ * ++ * device_ids_validate updates system.devices to use the latest value ++ * from sysfs wwid. ++ * ++ * In future, we could limit dev_read_nvme_wwids() to only devices ++ * that have the quirk flag (indicating a bad wwid had been used.) ++ * dev_has_nvme_quirk() checks a flag in a newly exposed sysfs file. ++ * If that sysfs file doesn't exist because of an older kernel, then ++ * the function returns -1. When the quirk file exists and says 0, ++ * then the device hasn't changed its reported sys_wwid value, and ++ * we don't need to check libnvme for other wwids that the dev ++ * might have displayed in the past. + */ + if (du->idtype == DEV_ID_TYPE_SYS_WWID) { + struct dev_wwid *dw; + +- if (!(dev->flags & DEV_ADDED_VPD_WWIDS)) ++ if (!(dev->flags & DEV_ADDED_VPD_WWIDS) && !dev_is_nvme(dev)) + dev_read_vpd_wwids(cmd, dev); + ++ if (!(dev->flags & DEV_ADDED_NVME_WWIDS) && dev_is_nvme(dev)) ++ dev_read_nvme_wwids(dev); ++ + dm_list_iterate_items(dw, &dev->wwids) { + if (!strcmp(dw->id, du_idname)) { + if (!(id = zalloc(sizeof(struct dev_id)))) + return_0; +- /* wwid types are 1,2,3 and idtypes are DEV_ID_TYPE_ */ +- id->idtype = wwid_type_to_idtype(dw->type); ++ /* scsi/nvme types are 1,2,3 and idtypes are DEV_ID_TYPE_ */ ++ if (dev_is_nvme(dev)) ++ id->idtype = nvme_type_to_idtype(dw->nvme_type); ++ else ++ id->idtype = scsi_type_to_idtype(dw->scsi_type); + id->idname = strdup(dw->id); + dm_list_add(&dev->ids, &id->list); + du->dev = dev; + dev->id = id; + dev->flags |= DEV_MATCHED_USE_ID; +- log_debug("Match %s %s to %s: using vpd_pg83 %s %s", ++ ++ /* update system.devices with sysfs wwid value since IDTYPE=sys_wwid */ ++ /* FIXME: also do this for scsi */ ++ if (dev_is_nvme(dev)) ++ dev->flags |= DEV_UPDATE_USE_ID; ++ ++ log_debug("Match %s %s to %s: using extra %s %s", + idtype_to_str(du->idtype), du_idname, dev_name(dev), + idtype_to_str(id->idtype), id->idname ?: "."); + du->idtype = id->idtype; +@@ -2939,6 +3058,31 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, + du->dev ? dev_name(du->dev) : "not set"); + } + ++ /* ++ * Replace old wwid with new value displayed by sysfs wwid. ++ */ ++ dm_list_iterate_items(du, &cmd->use_devices) { ++ if (!du->dev) ++ continue; ++ if (!(du->dev->flags & DEV_UPDATE_USE_ID)) ++ continue; ++ if ((id = get_dev_id(du->dev, DEV_ID_TYPE_SYS_WWID)) && id->idname) { ++ log_debug("Validate %s %s PVID %s on %s: replace old wwid with %s", ++ idtype_to_str(du->idtype), du->idname ?: ".", du->pvid ?: ".", ++ dev_name(du->dev), id->idname); ++ if (!(tmpdup = strdup(id->idname))) ++ continue; ++ free(du->idname); ++ du->idtype = DEV_ID_TYPE_SYS_WWID; ++ du->idname = tmpdup; ++ du->dev->id = id; ++ update_file = 1; ++ } else { ++ log_warn("Device %s PVID %s is using only old wwid %s.", ++ dev_name(du->dev), du->pvid ?: ".", du->idname ?: "."); ++ } ++ } ++ + /* + * Validate entries with proper device id types. + * idname is the authority for pairing du and dev. +diff --git a/lib/device/device_id.h b/lib/device/device_id.h +index a67774f1b..b10df9bf4 100644 +--- a/lib/device/device_id.h ++++ b/lib/device/device_id.h +@@ -69,11 +69,16 @@ int read_sys_block_binary(struct cmd_context *cmd, struct device *dev, + + int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, char **idname_out); + +-int wwid_type_to_idtype(int wwid_type); +-int idtype_to_wwid_type(int idtype); ++int scsi_type_to_idtype(int wwid_type); ++int nvme_type_to_idtype(int wwid_type); ++int idtype_to_scsi_type(int idtype); ++int idtype_to_nvme_type(int idtype); + void free_wwids(struct dm_list *ids); +-struct dev_wwid *dev_add_wwid(char *id, int id_type, struct dm_list *ids); ++struct dev_wwid *dev_add_wwid(char *id, int dw_type, int is_nvme, struct dm_list *ids); ++struct dev_wwid *dev_add_scsi_wwid(char *id, int dw_type, struct dm_list *ids); ++struct dev_wwid *dev_add_nvme_wwid(char *id, int dw_type, struct dm_list *ids); + int dev_read_vpd_wwids(struct cmd_context *cmd, struct device *dev); ++void dev_read_nvme_wwids(struct device *dev); + int dev_read_sys_wwid(struct cmd_context *cmd, struct device *dev, + char *buf, int bufsize, struct dev_wwid **dw_out); + +diff --git a/lib/device/nvme.c b/lib/device/nvme.c +new file mode 100644 +index 000000000..aa4a7a947 +--- /dev/null ++++ b/lib/device/nvme.c +@@ -0,0 +1,273 @@ ++/* ++ * Copyright (C) 2024 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/commands/toolcontext.h" ++#include "lib/device/device.h" ++#include "lib/device/device_id.h" ++#include "lib/mm/xlate.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef NVME_SUPPORT ++#include ++ ++static int iszero(unsigned char *d, size_t n) ++{ ++ size_t i; ++ ++ for (i = 0; i < n; ++i) { ++ if (d[i]) ++ return 0; ++ } ++ return 1; ++} ++ ++static void _save_uuid(struct device *dev, unsigned char *uuid) ++{ ++ char idname[DEV_WWID_SIZE] = {0}; ++ int max, pos, num, i; ++ ++ max = sizeof(idname); ++ pos = 0; ++ ++ num = snprintf(idname + pos, max - pos, "uuid."); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ ++ for (i = 0; i < NVME_UUID_LEN; ++i) { ++ num = snprintf(idname + pos, max - pos, "%02x", uuid[i]); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ ++ if (i == 3 || i == 5 || i == 7 || i == 9) { ++ num = snprintf(idname + pos, max - pos, "-"); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ } ++ } ++ ++ idname[DEV_WWID_SIZE-1] = '\0'; ++ ++ dev_add_nvme_wwid(idname, 3, &dev->wwids); ++ ++ return; ++bad: ++ log_debug("dev_read_nvme_wwids ignore invalid uuid %s for %s", uuid, dev_name(dev)); ++} ++ ++static void _save_nguid(struct device *dev, unsigned char *nguid) ++{ ++ char idname[DEV_WWID_SIZE] = {0}; ++ int max, pos, num, i; ++ ++ max = sizeof(idname); ++ pos = 0; ++ ++ num = snprintf(idname + pos, max - pos, "eui."); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ ++ for (i = 0; i < 16; ++i) { ++ num = snprintf(idname + pos, max - pos, "%02x", nguid[i]); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ } ++ ++ idname[DEV_WWID_SIZE-1] = '\0'; ++ ++ dev_add_nvme_wwid(idname, 2, &dev->wwids); ++ ++ return; ++bad: ++ log_debug("dev_read_nvme_wwids ignore invalid nguid %s for %s", nguid, dev_name(dev)); ++} ++ ++static void _save_eui64(struct device *dev, unsigned char *eui64) ++{ ++ char idname[DEV_WWID_SIZE] = {0}; ++ int max, pos, num, i; ++ ++ max = sizeof(idname); ++ pos = 0; ++ ++ num = snprintf(idname + pos, max - pos, "eui."); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ ++ for (i = 0; i < 8; ++i) { ++ num = snprintf(idname + pos, max - pos, "%02x", eui64[i]); ++ if (num >= max - pos) ++ goto bad; ++ pos += num; ++ } ++ ++ idname[DEV_WWID_SIZE-1] = '\0'; ++ ++ dev_add_nvme_wwid(idname, 1, &dev->wwids); ++ ++ return; ++bad: ++ log_debug("dev_read_nvme_wwids ignore invalid eui64 %s for %s", eui64, dev_name(dev)); ++} ++ ++#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) ++static void *_nvme_alloc(size_t len) ++{ ++ size_t _len = ROUND_UP(len, 0x1000); ++ void *p; ++ ++ if (posix_memalign((void *)&p, getpagesize(), _len)) ++ return NULL; ++ ++ memset(p, 0, _len); ++ return p; ++} ++ ++void dev_read_nvme_wwids(struct device *dev) ++{ ++ const char *devpath; ++ unsigned char *data = NULL; ++ struct nvme_id_ns *ns = NULL; ++ struct nvme_id_ctrl *ctrl_id = NULL; ++ unsigned char nguid[16] = {0}; ++ unsigned char eui64[8] = {0}; ++ unsigned char uuid[NVME_UUID_LEN] = {0}; ++ uint32_t nsid; ++ int fd, i, len; ++ ++ dev->flags |= DEV_ADDED_NVME_WWIDS; ++ ++ /* shouldn't happen */ ++ if (dm_list_empty(&dev->aliases)) ++ return; ++ ++ devpath = dev_name(dev); ++ ++ if ((fd = open(devpath, O_RDONLY)) < 0) { ++ log_debug("dev_read_nvme_wwids cannot open %s", devpath); ++ return; ++ } ++ ++ if (nvme_get_nsid(fd, &nsid)) { ++ log_print("dev_read_nvme_wwids nvme_get_nsid error %d %s", errno, devpath); ++ goto out; ++ } ++ ++ if (!(ns = _nvme_alloc(sizeof(*ns)))) ++ goto_out; ++ ++ if (nvme_identify_ns(fd, nsid, ns)) { ++ log_debug("dev_read_nvme_wwids nvme_identify_ns error %d %s", errno, devpath); ++ goto out; ++ } ++ ++ memcpy(nguid, ns->nguid, 16); ++ memcpy(eui64, ns->eui64, 8); ++ ++ if (!iszero(nguid, 16)) ++ _save_nguid(dev, nguid); ++ if (!iszero(eui64, 8)) ++ _save_eui64(dev, eui64); ++ ++ if (!(ctrl_id = _nvme_alloc(sizeof(struct nvme_id_ctrl)))) ++ goto_out; ++ ++ /* Avoid using nvme_identify_ns_descs before ver 1.3. */ ++ if (!nvme_identify_ctrl(fd, ctrl_id)) { ++ if (le32_to_cpu(ctrl_id->ver) < 0x10300) ++ goto_out; ++ } ++ ++ if (!(data = _nvme_alloc(NVME_IDENTIFY_DATA_SIZE))) ++ goto_out; ++ ++ if (nvme_identify_ns_descs(fd, nsid, (struct nvme_ns_id_desc *)data)) { ++ log_debug("dev_read_nvme_wwids nvme_identify_ns_descs error %d %s", errno, devpath); ++ goto out; ++ } ++ ++ for (i = 0; i < NVME_IDENTIFY_DATA_SIZE; i += len) { ++ struct nvme_ns_id_desc *cur = (struct nvme_ns_id_desc *)(data + i); ++ ++ if (cur->nidl == 0) ++ break; ++ ++ memset(eui64, 0, sizeof(eui64)); ++ memset(nguid, 0, sizeof(nguid)); ++ memset(uuid, 0, sizeof(uuid)); ++ ++ switch (cur->nidt) { ++ case NVME_NIDT_EUI64: ++ memcpy(eui64, data + i + sizeof(*cur), sizeof(eui64)); ++ len = sizeof(eui64); ++ break; ++ case NVME_NIDT_NGUID: ++ memcpy(nguid, data + i + sizeof(*cur), sizeof(nguid)); ++ len = sizeof(nguid); ++ break; ++ case NVME_NIDT_UUID: ++ memcpy(uuid, data + i + sizeof(*cur), NVME_UUID_LEN); ++ len = sizeof(uuid); ++ break; ++ case NVME_NIDT_CSI: ++ len = 1; ++ break; ++ default: ++ len = cur->nidl; ++ break; ++ } ++ ++ len += sizeof(*cur); ++ ++ if (!iszero(uuid, NVME_UUID_LEN)) ++ _save_uuid(dev, uuid); ++ else if (!iszero(nguid, 16)) ++ _save_nguid(dev, nguid); ++ else if (!iszero(eui64, 8)) ++ _save_eui64(dev, eui64); ++ } ++out: ++ free(ctrl_id); ++ free(ns); ++ free(data); ++ close(fd); ++} ++#else ++void dev_read_nvme_wwids(struct device *dev) ++{ ++} ++#endif +diff --git a/lib/device/parse_vpd.c b/lib/device/parse_vpd.c +index 968fd1f9c..16a653a14 100644 +--- a/lib/device/parse_vpd.c ++++ b/lib/device/parse_vpd.c +@@ -177,7 +177,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list + break; + if (id_size >= ID_BUFSIZE) + id_size = ID_BUFSIZE - 1; +- dev_add_wwid(id, 1, ids); ++ dev_add_scsi_wwid(id, 1, ids); + break; + case 0x2: + /* EUI-64 */ +@@ -203,7 +203,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list + break; + if (id_size >= ID_BUFSIZE) + id_size = ID_BUFSIZE - 1; +- dev_add_wwid(id, 2, ids); ++ dev_add_scsi_wwid(id, 2, ids); + break; + case 0x3: + /* NAA */ +@@ -225,7 +225,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list + break; + if (id_size >= ID_BUFSIZE) + id_size = ID_BUFSIZE - 1; +- dev_add_wwid(id, 3, ids); ++ dev_add_scsi_wwid(id, 3, ids); + break; + case 0x8: + /* SCSI name string */ +@@ -257,7 +257,7 @@ int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list + for (i = 0; i < strlen(id); i++) + id[i] = tolower(id[i]); + } +- dev_add_wwid(id, type, ids); ++ dev_add_scsi_wwid(id, type, ids); + break; + default: + break; +-- +2.47.1 + diff --git a/0018-configure.ac-add-support-for-libnvme.patch b/0018-configure.ac-add-support-for-libnvme.patch new file mode 100644 index 0000000..d1d0005 --- /dev/null +++ b/0018-configure.ac-add-support-for-libnvme.patch @@ -0,0 +1,121 @@ +From b2cec1fc0e879f5a7c7808c54e6eb92575d0e1cc Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 9 Dec 2024 14:33:39 +0100 +Subject: [PATCH 2/3] configure.ac: add support for libnvme + +Add 2 new options for linking libnvme with lvm2. +Option --without-libnvme, --disable-nvme-wwid + +(cherry picked from commit cb87e184bcbade1ac2da8fb611177f520169decd) +--- + configure.ac | 34 ++++++++++++++++++++++++++++++++++ + include/configure.h.in | 3 +++ + lib/Makefile.in | 2 +- + make.tmpl.in | 5 ++++- + 4 files changed, 42 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index cbea6adc6..5d4999b2d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -217,6 +217,8 @@ test "$exec_prefix" = "NONE" && exec_prefix='${prefix}' + + AC_ARG_WITH(blkid, [AS_HELP_STRING([--without-blkid], [do not build with blkid library])], + [], with_blkid="yes") ++AC_ARG_WITH(libnvme, [AS_HELP_STRING([--without-libnvme], [do not build with libnvme library])], ++ [], with_libnvme="yes") + AC_ARG_WITH(systemd, [AS_HELP_STRING([--without-systemd], [do not build with systemd library])], + [], with_systemd="yes") + AC_ARG_WITH(udev, [AS_HELP_STRING([--without-udev], [do not build with udev library])], +@@ -1139,6 +1141,38 @@ AC_MSG_RESULT([$BLKID_WIPING]) + AC_DEFINE_UNQUOTED(DEFAULT_USE_BLKID_WIPING, [$DEFAULT_USE_BLKID_WIPING], + [Use blkid wiping by default.]) + ++################################################################################ ++dnl -- Enable nvme alternate WWID via libnvme ++AC_ARG_ENABLE(nvme-wwid, ++ AS_HELP_STRING([--disable-nvme-wwid], ++ [do not use libnvme to detect alternate WWIDs]), ++ NVME_WWID=$enableval, ++ [AS_IF([test "$with_libnvme" = "yes"], [NVME_WWID="maybe"], [NVME_WWID="no"])]) ++ ++# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled ++AS_IF([test "$NVME_WWID" = "no"], [with_libnvme="no"]) ++ ++AS_IF([test "$with_libnvme" = "yes"], [ ++ PKG_CHECK_MODULES([LIBNVME], [libnvme >= 1.4], [ ++ AC_CACHE_CHECK([for NVME_NIDT_CSI in libnvme.h], ++ [ac_cv_have_libnvme_csi], ++ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ++const int a = NVME_NIDT_CSI; ++ ])], [ac_cv_have_libnvme_csi="yes"], [ac_cv_have_libnvme_csi="no"])]) ++ ++ AS_IF([test "$NVME_WWID" != "no"], [ ++ AC_IF_YES(ac_cv_have_libnvme_csi, [NVME_WWID="yes" ++ AC_DEFINE(NVME_SUPPORT, 1, [Use libnvme for WWID.])], ++ [NVME_WWID="error"])]) ++ ], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"])]) ++], [AS_IF([test "$NVME_WWID" = "yes"], [NVME_WWID="error"])]) ++ ++AS_IF([test "$NVME_WWID" = "error"], ++ [AC_MSG_ERROR([--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)])]) ++ ++AC_MSG_CHECKING([whether to use libnvme for alternate WWIDs]) ++AC_MSG_RESULT([$NVME_WWID]) ++ + ################################################################################ + dnl -- Enable udev synchronization + AC_MSG_CHECKING([whether to enable synchronization with udev processing]) +diff --git a/include/configure.h.in b/include/configure.h.in +index 1dabd23c6..5a09f1d11 100644 +--- a/include/configure.h.in ++++ b/include/configure.h.in +@@ -633,6 +633,9 @@ + /* Define to 1 to include code that uses dbus notification. */ + #undef NOTIFYDBUS_SUPPORT + ++/* Use libnvme for WWID. */ ++#undef NVME_SUPPORT ++ + /* Define to 1 to enable O_DIRECT support. */ + #undef O_DIRECT_SUPPORT + +diff --git a/lib/Makefile.in b/lib/Makefile.in +index 8eab625aa..8424ac952 100644 +--- a/lib/Makefile.in ++++ b/lib/Makefile.in +@@ -143,7 +143,7 @@ LIB_STATIC = $(LIB_NAME).a + CFLOW_LIST = $(SOURCES) + CFLOW_LIST_TARGET = $(LIB_NAME).cflow + +-PROGS_CFLAGS = $(BLKID_CFLAGS) $(UDEV_CFLAGS) ++PROGS_CFLAGS = $(BLKID_CFLAGS) $(LIBNVME_CFLAGS) $(UDEV_CFLAGS) + + include $(top_builddir)/make.tmpl + +diff --git a/make.tmpl.in b/make.tmpl.in +index c8a870a8e..878288938 100644 +--- a/make.tmpl.in ++++ b/make.tmpl.in +@@ -57,7 +57,8 @@ PYTHON3 = @PYTHON3@ + PYCOMPILE = $(top_srcdir)/autoconf/py-compile + + LIBS += @LIBS@ $(SELINUX_LIBS) $(UDEV_LIBS) $(RT_LIBS) $(M_LIBS) +-LVMLIBS = $(DMEVENT_LIBS) $(READLINE_LIBS) $(EDITLINE_LIBS) $(LIBSYSTEMD_LIBS) $(BLKID_LIBS) $(AIO_LIBS) $(LIBS) ++LVMLIBS = $(DMEVENT_LIBS) $(READLINE_LIBS) $(EDITLINE_LIBS) $(LIBSYSTEMD_LIBS)\ ++ $(BLKID_LIBS) $(LIBNVME_LIBS) $(AIO_LIBS) $(LIBS) + # Extra libraries always linked with static binaries + STATIC_LIBS = $(PTHREAD_LIBS) $(SELINUX_STATIC_LIBS) $(UDEV_STATIC_LIBS) $(BLKID_STATIC_LIBS) $(M_LIBS) + DEFS += @DEFS@ +@@ -88,6 +89,8 @@ LIBDLM_CFLAGS = @LIBDLM_CFLAGS@ + LIBDLM_LIBS = @LIBDLM_LIBS@ + LIBDLMCONTROL_CFLAGS = @LIBDLMCONTROL_CFLAGS@ + LIBDLMCONTROL_LIBS = @LIBDLMCONTROL_LIBS@ ++LIBNVME_CFLAGS = @LIBNVME_CFLAGS@ ++LIBNVME_LIBS = @LIBNVME_LIBS@ + LIBSANLOCKCLIENT_CFLAGS = @LIBSANLOCKCLIENT_CFLAGS@ + LIBSANLOCKCLIENT_LIBS = @LIBSANLOCKCLIENT_LIBS@ + LIBSEAGATEILM_CFLAGS = @LIBSEAGATEILM_CFLAGS@ +-- +2.47.1 + diff --git a/0019-configure-autoreconf.patch b/0019-configure-autoreconf.patch new file mode 100644 index 0000000..716e99e --- /dev/null +++ b/0019-configure-autoreconf.patch @@ -0,0 +1,271 @@ +From f8d2dda397803b2c274da8eec78b04423c5150dd Mon Sep 17 00:00:00 2001 +From: Zdenek Kabelac +Date: Mon, 9 Dec 2024 14:35:16 +0100 +Subject: [PATCH 3/3] configure: autoreconf + +(cherry picked from commit 928b8e9c6eaf871b3405b91c64eac5ea854f2572) +--- + configure | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 191 insertions(+) + +diff --git a/configure b/configure +index 5147c7910..e98f7c1f3 100755 +--- a/configure ++++ b/configure +@@ -787,6 +787,8 @@ LIBSYSTEMD_LIBS + LIBSYSTEMD_CFLAGS + UDEV_LIBS + UDEV_CFLAGS ++LIBNVME_LIBS ++LIBNVME_CFLAGS + BLKID_LIBS + BLKID_CFLAGS + SYSTEMD_RUN_CMD +@@ -912,6 +914,7 @@ enable_silent_rules + enable_static_link + enable_shared + with_blkid ++with_libnvme + with_systemd + with_udev + with_user +@@ -973,6 +976,7 @@ enable_systemd_journal + enable_app_machineid + with_systemd_run + enable_blkid_wiping ++enable_nvme_wwid + enable_udev_sync + enable_udev_rules + enable_udev_rule_exec_detection +@@ -1045,6 +1049,8 @@ LIBSEAGATEILM_CFLAGS + LIBSEAGATEILM_LIBS + BLKID_CFLAGS + BLKID_LIBS ++LIBNVME_CFLAGS ++LIBNVME_LIBS + UDEV_CFLAGS + UDEV_LIBS + LIBSYSTEMD_CFLAGS +@@ -1715,6 +1721,7 @@ Optional Features: + --disable-app-machineid disable LVM system ID using app-specific machine-id + --disable-blkid_wiping disable libblkid detection of signatures when wiping + and use native code instead ++ --disable-nvme-wwid do not use libnvme to detect alternate WWIDs + --enable-udev_sync enable synchronization with udev processing + --enable-udev_rules install rule files needed for udev synchronization + --enable-udev-rule-exec-detection +@@ -1741,6 +1748,7 @@ Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-blkid do not build with blkid library ++ --without-libnvme do not build with libnvme library + --without-systemd do not build with systemd library + --without-udev do not build with udev library + --with-user=USER set the owner of installed files [USER=] +@@ -1880,6 +1888,10 @@ Some influential environment variables: + BLKID_CFLAGS + C compiler flags for BLKID, overriding pkg-config + BLKID_LIBS linker flags for BLKID, overriding pkg-config ++ LIBNVME_CFLAGS ++ C compiler flags for LIBNVME, overriding pkg-config ++ LIBNVME_LIBS ++ linker flags for LIBNVME, overriding pkg-config + UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config + UDEV_LIBS linker flags for UDEV, overriding pkg-config + LIBSYSTEMD_CFLAGS +@@ -9128,6 +9140,16 @@ esac + fi + + ++# Check whether --with-libnvme was given. ++if test ${with_libnvme+y} ++then : ++ withval=$with_libnvme; ++else case e in #( ++ e) with_libnvme="yes" ;; ++esac ++fi ++ ++ + # Check whether --with-systemd was given. + if test ${with_systemd+y} + then : +@@ -13129,6 +13151,175 @@ printf "%s\n" "$BLKID_WIPING" >&6; } + printf "%s\n" "#define DEFAULT_USE_BLKID_WIPING $DEFAULT_USE_BLKID_WIPING" >>confdefs.h + + ++################################################################################ ++# Check whether --enable-nvme-wwid was given. ++if test ${enable_nvme_wwid+y} ++then : ++ enableval=$enable_nvme_wwid; NVME_WWID=$enableval ++else case e in #( ++ e) if test "$with_libnvme" = "yes" ++then : ++ NVME_WWID="maybe" ++else case e in #( ++ e) NVME_WWID="no" ;; ++esac ++fi ;; ++esac ++fi ++ ++ ++# ATM NVME_WWID is the only user of libnvme, so skip checking for libnvme when disabled ++if test "$NVME_WWID" = "no" ++then : ++ with_libnvme="no" ++fi ++ ++if test "$with_libnvme" = "yes" ++then : ++ ++ ++pkg_failed=no ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libnvme >= 1.4" >&5 ++printf %s "checking for libnvme >= 1.4... " >&6; } ++ ++if test -n "$LIBNVME_CFLAGS"; then ++ pkg_cv_LIBNVME_CFLAGS="$LIBNVME_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_LIBNVME_CFLAGS=`$PKG_CONFIG --cflags "libnvme >= 1.4" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++if test -n "$LIBNVME_LIBS"; then ++ pkg_cv_LIBNVME_LIBS="$LIBNVME_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnvme >= 1.4\""; } >&5 ++ ($PKG_CONFIG --exists --print-errors "libnvme >= 1.4") 2>&5 ++ ac_status=$? ++ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++ pkg_cv_LIBNVME_LIBS=`$PKG_CONFIG --libs "libnvme >= 1.4" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++else ++ pkg_failed=yes ++fi ++ else ++ pkg_failed=untried ++fi ++ ++ ++ ++if test $pkg_failed = yes; then ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++printf "%s\n" "no" >&6; } ++ ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi ++ if test $_pkg_short_errors_supported = yes; then ++ LIBNVME_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnvme >= 1.4" 2>&1` ++ else ++ LIBNVME_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnvme >= 1.4" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$LIBNVME_PKG_ERRORS" >&5 ++ ++ if test "$NVME_WWID" = "yes" ++then : ++ NVME_WWID="error" ++fi ++elif test $pkg_failed = untried; then ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++printf "%s\n" "no" >&6; } ++ if test "$NVME_WWID" = "yes" ++then : ++ NVME_WWID="error" ++fi ++else ++ LIBNVME_CFLAGS=$pkg_cv_LIBNVME_CFLAGS ++ LIBNVME_LIBS=$pkg_cv_LIBNVME_LIBS ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++printf "%s\n" "yes" >&6; } ++ ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for NVME_NIDT_CSI in libnvme.h" >&5 ++printf %s "checking for NVME_NIDT_CSI in libnvme.h... " >&6; } ++if test ${ac_cv_have_libnvme_csi+y} ++then : ++ printf %s "(cached) " >&6 ++else case e in #( ++ e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#include ++const int a = NVME_NIDT_CSI; ++ ++int ++main (void) ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO" ++then : ++ ac_cv_have_libnvme_csi="yes" ++else case e in #( ++ e) ac_cv_have_libnvme_csi="no" ;; ++esac ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; ++esac ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libnvme_csi" >&5 ++printf "%s\n" "$ac_cv_have_libnvme_csi" >&6; } ++ ++ if test "$NVME_WWID" != "no" ++then : ++ ++ if test $ac_cv_have_libnvme_csi = yes ++then : ++ NVME_WWID="yes" ++ ++printf "%s\n" "#define NVME_SUPPORT 1" >>confdefs.h ++ ++else case e in #( ++ e) NVME_WWID="error" ;; ++esac ++fi ++fi ++ ++fi ++ ++else case e in #( ++ e) if test "$NVME_WWID" = "yes" ++then : ++ NVME_WWID="error" ++fi ;; ++esac ++fi ++ ++if test "$NVME_WWID" = "error" ++then : ++ as_fn_error $? "--enable-nvme-wwid requires libnvme library >= 1.1. (--with-libnvme=$with_libnvme)" "$LINENO" 5 ++fi ++ ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use libnvme for alternate WWIDs" >&5 ++printf %s "checking whether to use libnvme for alternate WWIDs... " >&6; } ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NVME_WWID" >&5 ++printf "%s\n" "$NVME_WWID" >&6; } ++ + ################################################################################ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable synchronization with udev processing" >&5 + printf %s "checking whether to enable synchronization with udev processing... " >&6; } +-- +2.47.1 + diff --git a/lvm2.spec b/lvm2.spec index f854dd3..3502ecd 100644 --- a/lvm2.spec +++ b/lvm2.spec @@ -54,7 +54,7 @@ Version: 2.03.28 %if 0%{?from_snapshot} Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix} %else -Release: 3%{?dist}%{?rel_suffix} +Release: 4%{?dist}%{?rel_suffix} %endif License: GPL-2.0-only URL: https://sourceware.org/lvm2 @@ -79,6 +79,9 @@ Patch13: 0013-tests-check-vdo-minimum_io_size.patch Patch14: 0014-raid-fix-name-rotation.patch Patch15: 0015-tests-check-_tdata-conversion-to-raid1.patch Patch16: 0016-WHATS_NEW-update.patch +Patch17: 0017-device_id-nvme-devices-may-use-alternate-wwids.patch +Patch18: 0018-configure.ac-add-support-for-libnvme.patch +Patch19: 0019-configure-autoreconf.patch BuildRequires: make BuildRequires: gcc @@ -90,6 +93,7 @@ BuildRequires: libblkid-devel >= %{util_linux_version} BuildRequires: ncurses-devel BuildRequires: libedit-devel BuildRequires: libaio-devel +BuildRequires: libnvme-devel %if %{enable_lockd_dlm} BuildRequires: dlm-devel >= %{dlm_version} %endif @@ -709,6 +713,9 @@ An extensive functional testsuite for LVM2. %endif %changelog +* Tue Dec 17 2024 Marian Csontos - 2.03.28-4 +- Workaround for NVMe WWID changing after kernel update. + * Thu Nov 14 2024 Marian Csontos - 2.03.28-3 - Fix duplicate LV names when converting pools to RAID1 with more than 2 legs.