Update to latest upstream
Resolves: RHEL-36424 Signed-off-by: Xiao Ni <xni@redhat.com>
This commit is contained in:
parent
c9d414952b
commit
f102102bb4
44
0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch
Normal file
44
0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
From cc75b0faaa016e54d569486c9a7abe6c39cb883a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:15 +0100
|
||||||
|
Subject: [PATCH 42/69] mdadm: Move pr_vrb define to mdadm.h
|
||||||
|
|
||||||
|
Move pr_vrb define from super-intel.c to mdadm.h to make it widely
|
||||||
|
available. This change will be used in the next patches.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
mdadm.h | 2 ++
|
||||||
|
super-intel.c | 2 --
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index ae2106a2..fbb161ba 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1911,6 +1911,8 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
|
||||||
|
|
||||||
|
#define pr_info(fmt, args...) printf("%s: "fmt, Name, ##args)
|
||||||
|
|
||||||
|
+#define pr_vrb(fmt, arg...) ((void)(verbose && pr_err(fmt, ##arg)))
|
||||||
|
+
|
||||||
|
void *xmalloc(size_t len);
|
||||||
|
void *xrealloc(void *ptr, size_t len);
|
||||||
|
void *xcalloc(size_t num, size_t size);
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 70f3c4ef..212387ec 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -393,8 +393,6 @@ struct md_list {
|
||||||
|
struct md_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
-#define pr_vrb(fmt, arg...) (void) (verbose && pr_err(fmt, ##arg))
|
||||||
|
-
|
||||||
|
static __u8 migr_type(struct imsm_dev *dev)
|
||||||
|
{
|
||||||
|
if (dev->vol.migr_type == MIGR_VERIFY &&
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
463
0043-Add-reading-Opal-NVMe-encryption-information.patch
Normal file
463
0043-Add-reading-Opal-NVMe-encryption-information.patch
Normal file
@ -0,0 +1,463 @@
|
|||||||
|
From cc48406887b3bc439e3462e8e4d20f992e81b87e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:16 +0100
|
||||||
|
Subject: [PATCH 43/69] Add reading Opal NVMe encryption information
|
||||||
|
|
||||||
|
For NVMe devices with Opal support, encryption information, status and
|
||||||
|
ability are determined based on Opal Level 0 discovery response. Technical
|
||||||
|
documentation used is given in the implementation.
|
||||||
|
|
||||||
|
Ability in general describes what type of encryption is supported, Status
|
||||||
|
describes in what state the disk with encryption support is. The current
|
||||||
|
patch includes only the implementation of reading encryption information,
|
||||||
|
functions will be used in one of the next patches.
|
||||||
|
|
||||||
|
Motivation for adding this functionality is to block mixing of disks in
|
||||||
|
IMSM arrays with encryption enabled and disabled. The main goal is to not
|
||||||
|
allow stealing data by rebuilding array to not encrypted drive which can be
|
||||||
|
read elsewhere.
|
||||||
|
|
||||||
|
Value ENA_OTHER from enum encryption_ability will be used in the next
|
||||||
|
patch.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Makefile | 4 +-
|
||||||
|
drive_encryption.c | 362 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drive_encryption.h | 32 ++++
|
||||||
|
3 files changed, 396 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 drive_encryption.c
|
||||||
|
create mode 100644 drive_encryption.h
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index cbdba49a..7c221a89 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -170,7 +170,7 @@ OBJS = mdadm.o config.o policy.o mdstat.o ReadMe.o uuid.o util.o maps.o lib.o u
|
||||||
|
mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \
|
||||||
|
super-mbr.o super-gpt.o \
|
||||||
|
restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o xmalloc.o \
|
||||||
|
- platform-intel.o probe_roms.o crc32c.o
|
||||||
|
+ platform-intel.o probe_roms.o crc32c.o drive_encryption.o
|
||||||
|
|
||||||
|
CHECK_OBJS = restripe.o uuid.o sysfs.o maps.o lib.o xmalloc.o dlink.o
|
||||||
|
|
||||||
|
@@ -183,7 +183,7 @@ MON_OBJS = mdmon.o monitor.o managemon.o uuid.o util.o maps.o mdstat.o sysfs.o c
|
||||||
|
Kill.o sg_io.o dlink.o ReadMe.o super-intel.o \
|
||||||
|
super-mbr.o super-gpt.o \
|
||||||
|
super-ddf.o sha1.o crc32.o msg.o bitmap.o xmalloc.o \
|
||||||
|
- platform-intel.o probe_roms.o crc32c.o
|
||||||
|
+ platform-intel.o probe_roms.o crc32c.o drive_encryption.o
|
||||||
|
|
||||||
|
MON_SRCS = $(patsubst %.o,%.c,$(MON_OBJS))
|
||||||
|
|
||||||
|
diff --git a/drive_encryption.c b/drive_encryption.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..b44585a7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drive_encryption.c
|
||||||
|
@@ -0,0 +1,362 @@
|
||||||
|
+// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
+/*
|
||||||
|
+ * Read encryption information for Opal and ATA devices.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2024 Intel Corporation
|
||||||
|
+ * Author: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "mdadm.h"
|
||||||
|
+
|
||||||
|
+#include <asm/types.h>
|
||||||
|
+#include <linux/nvme_ioctl.h>
|
||||||
|
+#include "drive_encryption.h"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Opal defines
|
||||||
|
+ * TCG Storage Opal SSC 2.01 chapter 3.3.3
|
||||||
|
+ * NVM ExpressTM Revision 1.4c, chapter 5
|
||||||
|
+ */
|
||||||
|
+#define TCG_SECP_01 (0x01)
|
||||||
|
+#define TCG_SECP_00 (0x00)
|
||||||
|
+#define OPAL_DISCOVERY_COMID (0x0001)
|
||||||
|
+#define OPAL_LOCKING_FEATURE (0x0002)
|
||||||
|
+#define OPAL_IO_BUFFER_LEN 2048
|
||||||
|
+#define OPAL_DISCOVERY_FEATURE_HEADER_LEN (4)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * NVMe defines
|
||||||
|
+ * NVM ExpressTM Revision 1.4c, chapter 5
|
||||||
|
+ */
|
||||||
|
+#define NVME_SECURITY_RECV (0x82)
|
||||||
|
+#define NVME_IDENTIFY (0x06)
|
||||||
|
+#define NVME_IDENTIFY_RESPONSE_LEN 4096
|
||||||
|
+#define NVME_OACS_BYTE_POSITION (256)
|
||||||
|
+#define NVME_IDENTIFY_CONTROLLER_DATA (1)
|
||||||
|
+
|
||||||
|
+typedef enum drive_feature_support_status {
|
||||||
|
+ /* Drive feature is supported. */
|
||||||
|
+ DRIVE_FEAT_SUP_ST = 0,
|
||||||
|
+ /* Drive feature is not supported. */
|
||||||
|
+ DRIVE_FEAT_NOT_SUP_ST,
|
||||||
|
+ /* Drive feature support check failed. */
|
||||||
|
+ DRIVE_FEAT_CHECK_FAILED_ST
|
||||||
|
+} drive_feat_sup_st;
|
||||||
|
+
|
||||||
|
+/* TCG Storage Opal SSC 2.01 chapter 3.1.1.3 */
|
||||||
|
+typedef struct opal_locking_feature {
|
||||||
|
+ /* feature header */
|
||||||
|
+ __u16 feature_code;
|
||||||
|
+ __u8 reserved : 4;
|
||||||
|
+ __u8 version : 4;
|
||||||
|
+ __u8 description_length;
|
||||||
|
+ /* feature description */
|
||||||
|
+ __u8 locking_supported : 1;
|
||||||
|
+ __u8 locking_enabled : 1;
|
||||||
|
+ __u8 locked : 1;
|
||||||
|
+ __u8 media_encryption : 1;
|
||||||
|
+ __u8 mbr_enabled : 1;
|
||||||
|
+ __u8 mbr_done : 1;
|
||||||
|
+ __u8 mbr_shadowing_not_supported : 1;
|
||||||
|
+ __u8 hw_reset_for_dor_supported : 1;
|
||||||
|
+ __u8 reserved1[11];
|
||||||
|
+} __attribute__((__packed__)) opal_locking_feature_t;
|
||||||
|
+
|
||||||
|
+/* TCG Storage Opal SSC 2.01 chapter 3.1.1.1 */
|
||||||
|
+typedef struct opal_level0_header {
|
||||||
|
+ __u32 length;
|
||||||
|
+ __u32 version;
|
||||||
|
+ __u64 reserved;
|
||||||
|
+ __u8 vendor_specific[32];
|
||||||
|
+} opal_level0_header_t;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * NVM ExpressTM Revision 1.4c, Figure 249
|
||||||
|
+ * Structure specifies only OACS filed, which is needed in the current use case.
|
||||||
|
+ */
|
||||||
|
+typedef struct nvme_identify_ctrl {
|
||||||
|
+ __u8 reserved[255];
|
||||||
|
+ __u16 oacs;
|
||||||
|
+ __u8 reserved2[3839];
|
||||||
|
+} nvme_identify_ctrl_t;
|
||||||
|
+
|
||||||
|
+/* SCSI Primary Commands - 4 (SPC-4), Table 512 */
|
||||||
|
+typedef struct supported_security_protocols {
|
||||||
|
+ __u8 reserved[6];
|
||||||
|
+ __u16 list_length;
|
||||||
|
+ __u8 list[504];
|
||||||
|
+} supported_security_protocols_t;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_opal_locking_feature_description() - get opal locking feature description.
|
||||||
|
+ * @response: response from Opal Discovery Level 0.
|
||||||
|
+ *
|
||||||
|
+ * Based on the documentation TCG Storage Opal SSC 2.01 chapter 3.1.1,
|
||||||
|
+ * a Locking feature is searched for in Opal Level 0 Discovery response.
|
||||||
|
+ *
|
||||||
|
+ * Return: if locking feature is found, pointer to struct %opal_locking_feature_t, NULL otherwise.
|
||||||
|
+ */
|
||||||
|
+static opal_locking_feature_t *get_opal_locking_feature_description(__u8 *response)
|
||||||
|
+{
|
||||||
|
+ opal_level0_header_t *response_header = (opal_level0_header_t *)response;
|
||||||
|
+ int features_length = __be32_to_cpu(response_header->length);
|
||||||
|
+ int current_position = sizeof(*response_header);
|
||||||
|
+
|
||||||
|
+ while (current_position < features_length) {
|
||||||
|
+ opal_locking_feature_t *feature;
|
||||||
|
+
|
||||||
|
+ feature = (opal_locking_feature_t *)(response + current_position);
|
||||||
|
+
|
||||||
|
+ if (__be16_to_cpu(feature->feature_code) == OPAL_LOCKING_FEATURE)
|
||||||
|
+ return feature;
|
||||||
|
+
|
||||||
|
+ current_position += feature->description_length + OPAL_DISCOVERY_FEATURE_HEADER_LEN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * nvme_security_recv_ioctl() - nvme security receive ioctl.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @sec_protocol: security protocol.
|
||||||
|
+ * @comm_id: command id.
|
||||||
|
+ * @response_buffer: response buffer to fill out.
|
||||||
|
+ * @buf_size: response buffer size.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and
|
||||||
|
+ * NVM ExpressTM Revision 1.4c, chapter 5.25,
|
||||||
|
+ * read security receive command via ioctl().
|
||||||
|
+ * On success, @response_buffer is completed.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t
|
||||||
|
+nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *response_buffer,
|
||||||
|
+ size_t buf_size, const int verbose)
|
||||||
|
+{
|
||||||
|
+ struct nvme_admin_cmd nvme_cmd = {0};
|
||||||
|
+ int status;
|
||||||
|
+
|
||||||
|
+ nvme_cmd.opcode = NVME_SECURITY_RECV;
|
||||||
|
+ nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8;
|
||||||
|
+ nvme_cmd.cdw11 = buf_size;
|
||||||
|
+ nvme_cmd.data_len = buf_size;
|
||||||
|
+ nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
+
|
||||||
|
+ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ pr_vrb("Failed to read NVMe security receive ioctl() for device /dev/%s, status: %d\n",
|
||||||
|
+ fd2kname(disk_fd), status);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * nvme_identify_ioctl() - NVMe identify ioctl.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @response_buffer: response buffer to fill out.
|
||||||
|
+ * @buf_size: response buffer size.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Based on the documentations TCG Storage Opal SSC 2.01 chapter 3.3.3 and
|
||||||
|
+ * NVM ExpressTM Revision 1.4c, chapter 5.25,
|
||||||
|
+ * read NVMe identify via ioctl().
|
||||||
|
+ * On success, @response_buffer will be completed.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t
|
||||||
|
+nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const int verbose)
|
||||||
|
+{
|
||||||
|
+ struct nvme_admin_cmd nvme_cmd = {0};
|
||||||
|
+ int status;
|
||||||
|
+
|
||||||
|
+ nvme_cmd.opcode = NVME_IDENTIFY;
|
||||||
|
+ nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA;
|
||||||
|
+ nvme_cmd.data_len = buf_size;
|
||||||
|
+ nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
+
|
||||||
|
+ status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ pr_vrb("Failed to read NVMe identify ioctl() for device /dev/%s, status: %d\n",
|
||||||
|
+ fd2kname(disk_fd), status);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_sec_prot_01h_supported() - check if security protocol 01h supported.
|
||||||
|
+ * @security_protocols: struct with response from disk (NVMe, SATA) describing supported
|
||||||
|
+ * security protocols.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if TCG_SECP_01 found, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool is_sec_prot_01h_supported(supported_security_protocols_t *security_protocols)
|
||||||
|
+{
|
||||||
|
+ int list_length = be16toh(security_protocols->list_length);
|
||||||
|
+ int index;
|
||||||
|
+
|
||||||
|
+ for (index = 0 ; index < list_length; index++) {
|
||||||
|
+ if (security_protocols->list[index] == TCG_SECP_01)
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_sec_prot_01h_supported_nvme() - check if security protocol 01h supported for given NVMe disk.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported,
|
||||||
|
+ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check.
|
||||||
|
+ */
|
||||||
|
+static drive_feat_sup_st is_sec_prot_01h_supported_nvme(int disk_fd, const int verbose)
|
||||||
|
+{
|
||||||
|
+ supported_security_protocols_t security_protocols = {0};
|
||||||
|
+
|
||||||
|
+ /* security_protocol: TCG_SECP_00, comm_id: not applicable */
|
||||||
|
+ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_00, 0x0, &security_protocols,
|
||||||
|
+ sizeof(security_protocols), verbose))
|
||||||
|
+ return DRIVE_FEAT_CHECK_FAILED_ST;
|
||||||
|
+
|
||||||
|
+ if (is_sec_prot_01h_supported(&security_protocols))
|
||||||
|
+ return DRIVE_FEAT_SUP_ST;
|
||||||
|
+
|
||||||
|
+ return DRIVE_FEAT_NOT_SUP_ST;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_nvme_sec_send_recv_supported() - check if Security Send and Security Receive is supported.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Check if "Optional Admin Command Support" bit 0 is set in NVMe identify.
|
||||||
|
+ * Bit 0 set to 1 means controller supports the Security Send and Security Receive commands.
|
||||||
|
+ *
|
||||||
|
+ * Return: %DRIVE_FEAT_SUP_ST if security send/receive supported,
|
||||||
|
+ * %DRIVE_FEAT_NOT_SUP_ST if not supported, %DRIVE_FEAT_CHECK_FAILED_ST if check failed.
|
||||||
|
+ */
|
||||||
|
+static drive_feat_sup_st is_nvme_sec_send_recv_supported(int disk_fd, const int verbose)
|
||||||
|
+{
|
||||||
|
+ nvme_identify_ctrl_t nvme_identify = {0};
|
||||||
|
+ int status = 0;
|
||||||
|
+
|
||||||
|
+ status = nvme_identify_ioctl(disk_fd, &nvme_identify, sizeof(nvme_identify), verbose);
|
||||||
|
+ if (status)
|
||||||
|
+ return DRIVE_FEAT_CHECK_FAILED_ST;
|
||||||
|
+
|
||||||
|
+ if ((__le16_to_cpu(nvme_identify.oacs) & 0x1) == 0x1)
|
||||||
|
+ return DRIVE_FEAT_SUP_ST;
|
||||||
|
+
|
||||||
|
+ return DRIVE_FEAT_NOT_SUP_ST;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_opal_encryption_information() - get Opal encryption information.
|
||||||
|
+ * @buffer: buffer with Opal Level 0 Discovery response.
|
||||||
|
+ * @information: struct to fill out, describing encryption status of disk.
|
||||||
|
+ *
|
||||||
|
+ * If Locking feature frame is in response from Opal Level 0 discovery, &encryption_information_t
|
||||||
|
+ * structure is completed with status and ability otherwise the status is set to &None.
|
||||||
|
+ * For possible encryption statuses and abilities,
|
||||||
|
+ * please refer to enums &encryption_status and &encryption_ability.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t get_opal_encryption_information(__u8 *buffer,
|
||||||
|
+ encryption_information_t *information)
|
||||||
|
+{
|
||||||
|
+ opal_locking_feature_t *opal_locking_feature =
|
||||||
|
+ get_opal_locking_feature_description(buffer);
|
||||||
|
+
|
||||||
|
+ if (!opal_locking_feature)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ if (opal_locking_feature->locking_supported == 1) {
|
||||||
|
+ information->ability = ENC_ABILITY_SED;
|
||||||
|
+
|
||||||
|
+ if (opal_locking_feature->locking_enabled == 0)
|
||||||
|
+ information->status = ENC_STATUS_UNENCRYPTED;
|
||||||
|
+ else if (opal_locking_feature->locked == 1)
|
||||||
|
+ information->status = ENC_STATUS_LOCKED;
|
||||||
|
+ else
|
||||||
|
+ information->status = ENC_STATUS_UNLOCKED;
|
||||||
|
+ } else {
|
||||||
|
+ information->ability = ENC_ABILITY_NONE;
|
||||||
|
+ information->status = ENC_STATUS_UNENCRYPTED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_nvme_opal_encryption_information() - get NVMe Opal encryption information.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @information: struct to fill out, describing encryption status of disk.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * In case the disk supports Opal Level 0 discovery, &encryption_information_t structure
|
||||||
|
+ * is completed with status and ability based on ioctl response,
|
||||||
|
+ * otherwise the ability is set to %ENC_ABILITY_NONE and &status to %ENC_STATUS_UNENCRYPTED.
|
||||||
|
+ * As the current use case does not need the knowledge of Opal support, if there is no support,
|
||||||
|
+ * %MDADM_STATUS_SUCCESS will be returned, with the values described above.
|
||||||
|
+ * For possible encryption statuses and abilities,
|
||||||
|
+ * please refer to enums &encryption_status and &encryption_ability.
|
||||||
|
+ *
|
||||||
|
+ * %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR otherwise.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t
|
||||||
|
+get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *information,
|
||||||
|
+ const int verbose)
|
||||||
|
+{
|
||||||
|
+ __u8 buffer[OPAL_IO_BUFFER_LEN];
|
||||||
|
+ int sec_send_recv_supported = 0;
|
||||||
|
+ int protocol_01h_supported = 0;
|
||||||
|
+ mdadm_status_t status;
|
||||||
|
+
|
||||||
|
+ information->ability = ENC_ABILITY_NONE;
|
||||||
|
+ information->status = ENC_STATUS_UNENCRYPTED;
|
||||||
|
+
|
||||||
|
+ sec_send_recv_supported = is_nvme_sec_send_recv_supported(disk_fd, verbose);
|
||||||
|
+ if (sec_send_recv_supported == DRIVE_FEAT_CHECK_FAILED_ST)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ /* Opal not supported */
|
||||||
|
+ if (sec_send_recv_supported == DRIVE_FEAT_NOT_SUP_ST)
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * sec_send_recv_supported determine that it should be possible to read
|
||||||
|
+ * supported sec protocols
|
||||||
|
+ */
|
||||||
|
+ protocol_01h_supported = is_sec_prot_01h_supported_nvme(disk_fd, verbose);
|
||||||
|
+ if (protocol_01h_supported == DRIVE_FEAT_CHECK_FAILED_ST)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ /* Opal not supported */
|
||||||
|
+ if (sec_send_recv_supported == DRIVE_FEAT_SUP_ST &&
|
||||||
|
+ protocol_01h_supported == DRIVE_FEAT_NOT_SUP_ST)
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+
|
||||||
|
+ if (nvme_security_recv_ioctl(disk_fd, TCG_SECP_01, OPAL_DISCOVERY_COMID, (void *)&buffer,
|
||||||
|
+ OPAL_IO_BUFFER_LEN, verbose))
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ status = get_opal_encryption_information((__u8 *)&buffer, information);
|
||||||
|
+ if (status)
|
||||||
|
+ pr_vrb("Locking feature description not found in Level 0 discovery response. Device /dev/%s.\n",
|
||||||
|
+ fd2kname(disk_fd));
|
||||||
|
+
|
||||||
|
+ if (information->ability == ENC_ABILITY_NONE)
|
||||||
|
+ assert(information->status == ENC_STATUS_UNENCRYPTED);
|
||||||
|
+
|
||||||
|
+ return status;
|
||||||
|
+}
|
||||||
|
diff --git a/drive_encryption.h b/drive_encryption.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..82c2c624
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/drive_encryption.h
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
+/*
|
||||||
|
+ * Read encryption information for Opal and ATA devices.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2024 Intel Corporation
|
||||||
|
+ * Author: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+typedef enum encryption_status {
|
||||||
|
+ /* The drive is not currently encrypted. */
|
||||||
|
+ ENC_STATUS_UNENCRYPTED = 0,
|
||||||
|
+ /* The drive is encrypted and the data is not accessible. */
|
||||||
|
+ ENC_STATUS_LOCKED,
|
||||||
|
+ /* The drive is encrypted but the data is accessible in unencrypted form. */
|
||||||
|
+ ENC_STATUS_UNLOCKED
|
||||||
|
+} encryption_status_t;
|
||||||
|
+
|
||||||
|
+typedef enum encryption_ability {
|
||||||
|
+ ENC_ABILITY_NONE = 0,
|
||||||
|
+ ENC_ABILITY_OTHER,
|
||||||
|
+ /* Self encrypted drive */
|
||||||
|
+ ENC_ABILITY_SED
|
||||||
|
+} encryption_ability_t;
|
||||||
|
+
|
||||||
|
+typedef struct encryption_information {
|
||||||
|
+ encryption_ability_t ability;
|
||||||
|
+ encryption_status_t status;
|
||||||
|
+} encryption_information_t;
|
||||||
|
+
|
||||||
|
+mdadm_status_t
|
||||||
|
+get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information,
|
||||||
|
+ const int verbose);
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
459
0044-Add-reading-SATA-encryption-information.patch
Normal file
459
0044-Add-reading-SATA-encryption-information.patch
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
From df38df3052c3386c0fd076e0d534b4f688b5c8a4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:17 +0100
|
||||||
|
Subject: [PATCH 44/69] Add reading SATA encryption information
|
||||||
|
|
||||||
|
Functionality reads information about SATA disk encryption. Technical
|
||||||
|
documentation used is given in the implementation.
|
||||||
|
|
||||||
|
The implementation is able to recognized two encryption standards for SATA
|
||||||
|
drives, OPAL and ATA security.
|
||||||
|
|
||||||
|
If the SATA drive supports OPAL, encryption status and ability are
|
||||||
|
determined based on Opal Level 0 discovery response, for ATA security,
|
||||||
|
based on ATA identify response. If SATA supports OPAL, ability is set to
|
||||||
|
"SED", for ATA security to "Other".
|
||||||
|
|
||||||
|
SED(Self-Encrypting Drive) is commonly used to describe drive which using
|
||||||
|
OPAL or Enterprise standards developed by Trusted Computing Group. Ability
|
||||||
|
"Other" is used for ATA security because we rely only on information from
|
||||||
|
ATA identify which describe the overall state of encryption.
|
||||||
|
|
||||||
|
It is allowed to mix disks with different encryption ability such as "SED"
|
||||||
|
and "Other" and it is not security gap.
|
||||||
|
|
||||||
|
Motivation for adding this functionality is to block mixing of disks in
|
||||||
|
IMSM arrays with encryption enabled and disabled. The main goal is to not
|
||||||
|
allow stealing data by rebuilding array to not encrypted drive which can be
|
||||||
|
read elsewhere.
|
||||||
|
|
||||||
|
For SATA Opal drives, libata allow_tmp parameter enabled is required, which
|
||||||
|
is necessary for Opal Security commands to work, therefore, if the
|
||||||
|
parameter is not enabled, SATA Opal disk cannot be used in case the
|
||||||
|
encryption will be checked by metadata.
|
||||||
|
|
||||||
|
Implemented functions will be used in one of the next patches. In one of
|
||||||
|
the next patches, a flag will be added to enable disabling SATA Opal
|
||||||
|
encryption checking due to allow_tpm kernel setting dependency.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
drive_encryption.c | 318 +++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
drive_encryption.h | 3 +
|
||||||
|
mdadm.h | 1 +
|
||||||
|
sysfs.c | 29 +++++
|
||||||
|
4 files changed, 351 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drive_encryption.c b/drive_encryption.c
|
||||||
|
index b44585a7..d520f0c7 100644
|
||||||
|
--- a/drive_encryption.c
|
||||||
|
+++ b/drive_encryption.c
|
||||||
|
@@ -10,8 +10,12 @@
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <linux/nvme_ioctl.h>
|
||||||
|
+#include <scsi/sg.h>
|
||||||
|
+#include <scsi/scsi.h>
|
||||||
|
#include "drive_encryption.h"
|
||||||
|
|
||||||
|
+#define DEFAULT_SECTOR_SIZE (512)
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Opal defines
|
||||||
|
* TCG Storage Opal SSC 2.01 chapter 3.3.3
|
||||||
|
@@ -34,6 +38,35 @@
|
||||||
|
#define NVME_OACS_BYTE_POSITION (256)
|
||||||
|
#define NVME_IDENTIFY_CONTROLLER_DATA (1)
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * ATA defines
|
||||||
|
+ * ATA/ATAPI Command Set ATA8-ACS
|
||||||
|
+ * SCSI / ATA Translation - 3 (SAT-3)
|
||||||
|
+ * SCSI Primary Commands - 4 (SPC-4)
|
||||||
|
+ * AT Attachment-8 - ATA Serial Transport (ATA8-AST)
|
||||||
|
+ * ATA Command Pass-Through
|
||||||
|
+ */
|
||||||
|
+#define ATA_IDENTIFY (0xec)
|
||||||
|
+#define ATA_TRUSTED_RECEIVE (0x5c)
|
||||||
|
+#define ATA_SECURITY_WORD_POSITION (128)
|
||||||
|
+#define HDIO_DRIVE_CMD (0x031f)
|
||||||
|
+#define ATA_TRUSTED_COMPUTING_POS (48)
|
||||||
|
+#define ATA_PASS_THROUGH_12 (0xa1)
|
||||||
|
+#define ATA_IDENTIFY_RESPONSE_LEN (512)
|
||||||
|
+#define ATA_PIO_DATA_IN (4)
|
||||||
|
+#define SG_CHECK_CONDITION (0x02)
|
||||||
|
+#define ATA_STATUS_RETURN_DESCRIPTOR (0x09)
|
||||||
|
+#define ATA_PT_INFORMATION_AVAILABLE_ASCQ (0x1d)
|
||||||
|
+#define ATA_PT_INFORMATION_AVAILABLE_ASC (0x00)
|
||||||
|
+#define ATA_INQUIRY_LENGTH (0x0c)
|
||||||
|
+#define SG_INTERFACE_ID 'S'
|
||||||
|
+#define SG_IO_TIMEOUT (60000)
|
||||||
|
+#define SG_SENSE_SIZE (32)
|
||||||
|
+#define SENSE_DATA_CURRENT_FIXED (0x70)
|
||||||
|
+#define SENSE_DATA_CURRENT_DESC (0x72)
|
||||||
|
+#define SENSE_CURRENT_RES_DESC_POS (8)
|
||||||
|
+#define SG_DRIVER_SENSE (0x08)
|
||||||
|
+
|
||||||
|
typedef enum drive_feature_support_status {
|
||||||
|
/* Drive feature is supported. */
|
||||||
|
DRIVE_FEAT_SUP_ST = 0,
|
||||||
|
@@ -87,6 +120,27 @@ typedef struct supported_security_protocols {
|
||||||
|
__u8 list[504];
|
||||||
|
} supported_security_protocols_t;
|
||||||
|
|
||||||
|
+/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */
|
||||||
|
+typedef struct ata_security_status {
|
||||||
|
+ __u16 security_supported : 1;
|
||||||
|
+ __u16 security_enabled : 1;
|
||||||
|
+ __u16 security_locked : 1;
|
||||||
|
+ __u16 security_frozen : 1;
|
||||||
|
+ __u16 security_count_expired : 1;
|
||||||
|
+ __u16 enhanced_security_erase_supported : 1;
|
||||||
|
+ __u16 reserved1 : 2;
|
||||||
|
+ __u16 security_level : 1;
|
||||||
|
+ __u16 reserved2 : 7;
|
||||||
|
+} __attribute__((__packed__)) ata_security_status_t;
|
||||||
|
+
|
||||||
|
+/* ATA/ATAPI Command Set - 3 (ACS-3), Table 45 */
|
||||||
|
+typedef struct ata_trusted_computing {
|
||||||
|
+ __u16 tc_feature :1;
|
||||||
|
+ __u16 reserved : 13;
|
||||||
|
+ __u16 var1 : 1;
|
||||||
|
+ __u16 var2 : 1;
|
||||||
|
+} __attribute__((__packed__)) ata_trusted_computing_t;
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* get_opal_locking_feature_description() - get opal locking feature description.
|
||||||
|
* @response: response from Opal Discovery Level 0.
|
||||||
|
@@ -360,3 +414,267 @@ get_nvme_opal_encryption_information(int disk_fd, encryption_information_t *info
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * ata_pass_through12_ioctl() - ata pass through12 ioctl.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @ata_command: ata command.
|
||||||
|
+ * @sec_protocol: security protocol.
|
||||||
|
+ * @comm_id: additional command id.
|
||||||
|
+ * @response_buffer: response buffer to fill out.
|
||||||
|
+ * @buf_size: response buffer size.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Based on the documentations ATA Command Pass-Through, chapter 13.2.2 and
|
||||||
|
+ * ATA Translation - 3 (SAT-3), send read ata pass through 12 command via ioctl().
|
||||||
|
+ * On success, @response_buffer will be completed.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t
|
||||||
|
+ata_pass_through12_ioctl(int disk_fd, __u8 ata_command, __u8 sec_protocol, __u16 comm_id,
|
||||||
|
+ void *response_buffer, size_t buf_size, const int verbose)
|
||||||
|
+{
|
||||||
|
+ __u8 cdb[ATA_INQUIRY_LENGTH] = {0};
|
||||||
|
+ __u8 sense[SG_SENSE_SIZE] = {0};
|
||||||
|
+ __u8 *sense_desc = NULL;
|
||||||
|
+ sg_io_hdr_t sg = {0};
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * ATA Command Pass-Through, chapter 13.2.2
|
||||||
|
+ * SCSI Primary Commands - 4 (SPC-4)
|
||||||
|
+ * ATA Translation - 3 (SAT-3)
|
||||||
|
+ */
|
||||||
|
+ cdb[0] = ATA_PASS_THROUGH_12;
|
||||||
|
+ /* protocol, bits 1-4 */
|
||||||
|
+ cdb[1] = ATA_PIO_DATA_IN << 1;
|
||||||
|
+ /* Bytes: CK_COND=1, T_DIR = 1, BYTE_BLOCK = 1, Length in Sector Count = 2 */
|
||||||
|
+ cdb[2] = 0x2E;
|
||||||
|
+ cdb[3] = sec_protocol;
|
||||||
|
+ /* Sector count */
|
||||||
|
+ cdb[4] = buf_size / DEFAULT_SECTOR_SIZE;
|
||||||
|
+ cdb[6] = (comm_id) & 0xFF;
|
||||||
|
+ cdb[7] = (comm_id >> 8) & 0xFF;
|
||||||
|
+ cdb[9] = ata_command;
|
||||||
|
+
|
||||||
|
+ sg.interface_id = SG_INTERFACE_ID;
|
||||||
|
+ sg.cmd_len = sizeof(cdb);
|
||||||
|
+ sg.mx_sb_len = sizeof(sense);
|
||||||
|
+ sg.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||||
|
+ sg.dxfer_len = buf_size;
|
||||||
|
+ sg.dxferp = response_buffer;
|
||||||
|
+ sg.cmdp = cdb;
|
||||||
|
+ sg.sbp = sense;
|
||||||
|
+ sg.timeout = SG_IO_TIMEOUT;
|
||||||
|
+ sg.usr_ptr = NULL;
|
||||||
|
+
|
||||||
|
+ if (ioctl(disk_fd, SG_IO, &sg) < 0) {
|
||||||
|
+ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd));
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((sg.status && sg.status != SG_CHECK_CONDITION) || sg.host_status ||
|
||||||
|
+ (sg.driver_status && sg.driver_status != SG_DRIVER_SENSE)) {
|
||||||
|
+ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd));
|
||||||
|
+ pr_vrb("SG_IO error: ATA_12 Status: %d Host Status: %d, Driver Status: %d\n",
|
||||||
|
+ sg.status, sg.host_status, sg.driver_status);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* verify expected sense response code */
|
||||||
|
+ if (!(sense[0] == SENSE_DATA_CURRENT_DESC || sense[0] == SENSE_DATA_CURRENT_FIXED)) {
|
||||||
|
+ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s.\n", fd2kname(disk_fd));
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sense_desc = sense + SENSE_CURRENT_RES_DESC_POS;
|
||||||
|
+ /* verify sense data current response with descriptor format */
|
||||||
|
+ if (sense[0] == SENSE_DATA_CURRENT_DESC &&
|
||||||
|
+ !(sense_desc[0] == ATA_STATUS_RETURN_DESCRIPTOR &&
|
||||||
|
+ sense_desc[1] == ATA_INQUIRY_LENGTH)) {
|
||||||
|
+ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n",
|
||||||
|
+ fd2kname(disk_fd), sense[2], sense[3]);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* verify sense data current response with fixed format */
|
||||||
|
+ if (sense[0] == SENSE_DATA_CURRENT_FIXED &&
|
||||||
|
+ !(sense[12] == ATA_PT_INFORMATION_AVAILABLE_ASC &&
|
||||||
|
+ sense[13] == ATA_PT_INFORMATION_AVAILABLE_ASCQ)) {
|
||||||
|
+ pr_vrb("Failed ata passthrough12 ioctl. Device: /dev/%s. Sense data ASC: %d, ASCQ: %d.\n",
|
||||||
|
+ fd2kname(disk_fd), sense[12], sense[13]);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_sec_prot_01h_supported_ata() - check if security protocol 01h supported for given SATA disk.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported,
|
||||||
|
+ * %DRIVE_FEAT_CHECK_FAILED_ST if failed.
|
||||||
|
+ */
|
||||||
|
+static drive_feat_sup_st is_sec_prot_01h_supported_ata(int disk_fd, const int verbose)
|
||||||
|
+{
|
||||||
|
+ supported_security_protocols_t security_protocols;
|
||||||
|
+
|
||||||
|
+ mdadm_status_t result = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_00,
|
||||||
|
+ 0x0, &security_protocols,
|
||||||
|
+ sizeof(security_protocols), verbose);
|
||||||
|
+ if (result)
|
||||||
|
+ return DRIVE_FEAT_CHECK_FAILED_ST;
|
||||||
|
+
|
||||||
|
+ if (is_sec_prot_01h_supported(&security_protocols))
|
||||||
|
+ return DRIVE_FEAT_SUP_ST;
|
||||||
|
+
|
||||||
|
+ return DRIVE_FEAT_NOT_SUP_ST;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_ata_trusted_computing_supported() - check if ata trusted computing supported.
|
||||||
|
+ * @buffer: buffer with ATA identify response, not NULL.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if trusted computing bit set, false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool is_ata_trusted_computing_supported(__u16 *buffer)
|
||||||
|
+{
|
||||||
|
+ /* Added due to warnings from the compiler about a possible uninitialized variable below. */
|
||||||
|
+ assert(buffer);
|
||||||
|
+
|
||||||
|
+ __u16 security_tc_frame = __le16_to_cpu(buffer[ATA_TRUSTED_COMPUTING_POS]);
|
||||||
|
+ ata_trusted_computing_t *security_tc = (ata_trusted_computing_t *)&security_tc_frame;
|
||||||
|
+
|
||||||
|
+ if (security_tc->tc_feature == 1)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_ata_standard_security_status() - get ATA disk encryption information from ATA identify.
|
||||||
|
+ * @buffer: buffer with response from ATA identify, not NULL.
|
||||||
|
+ * @information: struct to fill out, describing encryption status of disk.
|
||||||
|
+ *
|
||||||
|
+ * The function based on the Security status frame from ATA identify,
|
||||||
|
+ * completed encryption information.
|
||||||
|
+ * For possible encryption statuses and abilities,
|
||||||
|
+ * please refer to enums &encryption_status and &encryption_ability.
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t get_ata_standard_security_status(__u16 *buffer,
|
||||||
|
+ struct encryption_information *information)
|
||||||
|
+{
|
||||||
|
+ /* Added due to warnings from the compiler about a possible uninitialized variable below. */
|
||||||
|
+ assert(buffer);
|
||||||
|
+
|
||||||
|
+ __u16 security_status_frame = __le16_to_cpu(buffer[ATA_SECURITY_WORD_POSITION]);
|
||||||
|
+ ata_security_status_t *security_status = (ata_security_status_t *)&security_status_frame;
|
||||||
|
+
|
||||||
|
+ if (!security_status->security_supported) {
|
||||||
|
+ information->ability = ENC_ABILITY_NONE;
|
||||||
|
+ information->status = ENC_STATUS_UNENCRYPTED;
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ information->ability = ENC_ABILITY_OTHER;
|
||||||
|
+
|
||||||
|
+ if (security_status->security_enabled == 0)
|
||||||
|
+ information->status = ENC_STATUS_UNENCRYPTED;
|
||||||
|
+ else if (security_status->security_locked == 1)
|
||||||
|
+ information->status = ENC_STATUS_LOCKED;
|
||||||
|
+ else
|
||||||
|
+ information->status = ENC_STATUS_UNLOCKED;
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * is_ata_opal() - check if SATA disk support Opal.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @buffer: buffer with ATA identify response.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Return: %DRIVE_FEAT_SUP_ST if TCG_SECP_01 supported, %DRIVE_FEAT_NOT_SUP_ST if not supported,
|
||||||
|
+ * %DRIVE_FEAT_CHECK_FAILED_ST if failed to check.
|
||||||
|
+ */
|
||||||
|
+static drive_feat_sup_st is_ata_opal(int disk_fd, __u16 *buffer_identify, const int verbose)
|
||||||
|
+{
|
||||||
|
+ bool tc_status = is_ata_trusted_computing_supported(buffer_identify);
|
||||||
|
+ drive_feat_sup_st tcg_sec_prot_status;
|
||||||
|
+
|
||||||
|
+ if (!tc_status)
|
||||||
|
+ return DRIVE_FEAT_NOT_SUP_ST;
|
||||||
|
+
|
||||||
|
+ tcg_sec_prot_status = is_sec_prot_01h_supported_ata(disk_fd, verbose);
|
||||||
|
+
|
||||||
|
+ if (tcg_sec_prot_status == DRIVE_FEAT_CHECK_FAILED_ST) {
|
||||||
|
+ pr_vrb("Failed to verify if security protocol 01h supported. Device /dev/%s.\n",
|
||||||
|
+ fd2kname(disk_fd));
|
||||||
|
+ return DRIVE_FEAT_CHECK_FAILED_ST;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (tc_status && tcg_sec_prot_status == DRIVE_FEAT_SUP_ST)
|
||||||
|
+ return DRIVE_FEAT_SUP_ST;
|
||||||
|
+
|
||||||
|
+ return DRIVE_FEAT_NOT_SUP_ST;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_ata_encryption_information() - get ATA disk encryption information.
|
||||||
|
+ * @disk_fd: a disk file descriptor.
|
||||||
|
+ * @information: struct to fill out, describing encryption status of disk.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * The function reads information about encryption, if the disk supports Opal,
|
||||||
|
+ * the information is completed based on Opal Level 0 discovery, otherwise,
|
||||||
|
+ * based on ATA security status frame from ATA identification response.
|
||||||
|
+ * For possible encryption statuses and abilities,
|
||||||
|
+ * please refer to enums &encryption_status and &encryption_ability.
|
||||||
|
+ *
|
||||||
|
+ * Based on the documentations ATA/ATAPI Command Set ATA8-ACS and
|
||||||
|
+ * AT Attachment-8 - ATA Serial Transport (ATA8-AST).
|
||||||
|
+ *
|
||||||
|
+ * Return: %MDADM_STATUS_SUCCESS on success, %MDADM_STATUS_ERROR on fail.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t
|
||||||
|
+get_ata_encryption_information(int disk_fd, struct encryption_information *information,
|
||||||
|
+ const int verbose)
|
||||||
|
+{
|
||||||
|
+ __u8 buffer_opal_level0_discovery[OPAL_IO_BUFFER_LEN] = {0};
|
||||||
|
+ __u16 buffer_identify[ATA_IDENTIFY_RESPONSE_LEN] = {0};
|
||||||
|
+ drive_feat_sup_st ata_opal_status;
|
||||||
|
+ mdadm_status_t status;
|
||||||
|
+
|
||||||
|
+ /* Get disk ATA identification */
|
||||||
|
+ status = ata_pass_through12_ioctl(disk_fd, ATA_IDENTIFY, 0x0, 0x0, buffer_identify,
|
||||||
|
+ sizeof(buffer_identify), verbose);
|
||||||
|
+ if (status == MDADM_STATUS_ERROR)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ if (is_ata_trusted_computing_supported(buffer_identify) &&
|
||||||
|
+ !sysfs_is_libata_allow_tpm_enabled(verbose)) {
|
||||||
|
+ pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n");
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose);
|
||||||
|
+ if (ata_opal_status == DRIVE_FEAT_CHECK_FAILED_ST)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ if (ata_opal_status == DRIVE_FEAT_NOT_SUP_ST)
|
||||||
|
+ return get_ata_standard_security_status(buffer_identify, information);
|
||||||
|
+
|
||||||
|
+ /* SATA Opal */
|
||||||
|
+ status = ata_pass_through12_ioctl(disk_fd, ATA_TRUSTED_RECEIVE, TCG_SECP_01,
|
||||||
|
+ OPAL_DISCOVERY_COMID, buffer_opal_level0_discovery,
|
||||||
|
+ OPAL_IO_BUFFER_LEN, verbose);
|
||||||
|
+ if (status != MDADM_STATUS_SUCCESS)
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+
|
||||||
|
+ return get_opal_encryption_information(buffer_opal_level0_discovery, information);
|
||||||
|
+}
|
||||||
|
diff --git a/drive_encryption.h b/drive_encryption.h
|
||||||
|
index 82c2c624..77c7f10f 100644
|
||||||
|
--- a/drive_encryption.h
|
||||||
|
+++ b/drive_encryption.h
|
||||||
|
@@ -30,3 +30,6 @@ typedef struct encryption_information {
|
||||||
|
mdadm_status_t
|
||||||
|
get_nvme_opal_encryption_information(int disk_fd, struct encryption_information *information,
|
||||||
|
const int verbose);
|
||||||
|
+mdadm_status_t
|
||||||
|
+get_ata_encryption_information(int disk_fd, struct encryption_information *information,
|
||||||
|
+ const int verbose);
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index fbb161ba..52a66b9a 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -853,6 +853,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
|
||||||
|
int source, unsigned long long read_offset,
|
||||||
|
unsigned long long start, unsigned long long length,
|
||||||
|
char *src_buf);
|
||||||
|
+extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose);
|
||||||
|
|
||||||
|
#ifndef Sendmail
|
||||||
|
#define Sendmail "/usr/lib/sendmail -t"
|
||||||
|
diff --git a/sysfs.c b/sysfs.c
|
||||||
|
index 4ded1672..20fe1e9e 100644
|
||||||
|
--- a/sysfs.c
|
||||||
|
+++ b/sysfs.c
|
||||||
|
@@ -1121,3 +1121,32 @@ void sysfsline(char *line)
|
||||||
|
sr->next = sysfs_rules;
|
||||||
|
sysfs_rules = sr;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * sysfs_is_libata_allow_tpm_enabled() - check if libata allow_tmp is enabled.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * Check if libata allow_tmp flag is set, this is required for SATA Opal Security commands to work.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if allow_tpm enable, false otherwise.
|
||||||
|
+ */
|
||||||
|
+bool sysfs_is_libata_allow_tpm_enabled(const int verbose)
|
||||||
|
+{
|
||||||
|
+ const char *path = "/sys/module/libata/parameters/allow_tpm";
|
||||||
|
+ const char *expected_value = "1";
|
||||||
|
+ int fd = open(path, O_RDONLY);
|
||||||
|
+ char buf[3];
|
||||||
|
+
|
||||||
|
+ if (!is_fd_valid(fd)) {
|
||||||
|
+ pr_vrb("Failed open file descriptor to %s. Cannot check libata allow_tpm param.\n",
|
||||||
|
+ path);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sysfs_fd_get_str(fd, buf, sizeof(buf));
|
||||||
|
+ close(fd);
|
||||||
|
+
|
||||||
|
+ if (strncmp(buf, expected_value, 1) == 0)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
163
0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch
Normal file
163
0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
From 336e13fc5ef43bc5b4633a9dadac5f7208e6c241 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:18 +0100
|
||||||
|
Subject: [PATCH 45/69] Add key ENCRYPTION_NO_VERIFY to conf
|
||||||
|
|
||||||
|
Add ENCRYPTION_NO_VERIFY config key and allow to disable checking
|
||||||
|
encryption status for given type of drives.
|
||||||
|
|
||||||
|
The key is introduced because of SATA Opal disks for which TPM commands
|
||||||
|
must be enabled in libata kernel module, (libata.allow_tpm=1), otherwise
|
||||||
|
it is impossible to verify encryption status. TPM commands are disabled by
|
||||||
|
default.
|
||||||
|
|
||||||
|
Currently the key only supports the "sata_opal" value, if necessary,
|
||||||
|
the functionality is ready to support more types of disks. This
|
||||||
|
functionality will be used in the next patches.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
config.c | 25 ++++++++++++++++++++++++-
|
||||||
|
drive_encryption.c | 16 ++++++++++++----
|
||||||
|
mdadm.conf.5.in | 13 +++++++++++++
|
||||||
|
mdadm.h | 1 +
|
||||||
|
4 files changed, 50 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.c b/config.c
|
||||||
|
index 44f7dd2f..b46d71cb 100644
|
||||||
|
--- a/config.c
|
||||||
|
+++ b/config.c
|
||||||
|
@@ -81,7 +81,7 @@ char DefaultAltConfDir[] = CONFFILE2 ".d";
|
||||||
|
|
||||||
|
enum linetype { Devices, Array, Mailaddr, Mailfrom, Program, CreateDev,
|
||||||
|
Homehost, HomeCluster, AutoMode, Policy, PartPolicy, Sysfs,
|
||||||
|
- MonitorDelay, LTEnd };
|
||||||
|
+ MonitorDelay, EncryptionNoVerify, LTEnd };
|
||||||
|
char *keywords[] = {
|
||||||
|
[Devices] = "devices",
|
||||||
|
[Array] = "array",
|
||||||
|
@@ -96,6 +96,7 @@ char *keywords[] = {
|
||||||
|
[PartPolicy]="part-policy",
|
||||||
|
[Sysfs] = "sysfs",
|
||||||
|
[MonitorDelay] = "monitordelay",
|
||||||
|
+ [EncryptionNoVerify] = "ENCRYPTION_NO_VERIFY",
|
||||||
|
[LTEnd] = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -729,6 +730,19 @@ void monitordelayline(char *line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool sata_opal_encryption_no_verify;
|
||||||
|
+void encryption_no_verify_line(char *line)
|
||||||
|
+{
|
||||||
|
+ char *word;
|
||||||
|
+
|
||||||
|
+ for (word = dl_next(line); word != line; word = dl_next(word)) {
|
||||||
|
+ if (strcasecmp(word, "sata_opal") == 0)
|
||||||
|
+ sata_opal_encryption_no_verify = true;
|
||||||
|
+ else
|
||||||
|
+ pr_err("unrecognised word on ENCRYPTION_NO_VERIFY line: %s\n", word);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
char auto_yes[] = "yes";
|
||||||
|
char auto_no[] = "no";
|
||||||
|
char auto_homehost[] = "homehost";
|
||||||
|
@@ -913,6 +927,9 @@ void conf_file(FILE *f)
|
||||||
|
case MonitorDelay:
|
||||||
|
monitordelayline(line);
|
||||||
|
break;
|
||||||
|
+ case EncryptionNoVerify:
|
||||||
|
+ encryption_no_verify_line(line);
|
||||||
|
+ break;
|
||||||
|
default:
|
||||||
|
pr_err("Unknown keyword %s\n", line);
|
||||||
|
}
|
||||||
|
@@ -1075,6 +1092,12 @@ int conf_get_monitor_delay(void)
|
||||||
|
return monitor_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool conf_get_sata_opal_encryption_no_verify(void)
|
||||||
|
+{
|
||||||
|
+ load_conffile();
|
||||||
|
+ return sata_opal_encryption_no_verify;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct createinfo *conf_get_create_info(void)
|
||||||
|
{
|
||||||
|
load_conffile();
|
||||||
|
diff --git a/drive_encryption.c b/drive_encryption.c
|
||||||
|
index d520f0c7..6b2bd358 100644
|
||||||
|
--- a/drive_encryption.c
|
||||||
|
+++ b/drive_encryption.c
|
||||||
|
@@ -656,10 +656,18 @@ get_ata_encryption_information(int disk_fd, struct encryption_information *infor
|
||||||
|
if (status == MDADM_STATUS_ERROR)
|
||||||
|
return MDADM_STATUS_ERROR;
|
||||||
|
|
||||||
|
- if (is_ata_trusted_computing_supported(buffer_identify) &&
|
||||||
|
- !sysfs_is_libata_allow_tpm_enabled(verbose)) {
|
||||||
|
- pr_vrb("For SATA with Trusted Computing support, required libata.tpm_enabled=1.\n");
|
||||||
|
- return MDADM_STATUS_ERROR;
|
||||||
|
+ /* Possible OPAL support, further checks require tpm_enabled.*/
|
||||||
|
+ if (is_ata_trusted_computing_supported(buffer_identify)) {
|
||||||
|
+ /* OPAL SATA encryption checking disabled. */
|
||||||
|
+ if (conf_get_sata_opal_encryption_no_verify())
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+
|
||||||
|
+ if (!sysfs_is_libata_allow_tpm_enabled(verbose)) {
|
||||||
|
+ pr_vrb("Detected SATA drive /dev/%s with Trusted Computing support.\n",
|
||||||
|
+ fd2kname(disk_fd));
|
||||||
|
+ pr_vrb("Cannot verify encryption state. Requires libata.tpm_enabled=1.\n");
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
ata_opal_status = is_ata_opal(disk_fd, buffer_identify, verbose);
|
||||||
|
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
|
||||||
|
index 787e51e9..afb0a296 100644
|
||||||
|
--- a/mdadm.conf.5.in
|
||||||
|
+++ b/mdadm.conf.5.in
|
||||||
|
@@ -636,6 +636,17 @@ If multiple
|
||||||
|
.B MINITORDELAY
|
||||||
|
lines are provided, only first non-zero value is considered.
|
||||||
|
|
||||||
|
+.TP
|
||||||
|
+.B ENCRYPTION_NO_VERIFY
|
||||||
|
+The
|
||||||
|
+.B ENCRYPTION_NO_VERIFY
|
||||||
|
+disables encryption verification for devices with particular encryption support detected.
|
||||||
|
+Currently, only verification of SATA OPAL encryption can be disabled.
|
||||||
|
+It does not disable ATA security encryption verification.
|
||||||
|
+Available parameter
|
||||||
|
+.I "sata_opal".
|
||||||
|
+
|
||||||
|
+
|
||||||
|
.SH FILES
|
||||||
|
|
||||||
|
.SS {CONFFILE}
|
||||||
|
@@ -744,6 +755,8 @@ SYSFS uuid=bead5eb6:31c17a27:da120ba2:7dfda40d group_thread_cnt=4
|
||||||
|
sync_speed_max=1000000
|
||||||
|
.br
|
||||||
|
MONITORDELAY 60
|
||||||
|
+.br
|
||||||
|
+ENCRYPTION_NO_VERIFY sata_opal
|
||||||
|
|
||||||
|
.SH SEE ALSO
|
||||||
|
.BR mdadm (8),
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 52a66b9a..2640b396 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1673,6 +1673,7 @@ extern char *conf_get_program(void);
|
||||||
|
extern char *conf_get_homehost(int *require_homehostp);
|
||||||
|
extern char *conf_get_homecluster(void);
|
||||||
|
extern int conf_get_monitor_delay(void);
|
||||||
|
+extern bool conf_get_sata_opal_encryption_no_verify(void);
|
||||||
|
extern char *conf_line(FILE *file);
|
||||||
|
extern char *conf_word(FILE *file, int allow_key);
|
||||||
|
extern void print_quoted(char *str);
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
217
0046-imsm-print-disk-encryption-information.patch
Normal file
217
0046-imsm-print-disk-encryption-information.patch
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
From bf62ed5d9642aa60abf4ac2d1d89f173bd66ae48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:19 +0100
|
||||||
|
Subject: [PATCH 46/69] imsm: print disk encryption information
|
||||||
|
|
||||||
|
Print SATA/NVMe disk encryption information in --detail-platform.
|
||||||
|
Encryption Ability and Status will be printed for each disk.
|
||||||
|
|
||||||
|
There is one exception, Opal SATA drives encryption is not checked when
|
||||||
|
ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this
|
||||||
|
reason such drives are treated as without encryption support.
|
||||||
|
|
||||||
|
To test this feature, drives SATA/NVMe with Opal support or SATA drives
|
||||||
|
with encryption support have to be used.
|
||||||
|
|
||||||
|
Example outputs of --detail-platform:
|
||||||
|
|
||||||
|
Non Opal, encryption enabled, SATA drive:
|
||||||
|
Port0 : /dev/sdc (CVPR050600G3120LGN)
|
||||||
|
Encryption(Ability|Status): Other|Unlocked
|
||||||
|
|
||||||
|
NVMe drive without Opal support:
|
||||||
|
NVMe under VMD : /dev/nvme2n1 (PHLF737302GB1P0GGN)
|
||||||
|
Encryption(Ability|Status): None|Unencrypted
|
||||||
|
|
||||||
|
Unencrypted SATA drive with OPAL support:
|
||||||
|
|
||||||
|
- default allow_tpm, we will get an error from mdadm:
|
||||||
|
Port6 : /dev/sdi (CVTS4246015V180IGN)
|
||||||
|
mdadm: Detected SATA drive /dev/sdi with Trusted Computing support.
|
||||||
|
mdadm: Cannot verify encryption state. Requires libata.tpm_enabled=1.
|
||||||
|
mdadm: Failed to get drive encrytpion information.
|
||||||
|
|
||||||
|
- default "allow_tpm" and config entry "ENCRYPTION_NO_VERIFY sata_opal":
|
||||||
|
Port6 : /dev/sdi (CVTS4246015V180IGN)
|
||||||
|
Encryption(Ability|Status): None|Unencrypted
|
||||||
|
|
||||||
|
- added "libata.allow_tpm=1" to boot parameters(requires reboot),
|
||||||
|
the status will be read correctly:
|
||||||
|
Port6 : /dev/sdi (CVTS4246015V180IGN)
|
||||||
|
Encryption(Ability|Status): SED|Unencrypted
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
drive_encryption.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||||
|
drive_encryption.h | 2 ++
|
||||||
|
mdadm.conf.5.in | 3 +++
|
||||||
|
super-intel.c | 42 ++++++++++++++++++++++++++++++++++++++----
|
||||||
|
4 files changed, 79 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drive_encryption.c b/drive_encryption.c
|
||||||
|
index 6b2bd358..27da9621 100644
|
||||||
|
--- a/drive_encryption.c
|
||||||
|
+++ b/drive_encryption.c
|
||||||
|
@@ -141,6 +141,42 @@ typedef struct ata_trusted_computing {
|
||||||
|
__u16 var2 : 1;
|
||||||
|
} __attribute__((__packed__)) ata_trusted_computing_t;
|
||||||
|
|
||||||
|
+mapping_t encryption_ability_map[] = {
|
||||||
|
+ { "None", ENC_ABILITY_NONE },
|
||||||
|
+ { "Other", ENC_ABILITY_OTHER },
|
||||||
|
+ { "SED", ENC_ABILITY_SED },
|
||||||
|
+ { NULL, UnSet }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+mapping_t encryption_status_map[] = {
|
||||||
|
+ { "Unencrypted", ENC_STATUS_UNENCRYPTED },
|
||||||
|
+ { "Locked", ENC_STATUS_LOCKED },
|
||||||
|
+ { "Unlocked", ENC_STATUS_UNLOCKED },
|
||||||
|
+ { NULL, UnSet }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_encryption_ability_string() - get encryption ability name string.
|
||||||
|
+ * @ability: encryption ability enum.
|
||||||
|
+ *
|
||||||
|
+ * Return: encryption ability string.
|
||||||
|
+ */
|
||||||
|
+const char *get_encryption_ability_string(enum encryption_ability ability)
|
||||||
|
+{
|
||||||
|
+ return map_num_s(encryption_ability_map, ability);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * get_encryption_status_string() - get encryption status name string.
|
||||||
|
+ * @ability: encryption status enum.
|
||||||
|
+ *
|
||||||
|
+ * Return: encryption status string.
|
||||||
|
+ */
|
||||||
|
+const char *get_encryption_status_string(enum encryption_status status)
|
||||||
|
+{
|
||||||
|
+ return map_num_s(encryption_status_map, status);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* get_opal_locking_feature_description() - get opal locking feature description.
|
||||||
|
* @response: response from Opal Discovery Level 0.
|
||||||
|
diff --git a/drive_encryption.h b/drive_encryption.h
|
||||||
|
index 77c7f10f..0cb8ff1b 100644
|
||||||
|
--- a/drive_encryption.h
|
||||||
|
+++ b/drive_encryption.h
|
||||||
|
@@ -33,3 +33,5 @@ get_nvme_opal_encryption_information(int disk_fd, struct encryption_information
|
||||||
|
mdadm_status_t
|
||||||
|
get_ata_encryption_information(int disk_fd, struct encryption_information *information,
|
||||||
|
const int verbose);
|
||||||
|
+const char *get_encryption_ability_string(enum encryption_ability ability);
|
||||||
|
+const char *get_encryption_status_string(enum encryption_status status);
|
||||||
|
diff --git a/mdadm.conf.5.in b/mdadm.conf.5.in
|
||||||
|
index afb0a296..14302a91 100644
|
||||||
|
--- a/mdadm.conf.5.in
|
||||||
|
+++ b/mdadm.conf.5.in
|
||||||
|
@@ -643,6 +643,9 @@ The
|
||||||
|
disables encryption verification for devices with particular encryption support detected.
|
||||||
|
Currently, only verification of SATA OPAL encryption can be disabled.
|
||||||
|
It does not disable ATA security encryption verification.
|
||||||
|
+Currently effective only for
|
||||||
|
+.I IMSM
|
||||||
|
+metadata.
|
||||||
|
Available parameter
|
||||||
|
.I "sata_opal".
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 212387ec..fbd1c11f 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include <scsi/sg.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
+#include "drive_encryption.h"
|
||||||
|
|
||||||
|
/* MPB == Metadata Parameter Block */
|
||||||
|
#define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. "
|
||||||
|
@@ -2349,12 +2350,41 @@ static int imsm_read_serial(int fd, char *devname, __u8 *serial,
|
||||||
|
size_t serial_buf_len);
|
||||||
|
static void fd2devname(int fd, char *name);
|
||||||
|
|
||||||
|
-static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose)
|
||||||
|
+void print_encryption_information(int disk_fd, enum sys_dev_type hba_type)
|
||||||
|
+{
|
||||||
|
+ struct encryption_information information = {0};
|
||||||
|
+ mdadm_status_t status = MDADM_STATUS_SUCCESS;
|
||||||
|
+ const char *indent = " ";
|
||||||
|
+
|
||||||
|
+ switch (hba_type) {
|
||||||
|
+ case SYS_DEV_VMD:
|
||||||
|
+ case SYS_DEV_NVME:
|
||||||
|
+ status = get_nvme_opal_encryption_information(disk_fd, &information, 1);
|
||||||
|
+ break;
|
||||||
|
+ case SYS_DEV_SATA:
|
||||||
|
+ case SYS_DEV_SATA_VMD:
|
||||||
|
+ status = get_ata_encryption_information(disk_fd, &information, 1);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (status) {
|
||||||
|
+ pr_err("Failed to get drive encryption information.\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ printf("%sEncryption(Ability|Status): %s|%s\n", indent,
|
||||||
|
+ get_encryption_ability_string(information.ability),
|
||||||
|
+ get_encryption_status_string(information.status));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int ahci_enumerate_ports(struct sys_dev *hba, int port_count, int host_base, int verbose)
|
||||||
|
{
|
||||||
|
/* dump an unsorted list of devices attached to AHCI Intel storage
|
||||||
|
* controller, as well as non-connected ports
|
||||||
|
*/
|
||||||
|
- int hba_len = strlen(hba_path) + 1;
|
||||||
|
+ int hba_len = strlen(hba->path) + 1;
|
||||||
|
struct dirent *ent;
|
||||||
|
DIR *dir;
|
||||||
|
char *path = NULL;
|
||||||
|
@@ -2390,7 +2420,7 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
|
||||||
|
path = devt_to_devpath(makedev(major, minor), 1, NULL);
|
||||||
|
if (!path)
|
||||||
|
continue;
|
||||||
|
- if (!path_attached_to_hba(path, hba_path)) {
|
||||||
|
+ if (!path_attached_to_hba(path, hba->path)) {
|
||||||
|
free(path);
|
||||||
|
path = NULL;
|
||||||
|
continue;
|
||||||
|
@@ -2493,6 +2523,8 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b
|
||||||
|
printf(" (%s)\n", buf);
|
||||||
|
else
|
||||||
|
printf(" ()\n");
|
||||||
|
+
|
||||||
|
+ print_encryption_information(fd, hba->type);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
@@ -2557,6 +2589,8 @@ static int print_nvme_info(struct sys_dev *hba)
|
||||||
|
else
|
||||||
|
printf("()\n");
|
||||||
|
|
||||||
|
+ print_encryption_information(fd, hba->type);
|
||||||
|
+
|
||||||
|
skip:
|
||||||
|
close_fd(&fd);
|
||||||
|
}
|
||||||
|
@@ -2812,7 +2846,7 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle
|
||||||
|
hba->path, get_sys_dev_type(hba->type));
|
||||||
|
if (hba->type == SYS_DEV_SATA || hba->type == SYS_DEV_SATA_VMD) {
|
||||||
|
host_base = ahci_get_port_count(hba->path, &port_count);
|
||||||
|
- if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
|
||||||
|
+ if (ahci_enumerate_ports(hba, port_count, host_base, verbose)) {
|
||||||
|
if (verbose > 0)
|
||||||
|
pr_err("failed to enumerate ports on %s controller at %s.\n",
|
||||||
|
get_sys_dev_type(hba->type), hba->pci_id);
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
114
0047-imsm-drive-encryption-policy-implementation.patch
Normal file
114
0047-imsm-drive-encryption-policy-implementation.patch
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
From acb8f13be88c224eb1e01f72c1e1fda955bc80ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Fri, 22 Mar 2024 12:51:20 +0100
|
||||||
|
Subject: [PATCH 47/69] imsm: drive encryption policy implementation
|
||||||
|
|
||||||
|
IMSM cares about drive encryption state. It is not allowed to mix disks
|
||||||
|
with different encryption state within one md device. This policy will
|
||||||
|
verify that attempt to use disks with different encryption states will
|
||||||
|
fail. Verification is performed for devices NVMe/SATA Opal and SATA.
|
||||||
|
|
||||||
|
There is one exception, Opal SATA drives encryption is not checked when
|
||||||
|
ENCRYPTION_NO_VERIFY key with "sata_opal" value is set in conf, for this
|
||||||
|
reason such drives are treated as without encryption support.
|
||||||
|
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
super-intel.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 73 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index fbd1c11f..1faab607 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -11291,6 +11291,78 @@ test_and_add_drive_controller_policy_imsm(const char * const type, dev_policy_t
|
||||||
|
return MDADM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * test_and_add_drive_encryption_policy_imsm() - add disk encryption to policies list.
|
||||||
|
+ * @type: policy type to search in the list.
|
||||||
|
+ * @pols: list of currently recorded policies.
|
||||||
|
+ * @disk_fd: file descriptor of the device to check.
|
||||||
|
+ * @hba: The hba to which the drive is attached, could be NULL if verification is disabled.
|
||||||
|
+ * @verbose: verbose flag.
|
||||||
|
+ *
|
||||||
|
+ * IMSM cares about drive encryption state. It is not allowed to mix disks with different
|
||||||
|
+ * encryption state within one md device.
|
||||||
|
+ * If there is no encryption policy on pols we are free to add first one.
|
||||||
|
+ * If there is a policy then, new must be the same.
|
||||||
|
+ */
|
||||||
|
+static mdadm_status_t
|
||||||
|
+test_and_add_drive_encryption_policy_imsm(const char * const type, dev_policy_t **pols, int disk_fd,
|
||||||
|
+ struct sys_dev *hba, const int verbose)
|
||||||
|
+{
|
||||||
|
+ struct dev_policy *expected_policy = pol_find(*pols, (char *)type);
|
||||||
|
+ struct encryption_information information = {0};
|
||||||
|
+ char *encryption_state = "Unknown";
|
||||||
|
+ int status = MDADM_STATUS_SUCCESS;
|
||||||
|
+ bool encryption_checked = true;
|
||||||
|
+ char devname[PATH_MAX];
|
||||||
|
+
|
||||||
|
+ if (!hba)
|
||||||
|
+ goto check_policy;
|
||||||
|
+
|
||||||
|
+ switch (hba->type) {
|
||||||
|
+ case SYS_DEV_NVME:
|
||||||
|
+ case SYS_DEV_VMD:
|
||||||
|
+ status = get_nvme_opal_encryption_information(disk_fd, &information, verbose);
|
||||||
|
+ break;
|
||||||
|
+ case SYS_DEV_SATA:
|
||||||
|
+ case SYS_DEV_SATA_VMD:
|
||||||
|
+ status = get_ata_encryption_information(disk_fd, &information, verbose);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ encryption_checked = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (status) {
|
||||||
|
+ fd2devname(disk_fd, devname);
|
||||||
|
+ pr_vrb("Failed to read encryption information of device %s\n", devname);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (encryption_checked) {
|
||||||
|
+ if (information.status == ENC_STATUS_LOCKED) {
|
||||||
|
+ fd2devname(disk_fd, devname);
|
||||||
|
+ pr_vrb("Device %s is in Locked state, cannot use. Aborting.\n", devname);
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+ encryption_state = (char *)get_encryption_status_string(information.status);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+check_policy:
|
||||||
|
+ if (expected_policy) {
|
||||||
|
+ if (strcmp(expected_policy->value, encryption_state) == 0)
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+
|
||||||
|
+ fd2devname(disk_fd, devname);
|
||||||
|
+ pr_vrb("Encryption status \"%s\" detected for disk %s, but \"%s\" status was detected eariler.\n",
|
||||||
|
+ encryption_state, devname, expected_policy->value);
|
||||||
|
+ pr_vrb("Disks with different encryption status cannot be used.\n");
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pol_add(pols, (char *)type, encryption_state, "imsm");
|
||||||
|
+
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct imsm_drive_policy {
|
||||||
|
char *type;
|
||||||
|
mdadm_status_t (*test_and_add_drive_policy)(const char * const type,
|
||||||
|
@@ -11300,6 +11372,7 @@ struct imsm_drive_policy {
|
||||||
|
|
||||||
|
struct imsm_drive_policy imsm_policies[] = {
|
||||||
|
{"controller", test_and_add_drive_controller_policy_imsm},
|
||||||
|
+ {"encryption", test_and_add_drive_encryption_policy_imsm}
|
||||||
|
};
|
||||||
|
|
||||||
|
mdadm_status_t test_and_add_drive_policies_imsm(struct dev_policy **pols, int disk_fd,
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
2010
0048-mdadm-add-CHANGELOG.md.patch
Normal file
2010
0048-mdadm-add-CHANGELOG.md.patch
Normal file
File diff suppressed because it is too large
Load Diff
66
0049-mdadm-Add-MAINTAINERS.md.patch
Normal file
66
0049-mdadm-Add-MAINTAINERS.md.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From 21d6c5d96a5a467b5877ba1d38106b3746005bcc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Tue, 26 Mar 2024 13:21:11 +0100
|
||||||
|
Subject: [PATCH 49/69] mdadm: Add MAINTAINERS.md
|
||||||
|
|
||||||
|
Describe rules maintainer should follow.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
MAINTAINERS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 44 insertions(+)
|
||||||
|
create mode 100644 MAINTAINERS.md
|
||||||
|
|
||||||
|
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..9c79ba87
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/MAINTAINERS.md
|
||||||
|
@@ -0,0 +1,44 @@
|
||||||
|
+# Maintainer tools
|
||||||
|
+
|
||||||
|
+Useful tools used in daily routines:
|
||||||
|
+- [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html)
|
||||||
|
+- [kup](https://korg.docs.kernel.org/kup.html)
|
||||||
|
+- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer)
|
||||||
|
+- [b4](https://b4.docs.kernel.org/en/latest/)
|
||||||
|
+
|
||||||
|
+# Checklist before applying patch
|
||||||
|
+
|
||||||
|
+We don't have CI testing yet, so all those steps must be performed manually:
|
||||||
|
+- Style check with [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html):
|
||||||
|
+
|
||||||
|
+ This is the current code style follows. We are not strict to all rules. It must be run
|
||||||
|
+ by **checkpatch --no-tree**, see README.md.
|
||||||
|
+
|
||||||
|
+- [Commit style](https://www.kernel.org/doc/html/v4.10/process/submitting-patches.html):
|
||||||
|
+
|
||||||
|
+ It doesn't need to be followed as strictly as is in kernel but changes should be logically
|
||||||
|
+ separated. Submitter should care at least to mention "It is used in next patches" if unused
|
||||||
|
+ externs/files are added in patch. We love: *Reported-by:*, *Suggested-by:*, *Fixes:* tags.
|
||||||
|
+
|
||||||
|
+- Compilation, ideally on various gcc versions.
|
||||||
|
+- Mdadm test suite execution.
|
||||||
|
+- Consider requesting new tests from submitter, especially for new functionalities.
|
||||||
|
+- Ensure that maintainer *sign-off* is added, before pushing.
|
||||||
|
+
|
||||||
|
+# Making a release
|
||||||
|
+
|
||||||
|
+Assuming that maintainer is certain that release is safe, following steps must be done:
|
||||||
|
+
|
||||||
|
+- Update versions strings in release commit, please refer to previous releases for examples.
|
||||||
|
+
|
||||||
|
+- Create GPG signed tag and push it to repo. Use same format as was used previously, prefixed by
|
||||||
|
+ **mdadm-**, e.g. **mdadm-3.1.2**, **mdadm-4.1**.
|
||||||
|
+
|
||||||
|
+- [Auto-publishing](https://korg.docs.kernel.org/kup.html#auto-publishing-with-git-archive-signer):
|
||||||
|
+
|
||||||
|
+ Adopt script to our release tag model. When ready, push signed note to repository. If it is done
|
||||||
|
+ correctly, then *(sig)* is added to the package automatically generated by kernel.org automation.
|
||||||
|
+ There is no need to upload archive manually.
|
||||||
|
+
|
||||||
|
+- Update CHANGELOG.md.
|
||||||
|
+- Write "ANNOUNCE" mail to linux-raid@kernel.org to notify community.
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
106
0050-mdadm-Add-README.md.patch
Normal file
106
0050-mdadm-Add-README.md.patch
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
From 256edaef3d43a112356762aaea4a48f021f45aec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Date: Tue, 26 Mar 2024 13:21:12 +0100
|
||||||
|
Subject: [PATCH 50/69] mdadm: Add README.md
|
||||||
|
|
||||||
|
Describe supported metadata types, add step-by-step patch sending
|
||||||
|
instruction, mention minimally supported kernel version and licensing.
|
||||||
|
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
README.md | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 83 insertions(+)
|
||||||
|
create mode 100644 README.md
|
||||||
|
|
||||||
|
diff --git a/README.md b/README.md
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000..64f2ecec
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/README.md
|
||||||
|
@@ -0,0 +1,83 @@
|
||||||
|
+**mdadm** is a utility used to create and manage **software RAID** devices implemented through
|
||||||
|
+**Multiple devices driver (MD)** in kernel. It supports following RAID metadata formats:
|
||||||
|
+
|
||||||
|
+* [Linux native RAID](https://raid.wiki.kernel.org/index.php/RAID_superblock_formats):
|
||||||
|
+
|
||||||
|
+ Known as **native** or **native RAID**. First and default metadata format. Metadata management
|
||||||
|
+ is implemented in **MD driver**.
|
||||||
|
+
|
||||||
|
+* Matrix Storage Manager Support (no reference, metadata format documentation is proprietary).
|
||||||
|
+
|
||||||
|
+ Known as **IMSM**. Metadata format developed and maintained by **Intel®** as a part of **VROC**
|
||||||
|
+ solution. There are some functional differences between **native** and **imsm**. The most
|
||||||
|
+ important difference is that the metadata is managed from userspace.
|
||||||
|
+
|
||||||
|
+ **CAUTION:** **imsm** is compatible with **Intel RST**, however it is not officially supported.
|
||||||
|
+ You are using it on your own risk.
|
||||||
|
+
|
||||||
|
+* [Common RAID DDF Specification Revision](https://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf)
|
||||||
|
+
|
||||||
|
+ **IMPORTANT:** DDF is in **maintenance only** mode. There is no active development around it.
|
||||||
|
+ Please do not use it in new solutions.
|
||||||
|
+
|
||||||
|
+# How to Contribute
|
||||||
|
+
|
||||||
|
+ **mdadm** is hosted on [kernel.org](https://kernel.org/). You can access repository
|
||||||
|
+[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git).
|
||||||
|
+
|
||||||
|
+It is maintained similarly to kernel, using *mailing list*. Patches must be send through email.
|
||||||
|
+Please familiarize with general kernel
|
||||||
|
+[submitting patches](https://www.kernel.org/doc/html/v4.17/process/submitting-patches.html)
|
||||||
|
+documentation. Formatting, tags and commit message guidelines applies to **mdadm**.
|
||||||
|
+
|
||||||
|
+## Sending patches step-by-step
|
||||||
|
+
|
||||||
|
+To maximize change of patches being taken, follow this instruction when submitting:
|
||||||
|
+
|
||||||
|
+1. Create possibly logically separated commits and generate patches:
|
||||||
|
+
|
||||||
|
+ Use ``git format-patch --cover-letter --signoff -v <nr>`` to create patches:
|
||||||
|
+ * ``--cover-letter`` can be skipped if it is only one patch;
|
||||||
|
+ * ``--signoff`` adds sign-off tag;
|
||||||
|
+ * ``-v <nr>`` indicates review revision number, sender should increment it before resending.
|
||||||
|
+
|
||||||
|
+2. Check style of every patch with kernel
|
||||||
|
+ [checkpatch](https://docs.kernel.org/dev-tools/checkpatch.html) script:
|
||||||
|
+
|
||||||
|
+ It is important to keep same coding style that is why in **mdadm**
|
||||||
|
+ [kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html)
|
||||||
|
+ is preferred. ``checkpath --no-tree <patch_file>`` can be used to verify patches.
|
||||||
|
+ Following checkpatch issues can be ignored:
|
||||||
|
+ - New typedefs.
|
||||||
|
+ - comparing with *True/False*.
|
||||||
|
+ - kernel *MAINTAINERS* file warning.
|
||||||
|
+ - *extern* keyword in headers.
|
||||||
|
+
|
||||||
|
+3. Send patches using ``git send-mail --to=linux-raid@vger.kernel.org <cover-letter> <patch1> <patch2> (...)``
|
||||||
|
+
|
||||||
|
+# Maintainers
|
||||||
|
+
|
||||||
|
+It is good practice to add **mdadm maintainers** to recipients for patches:
|
||||||
|
+
|
||||||
|
+- Jes Sorensen <jes@trained-monkey.org>;
|
||||||
|
+- Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>;
|
||||||
|
+
|
||||||
|
+Adding **MD maintainers** could be reasonable, especially if patches may affect MD driver:
|
||||||
|
+
|
||||||
|
+- Song Liu <song@kernel.org>;
|
||||||
|
+- Yu Kuai <yukuai3@huawei.com>;
|
||||||
|
+
|
||||||
|
+# Reviewers
|
||||||
|
+
|
||||||
|
+**mdadm** utility is not part of kernel tree, so there is no certificated *Reviewers* list. Everyone
|
||||||
|
+can comment on mailing list, last decision (and merging) belongs to maintainers.
|
||||||
|
+
|
||||||
|
+# Minimal supported kernel version
|
||||||
|
+
|
||||||
|
+We do not support kernel versions below **v3.10**. Please be aware that maintainers may remove
|
||||||
|
+workarounds and fixes for legacy issues.
|
||||||
|
+
|
||||||
|
+# License
|
||||||
|
+
|
||||||
|
+It is released under the terms of the **GNU General Public License version 2** as published
|
||||||
|
+by the **Free Software Foundation**.
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
41
0051-Create.c-fix-uclibc-build.patch
Normal file
41
0051-Create.c-fix-uclibc-build.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From 52bead95d2957437c691891fcdc49bd6afccdd49 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||||
|
Date: Fri, 12 Apr 2024 18:45:13 +0200
|
||||||
|
Subject: [PATCH 51/69] Create.c: fix uclibc build
|
||||||
|
|
||||||
|
Define FALLOC_FL_ZERO_RANGE if needed as FALLOC_FL_ZERO_RANGE is only
|
||||||
|
defined for aarch64 on uclibc-ng resulting in the following or1k build
|
||||||
|
failure since commit 577fd10486d8d1472a6b559066f344ac30a3a391:
|
||||||
|
|
||||||
|
Create.c: In function 'write_zeroes_fork':
|
||||||
|
Create.c:155:35: error: 'FALLOC_FL_ZERO_RANGE' undeclared (first use in this function)
|
||||||
|
155 | if (fallocate(fd, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE,
|
||||||
|
| ^~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Fixes:
|
||||||
|
- http://autobuild.buildroot.org/results/0e04bcdb591ca5642053e1f7e31384f06581e989
|
||||||
|
|
||||||
|
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Create.c | 4 ++++
|
||||||
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index 4397ff49..d94253b1 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -32,6 +32,10 @@
|
||||||
|
#include <sys/signalfd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
+#ifndef FALLOC_FL_ZERO_RANGE
|
||||||
|
+#define FALLOC_FL_ZERO_RANGE 16
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int round_size_and_verify(unsigned long long *size, int chunk)
|
||||||
|
{
|
||||||
|
if (*size == 0)
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
309
0052-mdadm-pass-struct-context-for-external-reshapes.patch
Normal file
309
0052-mdadm-pass-struct-context-for-external-reshapes.patch
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
From bdc2c56998abf76141294b04facf20217cfd1911 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:13 +0200
|
||||||
|
Subject: [PATCH 52/69] mdadm: pass struct context for external reshapes
|
||||||
|
|
||||||
|
This patch alters mutiple functions calls so the context is passed to
|
||||||
|
external reshape functions.
|
||||||
|
|
||||||
|
There are two main reasons behind it:
|
||||||
|
- reduces number of arguments passed and unifies them,
|
||||||
|
- imsm code will make use of context in incoming patches.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Assemble.c | 7 ++----
|
||||||
|
Grow.c | 68 +++++++++++++++++++++------------------------------
|
||||||
|
mdadm.c | 2 +-
|
||||||
|
mdadm.h | 11 +++------
|
||||||
|
super-intel.c | 6 ++---
|
||||||
|
5 files changed, 37 insertions(+), 57 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index f6c5b99e..f5e9ab1f 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -1197,9 +1197,7 @@ static int start_array(int mdfd,
|
||||||
|
rv = sysfs_set_str(content, NULL,
|
||||||
|
"array_state", "readonly");
|
||||||
|
if (rv == 0)
|
||||||
|
- rv = Grow_continue(mdfd, st, content,
|
||||||
|
- c->backup_file, 0,
|
||||||
|
- c->freeze_reshape);
|
||||||
|
+ rv = Grow_continue(mdfd, st, content, 0, c);
|
||||||
|
} else if (c->readonly &&
|
||||||
|
sysfs_attribute_available(content, NULL,
|
||||||
|
"array_state")) {
|
||||||
|
@@ -2180,8 +2178,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
st->update_tail = &st->updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
- err = Grow_continue(mdfd, st, content, c->backup_file,
|
||||||
|
- 0, c->freeze_reshape);
|
||||||
|
+ err = Grow_continue(mdfd, st, content, 0, c);
|
||||||
|
} else switch(content->array.level) {
|
||||||
|
case LEVEL_LINEAR:
|
||||||
|
case LEVEL_MULTIPATH:
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index 074f1995..f477b438 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -864,8 +864,7 @@ static void wait_reshape(struct mdinfo *sra)
|
||||||
|
|
||||||
|
static int reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
int level, int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *backup_file, char *dev,
|
||||||
|
- int direction, int verbose)
|
||||||
|
+ int delta_disks, char *dev, int direction, struct context *c)
|
||||||
|
{
|
||||||
|
/* nothing extra to check in the native case */
|
||||||
|
if (!st->ss->external)
|
||||||
|
@@ -876,9 +875,8 @@ static int reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return st->ss->reshape_super(st, size, level, layout, chunksize,
|
||||||
|
- raid_disks, delta_disks, backup_file, dev,
|
||||||
|
- direction, verbose);
|
||||||
|
+ return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks,
|
||||||
|
+ delta_disks, dev, direction, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sync_metadata(struct supertype *st)
|
||||||
|
@@ -1764,9 +1762,8 @@ static int reshape_container(char *container, char *devname,
|
||||||
|
int mdfd,
|
||||||
|
struct supertype *st,
|
||||||
|
struct mdinfo *info,
|
||||||
|
- int force,
|
||||||
|
- char *backup_file, int verbose,
|
||||||
|
- int forked, int restart, int freeze_reshape);
|
||||||
|
+ struct context *c,
|
||||||
|
+ int forked, int restart);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prepare_external_reshape() - prepares update on external metadata if supported.
|
||||||
|
@@ -2004,9 +2001,8 @@ int Grow_reshape(char *devname, int fd,
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet, NULL,
|
||||||
|
- devname, APPLY_METADATA_CHANGES,
|
||||||
|
- c->verbose > 0)) {
|
||||||
|
+ if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet,
|
||||||
|
+ devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
rv = 1;
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
@@ -2124,10 +2120,8 @@ size_change_error:
|
||||||
|
int err = errno;
|
||||||
|
|
||||||
|
/* restore metadata */
|
||||||
|
- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0,
|
||||||
|
- UnSet, NULL, devname,
|
||||||
|
- ROLLBACK_METADATA_CHANGES,
|
||||||
|
- c->verbose) == 0)
|
||||||
|
+ if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet,
|
||||||
|
+ devname, ROLLBACK_METADATA_CHANGES, c) == 0)
|
||||||
|
sync_metadata(st);
|
||||||
|
pr_err("Cannot set device size for %s: %s\n",
|
||||||
|
devname, strerror(err));
|
||||||
|
@@ -2338,8 +2332,7 @@ size_change_error:
|
||||||
|
*/
|
||||||
|
close_fd(&fd);
|
||||||
|
rv = reshape_container(container, devname, -1, st, &info,
|
||||||
|
- c->force, c->backup_file, c->verbose,
|
||||||
|
- 0, 0, 0);
|
||||||
|
+ c, 0, 0);
|
||||||
|
frozen = 0;
|
||||||
|
} else {
|
||||||
|
/* get spare devices from external metadata
|
||||||
|
@@ -2356,13 +2349,13 @@ size_change_error:
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Impose these changes on a single array. First
|
||||||
|
- * check that the metadata is OK with the change. */
|
||||||
|
+ * check that the metadata is OK with the change.
|
||||||
|
+ */
|
||||||
|
|
||||||
|
if (reshape_super(st, 0, info.new_level,
|
||||||
|
info.new_layout, info.new_chunk,
|
||||||
|
info.array.raid_disks, info.delta_disks,
|
||||||
|
- c->backup_file, devname,
|
||||||
|
- APPLY_METADATA_CHANGES, c->verbose)) {
|
||||||
|
+ devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
rv = 1;
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
@@ -3668,9 +3661,8 @@ int reshape_container(char *container, char *devname,
|
||||||
|
int mdfd,
|
||||||
|
struct supertype *st,
|
||||||
|
struct mdinfo *info,
|
||||||
|
- int force,
|
||||||
|
- char *backup_file, int verbose,
|
||||||
|
- int forked, int restart, int freeze_reshape)
|
||||||
|
+ struct context *c,
|
||||||
|
+ int forked, int restart)
|
||||||
|
{
|
||||||
|
struct mdinfo *cc = NULL;
|
||||||
|
int rv = restart;
|
||||||
|
@@ -3683,8 +3675,7 @@ int reshape_container(char *container, char *devname,
|
||||||
|
reshape_super(st, 0, info->new_level,
|
||||||
|
info->new_layout, info->new_chunk,
|
||||||
|
info->array.raid_disks, info->delta_disks,
|
||||||
|
- backup_file, devname, APPLY_METADATA_CHANGES,
|
||||||
|
- verbose)) {
|
||||||
|
+ devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
unfreeze(st);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -3695,7 +3686,7 @@ int reshape_container(char *container, char *devname,
|
||||||
|
*/
|
||||||
|
ping_monitor(container);
|
||||||
|
|
||||||
|
- if (!forked && !freeze_reshape)
|
||||||
|
+ if (!forked && !c->freeze_reshape)
|
||||||
|
if (continue_via_systemd(container, GROW_SERVICE, NULL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
@@ -3705,7 +3696,7 @@ int reshape_container(char *container, char *devname,
|
||||||
|
unfreeze(st);
|
||||||
|
return 1;
|
||||||
|
default: /* parent */
|
||||||
|
- if (!freeze_reshape)
|
||||||
|
+ if (!c->freeze_reshape)
|
||||||
|
printf("%s: multi-array reshape continues in background\n", Name);
|
||||||
|
return 0;
|
||||||
|
case 0: /* child */
|
||||||
|
@@ -3802,12 +3793,12 @@ int reshape_container(char *container, char *devname,
|
||||||
|
flush_mdmon(container);
|
||||||
|
|
||||||
|
rv = reshape_array(container, fd, adev, st,
|
||||||
|
- content, force, NULL, INVALID_SECTORS,
|
||||||
|
- backup_file, verbose, 1, restart,
|
||||||
|
- freeze_reshape);
|
||||||
|
+ content, c->force, NULL, INVALID_SECTORS,
|
||||||
|
+ c->backup_file, c->verbose, 1, restart,
|
||||||
|
+ c->freeze_reshape);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
- if (freeze_reshape) {
|
||||||
|
+ if (c->freeze_reshape) {
|
||||||
|
sysfs_free(cc);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
@@ -4970,8 +4961,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int Grow_continue_command(char *devname, int fd,
|
||||||
|
- char *backup_file, int verbose)
|
||||||
|
+int Grow_continue_command(char *devname, int fd, struct context *c)
|
||||||
|
{
|
||||||
|
int ret_val = 0;
|
||||||
|
struct supertype *st = NULL;
|
||||||
|
@@ -5157,7 +5147,7 @@ int Grow_continue_command(char *devname, int fd,
|
||||||
|
|
||||||
|
/* continue reshape
|
||||||
|
*/
|
||||||
|
- ret_val = Grow_continue(fd, st, content, backup_file, 1, 0);
|
||||||
|
+ ret_val = Grow_continue(fd, st, content, 1, c);
|
||||||
|
|
||||||
|
Grow_continue_command_exit:
|
||||||
|
if (cfd > -1)
|
||||||
|
@@ -5171,7 +5161,7 @@ Grow_continue_command_exit:
|
||||||
|
}
|
||||||
|
|
||||||
|
int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||||
|
- char *backup_file, int forked, int freeze_reshape)
|
||||||
|
+ int forked, struct context *c)
|
||||||
|
{
|
||||||
|
int ret_val = 2;
|
||||||
|
|
||||||
|
@@ -5187,14 +5177,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||||
|
st->ss->load_container(st, cfd, st->container_devnm);
|
||||||
|
close(cfd);
|
||||||
|
ret_val = reshape_container(st->container_devnm, NULL, mdfd,
|
||||||
|
- st, info, 0, backup_file, 0,
|
||||||
|
- forked, 1 | info->reshape_active,
|
||||||
|
- freeze_reshape);
|
||||||
|
+ st, info, c, forked, 1 | info->reshape_active);
|
||||||
|
} else
|
||||||
|
ret_val = reshape_array(NULL, mdfd, "array", st, info, 1,
|
||||||
|
- NULL, INVALID_SECTORS, backup_file,
|
||||||
|
+ NULL, INVALID_SECTORS, c->backup_file,
|
||||||
|
0, forked, 1 | info->reshape_active,
|
||||||
|
- freeze_reshape);
|
||||||
|
+ c->freeze_reshape);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
diff --git a/mdadm.c b/mdadm.c
|
||||||
|
index 3f191288..d18619db 100644
|
||||||
|
--- a/mdadm.c
|
||||||
|
+++ b/mdadm.c
|
||||||
|
@@ -1636,7 +1636,7 @@ int main(int argc, char *argv[])
|
||||||
|
c.delay = DEFAULT_BITMAP_DELAY;
|
||||||
|
rv = Grow_addbitmap(ident.devname, mdfd, &c, &s);
|
||||||
|
} else if (grow_continue)
|
||||||
|
- rv = Grow_continue_command(ident.devname, mdfd, c.backup_file, c.verbose);
|
||||||
|
+ rv = Grow_continue_command(ident.devname, mdfd, &c);
|
||||||
|
else if (s.size > 0 || s.raiddisks || s.layout_str ||
|
||||||
|
s.chunk != 0 || s.level != UnSet ||
|
||||||
|
s.data_offset != INVALID_SECTORS) {
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 2640b396..0ade4beb 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1235,9 +1235,8 @@ extern struct superswitch {
|
||||||
|
int (*reshape_super)(struct supertype *st,
|
||||||
|
unsigned long long size, int level,
|
||||||
|
int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *backup, char *dev,
|
||||||
|
- int direction,
|
||||||
|
- int verbose); /* optional */
|
||||||
|
+ int delta_disks, char *dev, int direction,
|
||||||
|
+ struct context *c);
|
||||||
|
int (*manage_reshape)( /* optional */
|
||||||
|
int afd, struct mdinfo *sra, struct reshape *reshape,
|
||||||
|
struct supertype *st, unsigned long blocks,
|
||||||
|
@@ -1541,8 +1540,7 @@ extern int Grow_reshape(char *devname, int fd,
|
||||||
|
extern int Grow_restart(struct supertype *st, struct mdinfo *info,
|
||||||
|
int *fdlist, int cnt, char *backup_file, int verbose);
|
||||||
|
extern int Grow_continue(int mdfd, struct supertype *st,
|
||||||
|
- struct mdinfo *info, char *backup_file,
|
||||||
|
- int forked, int freeze_reshape);
|
||||||
|
+ struct mdinfo *info, int forked, struct context *c);
|
||||||
|
extern int Grow_consistency_policy(char *devname, int fd,
|
||||||
|
struct context *c, struct shape *s);
|
||||||
|
|
||||||
|
@@ -1552,8 +1550,7 @@ extern int restore_backup(struct supertype *st,
|
||||||
|
int spares,
|
||||||
|
char **backup_filep,
|
||||||
|
int verbose);
|
||||||
|
-extern int Grow_continue_command(char *devname, int fd,
|
||||||
|
- char *backup_file, int verbose);
|
||||||
|
+extern int Grow_continue_command(char *devname, int fd, struct context *c);
|
||||||
|
|
||||||
|
extern int Assemble(struct supertype *st, char *mddev,
|
||||||
|
struct mddev_ident *ident,
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 1faab607..417da267 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -12153,10 +12153,8 @@ exit:
|
||||||
|
}
|
||||||
|
|
||||||
|
static int imsm_reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
- int level,
|
||||||
|
- int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *backup, char *dev,
|
||||||
|
- int direction, int verbose)
|
||||||
|
+ int level, int layout, int chunksize, int raid_disks,
|
||||||
|
+ int delta_disks, char *dev, int direction, struct context *c)
|
||||||
|
{
|
||||||
|
int ret_val = 1;
|
||||||
|
struct geo_params geo;
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
296
0053-mdadm-use-struct-context-in-reshape_super.patch
Normal file
296
0053-mdadm-use-struct-context-in-reshape_super.patch
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
From 0acda7053df653022e46fa3b7caf1f4d4ba31a66 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:14 +0200
|
||||||
|
Subject: [PATCH 53/69] mdadm: use struct context in reshape_super()
|
||||||
|
|
||||||
|
reshape_super() takes too many arguments. Change passing params in
|
||||||
|
favor of single struct.
|
||||||
|
|
||||||
|
Add devname pointer and change direction members to struct shape
|
||||||
|
and use it for reshape_super().
|
||||||
|
|
||||||
|
Create reshape_array_size() and reshape_array_non_size() to handle
|
||||||
|
reshape_super() calls.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Grow.c | 93 +++++++++++++++++++++++++++++++++++++--------------
|
||||||
|
mdadm.h | 18 +++++-----
|
||||||
|
super-intel.c | 43 +++++++++++++++---------
|
||||||
|
3 files changed, 105 insertions(+), 49 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index f477b438..87ed9214 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -862,9 +862,7 @@ static void wait_reshape(struct mdinfo *sra)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
- int level, int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *dev, int direction, struct context *c)
|
||||||
|
+static int reshape_super(struct supertype *st, struct shape *shape, struct context *c)
|
||||||
|
{
|
||||||
|
/* nothing extra to check in the native case */
|
||||||
|
if (!st->ss->external)
|
||||||
|
@@ -875,8 +873,65 @@ static int reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return st->ss->reshape_super(st, size, level, layout, chunksize, raid_disks,
|
||||||
|
- delta_disks, dev, direction, c);
|
||||||
|
+ return st->ss->reshape_super(st, shape, c);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * reshape_super_size() - Reshape array, size only.
|
||||||
|
+ *
|
||||||
|
+ * @st: supertype.
|
||||||
|
+ * @devname: device name.
|
||||||
|
+ * @size: component size.
|
||||||
|
+ * @dir metadata changes direction
|
||||||
|
+ * Returns: 0 on success, 1 otherwise.
|
||||||
|
+ *
|
||||||
|
+ * This function is solely used to change size of the volume.
|
||||||
|
+ * Setting size is not valid for container.
|
||||||
|
+ * Size is only change that can be rolled back, thus the @dir param.
|
||||||
|
+ */
|
||||||
|
+static int reshape_super_size(struct supertype *st, char *devname,
|
||||||
|
+ unsigned long long size, change_dir_t direction,
|
||||||
|
+ struct context *c)
|
||||||
|
+{
|
||||||
|
+ struct shape shape = {0};
|
||||||
|
+
|
||||||
|
+ shape.level = UnSet;
|
||||||
|
+ shape.layout = UnSet;
|
||||||
|
+ shape.delta_disks = UnSet;
|
||||||
|
+ shape.dev = devname;
|
||||||
|
+ shape.size = size;
|
||||||
|
+ shape.direction = direction;
|
||||||
|
+
|
||||||
|
+ return reshape_super(st, &shape, c);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * reshape_super_non_size() - Reshape array, non size changes.
|
||||||
|
+ *
|
||||||
|
+ * @st: supertype.
|
||||||
|
+ * @devname: device name.
|
||||||
|
+ * @info: superblock info.
|
||||||
|
+ * Returns: 0 on success, 1 otherwise.
|
||||||
|
+ *
|
||||||
|
+ * This function is used for any external array changes but size.
|
||||||
|
+ * It handles both volumes and containers.
|
||||||
|
+ * For changes other than size, rollback is not possible.
|
||||||
|
+ */
|
||||||
|
+static int reshape_super_non_size(struct supertype *st, char *devname,
|
||||||
|
+ struct mdinfo *info, struct context *c)
|
||||||
|
+{
|
||||||
|
+ struct shape shape = {0};
|
||||||
|
+ /* Size already set to zero, not updating size */
|
||||||
|
+ shape.level = info->new_level;
|
||||||
|
+ shape.layout = info->new_layout;
|
||||||
|
+ shape.chunk = info->new_chunk;
|
||||||
|
+ shape.raiddisks = info->array.raid_disks;
|
||||||
|
+ shape.delta_disks = info->delta_disks;
|
||||||
|
+ shape.dev = devname;
|
||||||
|
+ /* Rollback not possible for non size changes */
|
||||||
|
+ shape.direction = APPLY_METADATA_CHANGES;
|
||||||
|
+
|
||||||
|
+ return reshape_super(st, &shape, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sync_metadata(struct supertype *st)
|
||||||
|
@@ -1979,9 +2034,8 @@ int Grow_reshape(char *devname, int fd,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========= set size =============== */
|
||||||
|
- if (s->size > 0 &&
|
||||||
|
- (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
|
||||||
|
- unsigned long long orig_size = get_component_size(fd)/2;
|
||||||
|
+ if (s->size > 0 && (s->size == MAX_SIZE || s->size != (unsigned)array.size)) {
|
||||||
|
+ unsigned long long orig_size = get_component_size(fd) / 2;
|
||||||
|
unsigned long long min_csize;
|
||||||
|
struct mdinfo *mdi;
|
||||||
|
int raid0_takeover = 0;
|
||||||
|
@@ -2001,8 +2055,7 @@ int Grow_reshape(char *devname, int fd,
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (reshape_super(st, s->size, UnSet, UnSet, 0, 0, UnSet,
|
||||||
|
- devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
+ if (reshape_super_size(st, devname, s->size, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
rv = 1;
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
@@ -2120,8 +2173,8 @@ size_change_error:
|
||||||
|
int err = errno;
|
||||||
|
|
||||||
|
/* restore metadata */
|
||||||
|
- if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0, UnSet,
|
||||||
|
- devname, ROLLBACK_METADATA_CHANGES, c) == 0)
|
||||||
|
+ if (reshape_super_size(st, devname, orig_size,
|
||||||
|
+ ROLLBACK_METADATA_CHANGES, c) == 0)
|
||||||
|
sync_metadata(st);
|
||||||
|
pr_err("Cannot set device size for %s: %s\n",
|
||||||
|
devname, strerror(err));
|
||||||
|
@@ -2351,11 +2404,7 @@ size_change_error:
|
||||||
|
/* Impose these changes on a single array. First
|
||||||
|
* check that the metadata is OK with the change.
|
||||||
|
*/
|
||||||
|
-
|
||||||
|
- if (reshape_super(st, 0, info.new_level,
|
||||||
|
- info.new_layout, info.new_chunk,
|
||||||
|
- info.array.raid_disks, info.delta_disks,
|
||||||
|
- devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
+ if (reshape_super_non_size(st, devname, &info, c)) {
|
||||||
|
rv = 1;
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
@@ -3668,14 +3717,8 @@ int reshape_container(char *container, char *devname,
|
||||||
|
int rv = restart;
|
||||||
|
char last_devnm[32] = "";
|
||||||
|
|
||||||
|
- /* component_size is not meaningful for a container,
|
||||||
|
- * so pass '0' meaning 'no change'
|
||||||
|
- */
|
||||||
|
- if (!restart &&
|
||||||
|
- reshape_super(st, 0, info->new_level,
|
||||||
|
- info->new_layout, info->new_chunk,
|
||||||
|
- info->array.raid_disks, info->delta_disks,
|
||||||
|
- devname, APPLY_METADATA_CHANGES, c)) {
|
||||||
|
+ /* component_size is not meaningful for a container */
|
||||||
|
+ if (!restart && reshape_super_non_size(st, devname, info, c)) {
|
||||||
|
unfreeze(st);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 0ade4beb..2ff3e463 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -594,6 +594,11 @@ enum flag_mode {
|
||||||
|
FlagDefault, FlagSet, FlagClear,
|
||||||
|
};
|
||||||
|
|
||||||
|
+typedef enum {
|
||||||
|
+ ROLLBACK_METADATA_CHANGES,
|
||||||
|
+ APPLY_METADATA_CHANGES
|
||||||
|
+} change_dir_t;
|
||||||
|
+
|
||||||
|
/* structures read from config file */
|
||||||
|
/* List of mddevice names and identifiers
|
||||||
|
* Identifiers can be:
|
||||||
|
@@ -667,7 +672,9 @@ struct context {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct shape {
|
||||||
|
+ char *dev;
|
||||||
|
int raiddisks;
|
||||||
|
+ int delta_disks;
|
||||||
|
int sparedisks;
|
||||||
|
int journaldisks;
|
||||||
|
int level;
|
||||||
|
@@ -682,6 +689,7 @@ struct shape {
|
||||||
|
unsigned long long size;
|
||||||
|
unsigned long long data_offset;
|
||||||
|
int consistency_policy;
|
||||||
|
+ change_dir_t direction;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List of device names - wildcards expanded */
|
||||||
|
@@ -1229,14 +1237,8 @@ extern struct superswitch {
|
||||||
|
* initialized to indicate if reshape is being performed at the
|
||||||
|
* container or subarray level
|
||||||
|
*/
|
||||||
|
-#define APPLY_METADATA_CHANGES 1
|
||||||
|
-#define ROLLBACK_METADATA_CHANGES 0
|
||||||
|
-
|
||||||
|
- int (*reshape_super)(struct supertype *st,
|
||||||
|
- unsigned long long size, int level,
|
||||||
|
- int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *dev, int direction,
|
||||||
|
- struct context *c);
|
||||||
|
+
|
||||||
|
+ int (*reshape_super)(struct supertype *st, struct shape *shape, struct context *c);
|
||||||
|
int (*manage_reshape)( /* optional */
|
||||||
|
int afd, struct mdinfo *sra, struct reshape *reshape,
|
||||||
|
struct supertype *st, unsigned long blocks,
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 417da267..1a8a7b12 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -12152,26 +12152,37 @@ exit:
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int imsm_reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
- int level, int layout, int chunksize, int raid_disks,
|
||||||
|
- int delta_disks, char *dev, int direction, struct context *c)
|
||||||
|
+/**
|
||||||
|
+ * shape_to_geo() - fill geo_params from shape.
|
||||||
|
+ *
|
||||||
|
+ * @shape: array details.
|
||||||
|
+ * @geo: new geometry params.
|
||||||
|
+ * Returns: 0 on success, 1 otherwise.
|
||||||
|
+ */
|
||||||
|
+static void shape_to_geo(struct shape *shape, struct geo_params *geo)
|
||||||
|
+{
|
||||||
|
+ assert(shape);
|
||||||
|
+ assert(geo);
|
||||||
|
+
|
||||||
|
+ geo->dev_name = shape->dev;
|
||||||
|
+ geo->size = shape->size;
|
||||||
|
+ geo->level = shape->level;
|
||||||
|
+ geo->layout = shape->layout;
|
||||||
|
+ geo->chunksize = shape->chunk;
|
||||||
|
+ geo->raid_disks = shape->raiddisks;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct context *c)
|
||||||
|
{
|
||||||
|
int ret_val = 1;
|
||||||
|
- struct geo_params geo;
|
||||||
|
+ struct geo_params geo = {0};
|
||||||
|
|
||||||
|
dprintf("(enter)\n");
|
||||||
|
|
||||||
|
- memset(&geo, 0, sizeof(struct geo_params));
|
||||||
|
-
|
||||||
|
- geo.dev_name = dev;
|
||||||
|
+ shape_to_geo(shape, &geo);
|
||||||
|
strcpy(geo.devnm, st->devnm);
|
||||||
|
- geo.size = size;
|
||||||
|
- geo.level = level;
|
||||||
|
- geo.layout = layout;
|
||||||
|
- geo.chunksize = chunksize;
|
||||||
|
- geo.raid_disks = raid_disks;
|
||||||
|
- if (delta_disks != UnSet)
|
||||||
|
- geo.raid_disks += delta_disks;
|
||||||
|
+ if (shape->delta_disks != UnSet)
|
||||||
|
+ geo.raid_disks += shape->delta_disks;
|
||||||
|
|
||||||
|
dprintf("for level : %i\n", geo.level);
|
||||||
|
dprintf("for raid_disks : %i\n", geo.raid_disks);
|
||||||
|
@@ -12182,7 +12193,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
int old_raid_disks = 0;
|
||||||
|
|
||||||
|
if (imsm_reshape_is_allowed_on_container(
|
||||||
|
- st, &geo, &old_raid_disks, direction)) {
|
||||||
|
+ st, &geo, &old_raid_disks, shape->direction)) {
|
||||||
|
struct imsm_update_reshape *u = NULL;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
@@ -12236,7 +12247,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
|
||||||
|
goto exit_imsm_reshape_super;
|
||||||
|
}
|
||||||
|
super->current_vol = dev->index;
|
||||||
|
- change = imsm_analyze_change(st, &geo, direction);
|
||||||
|
+ change = imsm_analyze_change(st, &geo, shape->direction);
|
||||||
|
switch (change) {
|
||||||
|
case CH_TAKEOVER:
|
||||||
|
ret_val = imsm_takeover(st, &geo);
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
184
0054-imsm-add-support-for-literal-RAID-10.patch
Normal file
184
0054-imsm-add-support-for-literal-RAID-10.patch
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
From 27550b13297adbdefe42fe4eb785b7fde1c0ed91 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:15 +0200
|
||||||
|
Subject: [PATCH 54/69] imsm: add support for literal RAID 10
|
||||||
|
|
||||||
|
As for now, IMSM supports only 4 drive RAID 1+0. This patch is first in
|
||||||
|
series to add support for literal RAID 10 (with more than 4 drives) to
|
||||||
|
imsm.
|
||||||
|
|
||||||
|
Allow setting RAID 10 as raid level for imsm arrays.
|
||||||
|
|
||||||
|
Add update_imsm_raid_level() to handle raid level updates. Set RAID10 as
|
||||||
|
default level for imsm R0 to R10 migrations. Replace magic numbers with
|
||||||
|
defined values for RAID level checks/assigns.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
super-intel.c | 67 ++++++++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 48 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 1a8a7b12..a7efc8df 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -166,7 +166,8 @@ struct imsm_map {
|
||||||
|
__u8 raid_level;
|
||||||
|
#define IMSM_T_RAID0 0
|
||||||
|
#define IMSM_T_RAID1 1
|
||||||
|
-#define IMSM_T_RAID5 5 /* since metadata version 1.2.02 ? */
|
||||||
|
+#define IMSM_T_RAID5 5
|
||||||
|
+#define IMSM_T_RAID10 10
|
||||||
|
__u8 num_members; /* number of member disks */
|
||||||
|
__u8 num_domains; /* number of parity domains */
|
||||||
|
__u8 failed_disk_num; /* valid only when state is degraded */
|
||||||
|
@@ -1259,14 +1260,42 @@ static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx)
|
||||||
|
|
||||||
|
return IMSM_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
+/**
|
||||||
|
+ * update_imsm_raid_level() - update raid level appropriately in &imsm_map.
|
||||||
|
+ * @map: &imsm_map pointer.
|
||||||
|
+ * @new_level: MD style level.
|
||||||
|
+ *
|
||||||
|
+ * For backward compatibility reasons we need to differentiate RAID10.
|
||||||
|
+ * In the past IMSM RAID10 was presented as RAID1.
|
||||||
|
+ * Keep compatibility unless it is not explicitly updated by UEFI driver.
|
||||||
|
+ *
|
||||||
|
+ * Routine needs num_members to be set and (optionally) raid_level.
|
||||||
|
+ */
|
||||||
|
+static void update_imsm_raid_level(struct imsm_map *map, int new_level)
|
||||||
|
+{
|
||||||
|
+ if (new_level != IMSM_T_RAID10) {
|
||||||
|
+ map->raid_level = new_level;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (map->num_members == 4) {
|
||||||
|
+ if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ map->raid_level = IMSM_T_RAID1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ map->raid_level = IMSM_T_RAID10;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static int get_imsm_raid_level(struct imsm_map *map)
|
||||||
|
{
|
||||||
|
- if (map->raid_level == 1) {
|
||||||
|
+ if (map->raid_level == IMSM_T_RAID1) {
|
||||||
|
if (map->num_members == 2)
|
||||||
|
- return 1;
|
||||||
|
+ return IMSM_T_RAID1;
|
||||||
|
else
|
||||||
|
- return 10;
|
||||||
|
+ return IMSM_T_RAID10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map->raid_level;
|
||||||
|
@@ -5678,7 +5707,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
set_pba_of_lba0(map, super->create_offset);
|
||||||
|
map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
|
||||||
|
map->failed_disk_num = ~0;
|
||||||
|
- if (info->level > 0)
|
||||||
|
+ if (info->level > IMSM_T_RAID0)
|
||||||
|
map->map_state = (info->state ? IMSM_T_STATE_NORMAL
|
||||||
|
: IMSM_T_STATE_UNINITIALIZED);
|
||||||
|
else
|
||||||
|
@@ -5686,16 +5715,15 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
IMSM_T_STATE_NORMAL;
|
||||||
|
map->ddf = 1;
|
||||||
|
|
||||||
|
- if (info->level == 1 && info->raid_disks > 2) {
|
||||||
|
+ if (info->level == IMSM_T_RAID1 && info->raid_disks > 2) {
|
||||||
|
free(dev);
|
||||||
|
free(dv);
|
||||||
|
- pr_err("imsm does not support more than 2 disksin a raid1 volume\n");
|
||||||
|
+ pr_err("imsm does not support more than 2 disks in a raid1 volume\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+ map->num_members = info->raid_disks;
|
||||||
|
|
||||||
|
- map->raid_level = info->level;
|
||||||
|
- if (info->level == 10)
|
||||||
|
- map->raid_level = 1;
|
||||||
|
+ update_imsm_raid_level(map, info->level);
|
||||||
|
set_num_domains(map);
|
||||||
|
|
||||||
|
size_per_member += NUM_BLOCKS_DIRTY_STRIPE_REGION;
|
||||||
|
@@ -5703,7 +5731,6 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
size_per_member /
|
||||||
|
BLOCKS_PER_KB));
|
||||||
|
|
||||||
|
- map->num_members = info->raid_disks;
|
||||||
|
update_num_data_stripes(map, array_blocks);
|
||||||
|
for (i = 0; i < map->num_members; i++) {
|
||||||
|
/* initialized in add_to_super */
|
||||||
|
@@ -8275,7 +8302,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
||||||
|
info_d->data_offset = pba_of_lba0(map);
|
||||||
|
info_d->component_size = calc_component_size(map, dev);
|
||||||
|
|
||||||
|
- if (map->raid_level == 5) {
|
||||||
|
+ if (map->raid_level == IMSM_T_RAID5) {
|
||||||
|
info_d->ppl_sector = this->ppl_sector;
|
||||||
|
info_d->ppl_size = this->ppl_size;
|
||||||
|
if (this->consistency_policy == CONSISTENCY_POLICY_PPL &&
|
||||||
|
@@ -9533,7 +9560,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
||||||
|
}
|
||||||
|
|
||||||
|
to_state = map->map_state;
|
||||||
|
- if ((u->new_level == 5) && (map->raid_level == 0)) {
|
||||||
|
+ if ((u->new_level == IMSM_T_RAID5) && (map->raid_level == IMSM_T_RAID0)) {
|
||||||
|
map->num_members++;
|
||||||
|
/* this should not happen */
|
||||||
|
if (u->new_disks[0] < 0) {
|
||||||
|
@@ -9544,11 +9571,13 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
||||||
|
to_state = IMSM_T_STATE_NORMAL;
|
||||||
|
}
|
||||||
|
migrate(new_dev, super, to_state, MIGR_GEN_MIGR);
|
||||||
|
+
|
||||||
|
if (u->new_level > -1)
|
||||||
|
- map->raid_level = u->new_level;
|
||||||
|
+ update_imsm_raid_level(map, u->new_level);
|
||||||
|
+
|
||||||
|
migr_map = get_imsm_map(new_dev, MAP_1);
|
||||||
|
- if ((u->new_level == 5) &&
|
||||||
|
- (migr_map->raid_level == 0)) {
|
||||||
|
+ if ((u->new_level == IMSM_T_RAID5) &&
|
||||||
|
+ (migr_map->raid_level == IMSM_T_RAID0)) {
|
||||||
|
int ord = map->num_members - 1;
|
||||||
|
migr_map->num_members--;
|
||||||
|
if (u->new_disks[0] < 0)
|
||||||
|
@@ -9584,7 +9613,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
||||||
|
|
||||||
|
/* add disk
|
||||||
|
*/
|
||||||
|
- if (u->new_level != 5 || migr_map->raid_level != 0 ||
|
||||||
|
+ if (u->new_level != IMSM_T_RAID5 || migr_map->raid_level != IMSM_T_RAID0 ||
|
||||||
|
migr_map->raid_level == map->raid_level)
|
||||||
|
goto skip_disk_add;
|
||||||
|
|
||||||
|
@@ -9963,7 +9992,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
|
||||||
|
/* update map */
|
||||||
|
map->num_members /= map->num_domains;
|
||||||
|
map->map_state = IMSM_T_STATE_NORMAL;
|
||||||
|
- map->raid_level = 0;
|
||||||
|
+ update_imsm_raid_level(map, IMSM_T_RAID0);
|
||||||
|
set_num_domains(map);
|
||||||
|
update_num_data_stripes(map, imsm_dev_size(dev));
|
||||||
|
map->failed_disk_num = -1;
|
||||||
|
@@ -10007,7 +10036,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
|
||||||
|
map = get_imsm_map(dev_new, MAP_0);
|
||||||
|
|
||||||
|
map->map_state = IMSM_T_STATE_DEGRADED;
|
||||||
|
- map->raid_level = 1;
|
||||||
|
+ update_imsm_raid_level(map, IMSM_T_RAID10);
|
||||||
|
set_num_domains(map);
|
||||||
|
map->num_members = map->num_members * map->num_domains;
|
||||||
|
update_num_data_stripes(map, imsm_dev_size(dev));
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
345
0055-imsm-refactor-RAID-level-handling.patch
Normal file
345
0055-imsm-refactor-RAID-level-handling.patch
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
From 191e6ddb1388236c5c54baf5020a87c996be941f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:16 +0200
|
||||||
|
Subject: [PATCH 55/69] imsm: refactor RAID level handling
|
||||||
|
|
||||||
|
Add imsm_level_ops struct for better handling and unifying raid level
|
||||||
|
support. Add helper methods and move "orom_has_raid[...]" methods from
|
||||||
|
header to source file.
|
||||||
|
|
||||||
|
RAID 1e is not supported under Linux, remove RAID 1e associated code.
|
||||||
|
|
||||||
|
Refactor imsm_analyze_change() and is_raid_level_supported().
|
||||||
|
Remove hardcoded check for 4 drives and make devNumChange a multiplier
|
||||||
|
for RAID 10.
|
||||||
|
|
||||||
|
Refactor printing supported raid levels.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
platform-intel.c | 57 ++++++++++++++++++++++++
|
||||||
|
platform-intel.h | 32 ++++++--------
|
||||||
|
super-intel.c | 111 ++++++++++++++++++++++++++++-------------------
|
||||||
|
3 files changed, 138 insertions(+), 62 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index ac282bc5..40e8fb82 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -32,6 +32,63 @@
|
||||||
|
|
||||||
|
#define NVME_SUBSYS_PATH "/sys/devices/virtual/nvme-subsystem/"
|
||||||
|
|
||||||
|
+static bool imsm_orom_has_raid0(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_has_raid1(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_has_raid10(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID10);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_has_raid5(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ return imsm_rlc_has_bit(orom, IMSM_OROM_RLC_RAID5);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* IMSM platforms do not define how many disks are allowed for each level,
|
||||||
|
+ * but there are some global limitations we need to follow.
|
||||||
|
+ */
|
||||||
|
+static bool imsm_orom_support_raid_disks_count_raid0(const int raid_disks)
|
||||||
|
+{
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_support_raid_disks_count_raid1(const int raid_disks)
|
||||||
|
+{
|
||||||
|
+ if (raid_disks == 2)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks)
|
||||||
|
+{
|
||||||
|
+ if (raid_disks > 2)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks)
|
||||||
|
+{
|
||||||
|
+ if (raid_disks == 4)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct imsm_level_ops imsm_level_ops[] = {
|
||||||
|
+ {0, imsm_orom_has_raid0, imsm_orom_support_raid_disks_count_raid0, "raid0"},
|
||||||
|
+ {1, imsm_orom_has_raid1, imsm_orom_support_raid_disks_count_raid1, "raid1"},
|
||||||
|
+ {5, imsm_orom_has_raid5, imsm_orom_support_raid_disks_count_raid5, "raid5"},
|
||||||
|
+ {10, imsm_orom_has_raid10, imsm_orom_support_raid_disks_count_raid10, "raid10"},
|
||||||
|
+ {-1, NULL, NULL, NULL}
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static int devpath_to_ll(const char *dev_path, const char *entry,
|
||||||
|
unsigned long long *val);
|
||||||
|
|
||||||
|
diff --git a/platform-intel.h b/platform-intel.h
|
||||||
|
index 3c2bc595..dcc5aaa7 100644
|
||||||
|
--- a/platform-intel.h
|
||||||
|
+++ b/platform-intel.h
|
||||||
|
@@ -109,25 +109,21 @@ struct imsm_orom {
|
||||||
|
#define IMSM_OROM_CAPABILITIES_TPV (1 << 10)
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
-static inline int imsm_orom_has_raid0(const struct imsm_orom *orom)
|
||||||
|
-{
|
||||||
|
- return !!(orom->rlc & IMSM_OROM_RLC_RAID0);
|
||||||
|
-}
|
||||||
|
-static inline int imsm_orom_has_raid1(const struct imsm_orom *orom)
|
||||||
|
-{
|
||||||
|
- return !!(orom->rlc & IMSM_OROM_RLC_RAID1);
|
||||||
|
-}
|
||||||
|
-static inline int imsm_orom_has_raid1e(const struct imsm_orom *orom)
|
||||||
|
-{
|
||||||
|
- return !!(orom->rlc & IMSM_OROM_RLC_RAID1E);
|
||||||
|
-}
|
||||||
|
-static inline int imsm_orom_has_raid10(const struct imsm_orom *orom)
|
||||||
|
-{
|
||||||
|
- return !!(orom->rlc & IMSM_OROM_RLC_RAID10);
|
||||||
|
-}
|
||||||
|
-static inline int imsm_orom_has_raid5(const struct imsm_orom *orom)
|
||||||
|
+/* IMSM metadata requirements for each level */
|
||||||
|
+struct imsm_level_ops {
|
||||||
|
+ int level;
|
||||||
|
+ bool (*is_level_supported)(const struct imsm_orom *);
|
||||||
|
+ bool (*is_raiddisks_count_supported)(const int);
|
||||||
|
+ char *name;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+extern struct imsm_level_ops imsm_level_ops[];
|
||||||
|
+
|
||||||
|
+static inline bool imsm_rlc_has_bit(const struct imsm_orom *orom, const unsigned short bit)
|
||||||
|
{
|
||||||
|
- return !!(orom->rlc & IMSM_OROM_RLC_RAID5);
|
||||||
|
+ if (orom->rlc & bit)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index a7efc8df..da17265d 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -2681,6 +2681,15 @@ static int ahci_get_port_count(const char *hba_path, int *port_count)
|
||||||
|
return host_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void print_imsm_level_capability(const struct imsm_orom *orom)
|
||||||
|
+{
|
||||||
|
+ int idx;
|
||||||
|
+
|
||||||
|
+ for (idx = 0; imsm_level_ops[idx].name; idx++)
|
||||||
|
+ if (imsm_level_ops[idx].is_level_supported(orom))
|
||||||
|
+ printf("%s ", imsm_level_ops[idx].name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void print_imsm_capability(const struct imsm_orom *orom)
|
||||||
|
{
|
||||||
|
printf(" Platform : Intel(R) ");
|
||||||
|
@@ -2699,12 +2708,11 @@ static void print_imsm_capability(const struct imsm_orom *orom)
|
||||||
|
printf(" Version : %d.%d.%d.%d\n", orom->major_ver,
|
||||||
|
orom->minor_ver, orom->hotfix_ver, orom->build);
|
||||||
|
}
|
||||||
|
- printf(" RAID Levels :%s%s%s%s%s\n",
|
||||||
|
- imsm_orom_has_raid0(orom) ? " raid0" : "",
|
||||||
|
- imsm_orom_has_raid1(orom) ? " raid1" : "",
|
||||||
|
- imsm_orom_has_raid1e(orom) ? " raid1e" : "",
|
||||||
|
- imsm_orom_has_raid10(orom) ? " raid10" : "",
|
||||||
|
- imsm_orom_has_raid5(orom) ? " raid5" : "");
|
||||||
|
+
|
||||||
|
+ printf(" RAID Levels : ");
|
||||||
|
+ print_imsm_level_capability(orom);
|
||||||
|
+ printf("\n");
|
||||||
|
+
|
||||||
|
printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||||
|
imsm_orom_has_chunk(orom, 2) ? " 2k" : "",
|
||||||
|
imsm_orom_has_chunk(orom, 4) ? " 4k" : "",
|
||||||
|
@@ -2739,12 +2747,11 @@ static void print_imsm_capability_export(const struct imsm_orom *orom)
|
||||||
|
if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build)
|
||||||
|
printf("IMSM_VERSION=%d.%d.%d.%d\n", orom->major_ver, orom->minor_ver,
|
||||||
|
orom->hotfix_ver, orom->build);
|
||||||
|
- printf("IMSM_SUPPORTED_RAID_LEVELS=%s%s%s%s%s\n",
|
||||||
|
- imsm_orom_has_raid0(orom) ? "raid0 " : "",
|
||||||
|
- imsm_orom_has_raid1(orom) ? "raid1 " : "",
|
||||||
|
- imsm_orom_has_raid1e(orom) ? "raid1e " : "",
|
||||||
|
- imsm_orom_has_raid5(orom) ? "raid10 " : "",
|
||||||
|
- imsm_orom_has_raid10(orom) ? "raid5 " : "");
|
||||||
|
+
|
||||||
|
+ printf("IMSM_SUPPORTED_RAID_LEVELS=");
|
||||||
|
+ print_imsm_level_capability(orom);
|
||||||
|
+ printf("\n");
|
||||||
|
+
|
||||||
|
printf("IMSM_SUPPORTED_CHUNK_SIZES=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||||
|
imsm_orom_has_chunk(orom, 2) ? "2k " : "",
|
||||||
|
imsm_orom_has_chunk(orom, 4) ? "4k " : "",
|
||||||
|
@@ -6992,26 +6999,41 @@ static unsigned long long merge_extents(struct intel_super *super, const bool ex
|
||||||
|
return free_size - reservation_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
|
||||||
|
+/**
|
||||||
|
+ * is_raid_level_supported() - check if this count of drives and level is supported by platform.
|
||||||
|
+ * @orom: hardware properties, could be NULL.
|
||||||
|
+ * @level: requested raid level.
|
||||||
|
+ * @raiddisks: requested disk count.
|
||||||
|
+ *
|
||||||
|
+ * IMSM UEFI/OROM does not provide information about supported count of raid disks
|
||||||
|
+ * for particular level. That is why it is hardcoded.
|
||||||
|
+ * It is recommended to not allow of usage other levels than supported,
|
||||||
|
+ * IMSM code is not tested against different level implementations.
|
||||||
|
+ *
|
||||||
|
+ * Return: true if supported, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
|
||||||
|
{
|
||||||
|
- if (level < 0 || level == 6 || level == 4)
|
||||||
|
- return 0;
|
||||||
|
+ int idx;
|
||||||
|
|
||||||
|
- /* if we have an orom prevent invalid raid levels */
|
||||||
|
- if (orom)
|
||||||
|
- switch (level) {
|
||||||
|
- case 0: return imsm_orom_has_raid0(orom);
|
||||||
|
- case 1:
|
||||||
|
- if (raiddisks > 2)
|
||||||
|
- return imsm_orom_has_raid1e(orom);
|
||||||
|
- return imsm_orom_has_raid1(orom) && raiddisks == 2;
|
||||||
|
- case 10: return imsm_orom_has_raid10(orom) && raiddisks == 4;
|
||||||
|
- case 5: return imsm_orom_has_raid5(orom) && raiddisks > 2;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- return 1; /* not on an Intel RAID platform so anything goes */
|
||||||
|
+ for (idx = 0; imsm_level_ops[idx].name; idx++) {
|
||||||
|
+ if (imsm_level_ops[idx].level == level)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+ if (!imsm_level_ops[idx].name)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!imsm_level_ops[idx].is_raiddisks_count_supported(raiddisks))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!orom)
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ if (imsm_level_ops[idx].is_level_supported(orom))
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -11962,18 +11984,17 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
int change = -1;
|
||||||
|
int check_devs = 0;
|
||||||
|
int chunk;
|
||||||
|
- /* number of added/removed disks in operation result */
|
||||||
|
- int devNumChange = 0;
|
||||||
|
/* imsm compatible layout value for array geometry verification */
|
||||||
|
int imsm_layout = -1;
|
||||||
|
+ int raid_disks = geo->raid_disks;
|
||||||
|
imsm_status_t rv;
|
||||||
|
|
||||||
|
getinfo_super_imsm_volume(st, &info, NULL);
|
||||||
|
- if (geo->level != info.array.level && geo->level >= 0 &&
|
||||||
|
+ if (geo->level != info.array.level && geo->level >= IMSM_T_RAID0 &&
|
||||||
|
geo->level != UnSet) {
|
||||||
|
switch (info.array.level) {
|
||||||
|
- case 0:
|
||||||
|
- if (geo->level == 5) {
|
||||||
|
+ case IMSM_T_RAID0:
|
||||||
|
+ if (geo->level == IMSM_T_RAID5) {
|
||||||
|
change = CH_MIGRATION;
|
||||||
|
if (geo->layout != ALGORITHM_LEFT_ASYMMETRIC) {
|
||||||
|
pr_err("Error. Requested Layout not supported (left-asymmetric layout is supported only)!\n");
|
||||||
|
@@ -11982,20 +12003,20 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
}
|
||||||
|
imsm_layout = geo->layout;
|
||||||
|
check_devs = 1;
|
||||||
|
- devNumChange = 1; /* parity disk added */
|
||||||
|
- } else if (geo->level == 10) {
|
||||||
|
+ raid_disks += 1; /* parity disk added */
|
||||||
|
+ } else if (geo->level == IMSM_T_RAID10) {
|
||||||
|
change = CH_TAKEOVER;
|
||||||
|
check_devs = 1;
|
||||||
|
- devNumChange = 2; /* two mirrors added */
|
||||||
|
+ raid_disks *= 2; /* mirrors added */
|
||||||
|
imsm_layout = 0x102; /* imsm supported layout */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
- case 1:
|
||||||
|
- case 10:
|
||||||
|
+ case IMSM_T_RAID1:
|
||||||
|
+ case IMSM_T_RAID10:
|
||||||
|
if (geo->level == 0) {
|
||||||
|
change = CH_TAKEOVER;
|
||||||
|
check_devs = 1;
|
||||||
|
- devNumChange = -(geo->raid_disks/2);
|
||||||
|
+ raid_disks /= 2;
|
||||||
|
imsm_layout = 0; /* imsm raid0 layout */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
@@ -12011,10 +12032,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
if (geo->layout != info.array.layout &&
|
||||||
|
(geo->layout != UnSet && geo->layout != -1)) {
|
||||||
|
change = CH_MIGRATION;
|
||||||
|
- if (info.array.layout == 0 && info.array.level == 5 &&
|
||||||
|
+ if (info.array.layout == 0 && info.array.level == IMSM_T_RAID5 &&
|
||||||
|
geo->layout == 5) {
|
||||||
|
/* reshape 5 -> 4 */
|
||||||
|
- } else if (info.array.layout == 5 && info.array.level == 5 &&
|
||||||
|
+ } else if (info.array.layout == 5 && info.array.level == IMSM_T_RAID5 &&
|
||||||
|
geo->layout == 0) {
|
||||||
|
/* reshape 4 -> 5 */
|
||||||
|
geo->layout = 0;
|
||||||
|
@@ -12033,7 +12054,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
|
||||||
|
if (geo->chunksize > 0 && geo->chunksize != UnSet &&
|
||||||
|
geo->chunksize != info.array.chunk_size) {
|
||||||
|
- if (info.array.level == 10) {
|
||||||
|
+ if (info.array.level == IMSM_T_RAID10) {
|
||||||
|
pr_err("Error. Chunk size change for RAID 10 is not supported.\n");
|
||||||
|
change = -1;
|
||||||
|
goto analyse_change_exit;
|
||||||
|
@@ -12058,14 +12079,16 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
rv = imsm_analyze_expand(st, geo, &info, direction);
|
||||||
|
if (rv != IMSM_STATUS_OK)
|
||||||
|
goto analyse_change_exit;
|
||||||
|
+ raid_disks = geo->raid_disks;
|
||||||
|
change = CH_ARRAY_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = geo->chunksize / 1024;
|
||||||
|
+
|
||||||
|
if (!validate_geometry_imsm(st,
|
||||||
|
geo->level,
|
||||||
|
imsm_layout,
|
||||||
|
- geo->raid_disks + devNumChange,
|
||||||
|
+ raid_disks,
|
||||||
|
&chunk,
|
||||||
|
geo->size, INVALID_SECTORS,
|
||||||
|
0, 0, info.consistency_policy, 1))
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
180
0056-imsm-bump-minimal-version.patch
Normal file
180
0056-imsm-bump-minimal-version.patch
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
From ec7e873ba6643a9e5e74311b00ede66a3d2e36c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:17 +0200
|
||||||
|
Subject: [PATCH 56/69] imsm: bump minimal version
|
||||||
|
|
||||||
|
IMSM version 1.3 (called ATTRIBS) brought attributes used to define array
|
||||||
|
properties which require support in driver. The goal of this change was
|
||||||
|
to avoid changing version when adding new features.
|
||||||
|
|
||||||
|
For some reasons migration has never been completed and currently (after
|
||||||
|
10 years of implementing) IMSM can use older versions.
|
||||||
|
|
||||||
|
It is right time to finally switch it. There is no point in using old
|
||||||
|
versions, use 1.3.00 as minimal one.
|
||||||
|
|
||||||
|
Define JD_VERSION used by Windows driver.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
super-intel.c | 87 ++++++++++++++++++++++-----------------------------
|
||||||
|
1 file changed, 38 insertions(+), 49 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index da17265d..4b168add 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -32,14 +32,19 @@
|
||||||
|
/* MPB == Metadata Parameter Block */
|
||||||
|
#define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. "
|
||||||
|
#define MPB_SIG_LEN (strlen(MPB_SIGNATURE))
|
||||||
|
-#define MPB_VERSION_RAID0 "1.0.00"
|
||||||
|
-#define MPB_VERSION_RAID1 "1.1.00"
|
||||||
|
-#define MPB_VERSION_MANY_VOLUMES_PER_ARRAY "1.2.00"
|
||||||
|
-#define MPB_VERSION_3OR4_DISK_ARRAY "1.2.01"
|
||||||
|
-#define MPB_VERSION_RAID5 "1.2.02"
|
||||||
|
-#define MPB_VERSION_5OR6_DISK_ARRAY "1.2.04"
|
||||||
|
-#define MPB_VERSION_CNG "1.2.06"
|
||||||
|
+
|
||||||
|
+/* Legacy IMSM versions:
|
||||||
|
+ * MPB_VERSION_RAID0 1.0.00
|
||||||
|
+ * MPB_VERSION_RAID1 1.1.00
|
||||||
|
+ * MPB_VERSION_MANY_VOLUMES_PER_ARRAY 1.2.00
|
||||||
|
+ * MPB_VERSION_3OR4_DISK_ARRAY 1.2.01
|
||||||
|
+ * MPB_VERSION_RAID5 1.2.02
|
||||||
|
+ * MPB_VERSION_5OR6_DISK_ARRAY 1.2.04
|
||||||
|
+ * MPB_VERSION_CNG 1.2.06
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
#define MPB_VERSION_ATTRIBS "1.3.00"
|
||||||
|
+#define MPB_VERSION_ATTRIBS_JD "2.0.00"
|
||||||
|
#define MAX_SIGNATURE_LENGTH 32
|
||||||
|
#define MAX_RAID_SERIAL_LEN 16
|
||||||
|
|
||||||
|
@@ -5512,51 +5517,46 @@ static unsigned long long info_to_blocks_per_member(mdu_array_info_t *info,
|
||||||
|
return (size * 2) & ~(info_to_blocks_per_strip(info) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void imsm_write_signature(struct imsm_super *mpb)
|
||||||
|
+{
|
||||||
|
+ /* It is safer to eventually truncate version rather than left it not NULL ended */
|
||||||
|
+ snprintf((char *) mpb->sig, MAX_SIGNATURE_LENGTH, MPB_SIGNATURE MPB_VERSION_ATTRIBS);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void imsm_update_version_info(struct intel_super *super)
|
||||||
|
{
|
||||||
|
/* update the version and attributes */
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
- char *version;
|
||||||
|
struct imsm_dev *dev;
|
||||||
|
struct imsm_map *map;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_CHECKSUM_VERIFY;
|
||||||
|
+
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
dev = get_imsm_dev(super, i);
|
||||||
|
map = get_imsm_map(dev, MAP_0);
|
||||||
|
+
|
||||||
|
if (__le32_to_cpu(dev->size_high) > 0)
|
||||||
|
mpb->attributes |= MPB_ATTRIB_2TB;
|
||||||
|
|
||||||
|
- /* FIXME detect when an array spans a port multiplier */
|
||||||
|
- #if 0
|
||||||
|
- mpb->attributes |= MPB_ATTRIB_PM;
|
||||||
|
- #endif
|
||||||
|
-
|
||||||
|
- if (mpb->num_raid_devs > 1 ||
|
||||||
|
- mpb->attributes != MPB_ATTRIB_CHECKSUM_VERIFY) {
|
||||||
|
- version = MPB_VERSION_ATTRIBS;
|
||||||
|
- switch (get_imsm_raid_level(map)) {
|
||||||
|
- case 0: mpb->attributes |= MPB_ATTRIB_RAID0; break;
|
||||||
|
- case 1: mpb->attributes |= MPB_ATTRIB_RAID1; break;
|
||||||
|
- case 10: mpb->attributes |= MPB_ATTRIB_RAID10; break;
|
||||||
|
- case 5: mpb->attributes |= MPB_ATTRIB_RAID5; break;
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
- if (map->num_members >= 5)
|
||||||
|
- version = MPB_VERSION_5OR6_DISK_ARRAY;
|
||||||
|
- else if (dev->status == DEV_CLONE_N_GO)
|
||||||
|
- version = MPB_VERSION_CNG;
|
||||||
|
- else if (get_imsm_raid_level(map) == 5)
|
||||||
|
- version = MPB_VERSION_RAID5;
|
||||||
|
- else if (map->num_members >= 3)
|
||||||
|
- version = MPB_VERSION_3OR4_DISK_ARRAY;
|
||||||
|
- else if (get_imsm_raid_level(map) == 1)
|
||||||
|
- version = MPB_VERSION_RAID1;
|
||||||
|
- else
|
||||||
|
- version = MPB_VERSION_RAID0;
|
||||||
|
+ switch (get_imsm_raid_level(map)) {
|
||||||
|
+ case IMSM_T_RAID0:
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_RAID0;
|
||||||
|
+ break;
|
||||||
|
+ case IMSM_T_RAID1:
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_RAID1;
|
||||||
|
+ break;
|
||||||
|
+ case IMSM_T_RAID5:
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_RAID5;
|
||||||
|
+ break;
|
||||||
|
+ case IMSM_T_RAID10:
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_RAID10;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
- strcpy(((char *) mpb->sig) + strlen(MPB_SIGNATURE), version);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ imsm_write_signature(mpb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -5785,7 +5785,6 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
struct intel_super *super;
|
||||||
|
struct imsm_super *mpb;
|
||||||
|
size_t mpb_size;
|
||||||
|
- char *version;
|
||||||
|
|
||||||
|
if (data_offset != INVALID_SECTORS) {
|
||||||
|
pr_err("data-offset not supported by imsm\n");
|
||||||
|
@@ -5828,13 +5827,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- mpb->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
|
||||||
|
-
|
||||||
|
- version = (char *) mpb->sig;
|
||||||
|
- strcpy(version, MPB_SIGNATURE);
|
||||||
|
- version += strlen(MPB_SIGNATURE);
|
||||||
|
- strcpy(version, MPB_VERSION_RAID0);
|
||||||
|
-
|
||||||
|
+ imsm_update_version_info(super);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -6208,7 +6201,6 @@ static union {
|
||||||
|
|
||||||
|
static int write_super_imsm_spare(struct intel_super *super, struct dl *d)
|
||||||
|
{
|
||||||
|
- struct imsm_super *mpb = super->anchor;
|
||||||
|
struct imsm_super *spare = &spare_record.anchor;
|
||||||
|
__u32 sum;
|
||||||
|
|
||||||
|
@@ -6217,14 +6209,11 @@ static int write_super_imsm_spare(struct intel_super *super, struct dl *d)
|
||||||
|
|
||||||
|
spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super));
|
||||||
|
spare->generation_num = __cpu_to_le32(1UL);
|
||||||
|
- spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
|
||||||
|
spare->num_disks = 1;
|
||||||
|
spare->num_raid_devs = 0;
|
||||||
|
- spare->cache_size = mpb->cache_size;
|
||||||
|
spare->pwr_cycle_count = __cpu_to_le32(1);
|
||||||
|
|
||||||
|
- snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH,
|
||||||
|
- MPB_SIGNATURE MPB_VERSION_RAID0);
|
||||||
|
+ imsm_write_signature(spare);
|
||||||
|
|
||||||
|
spare->disk[0] = d->disk;
|
||||||
|
if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
67
0057-imsm-define-RAID_10-attribute.patch
Normal file
67
0057-imsm-define-RAID_10-attribute.patch
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
From 610fc2ee6fc09e828b14e8fa221b3f4f70fc7b2b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:18 +0200
|
||||||
|
Subject: [PATCH 57/69] imsm: define RAID_10 attribute
|
||||||
|
|
||||||
|
Add MPB_ATTRIB_RAID10_EXT attribute to support RAID 10
|
||||||
|
with more than 4 drives.
|
||||||
|
|
||||||
|
Allow more than 4 drives in imsm_orom_support_raid_disks_raid10().
|
||||||
|
|
||||||
|
This is one of last patches for introducing R10D4+ to imsm.
|
||||||
|
Only small adjustments in reshape behaviours are needed.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
platform-intel.c | 3 ++-
|
||||||
|
super-intel.c | 5 +++++
|
||||||
|
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/platform-intel.c b/platform-intel.c
|
||||||
|
index 40e8fb82..15a9fa5a 100644
|
||||||
|
--- a/platform-intel.c
|
||||||
|
+++ b/platform-intel.c
|
||||||
|
@@ -76,7 +76,8 @@ static bool imsm_orom_support_raid_disks_count_raid5(const int raid_disks)
|
||||||
|
|
||||||
|
static bool imsm_orom_support_raid_disks_count_raid10(const int raid_disks)
|
||||||
|
{
|
||||||
|
- if (raid_disks == 4)
|
||||||
|
+ /* raid_disks count must be higher than 4 and even */
|
||||||
|
+ if (raid_disks >= 4 && (raid_disks & 1) == 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 4b168add..2d309316 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -62,6 +62,8 @@
|
||||||
|
#define MPB_ATTRIB_RAIDCNG __cpu_to_le32(0x00000020)
|
||||||
|
/* supports expanded stripe sizes of 256K, 512K and 1MB */
|
||||||
|
#define MPB_ATTRIB_EXP_STRIPE_SIZE __cpu_to_le32(0x00000040)
|
||||||
|
+/* supports RAID10 with more than 4 drives */
|
||||||
|
+#define MPB_ATTRIB_RAID10_EXT __cpu_to_le32(0x00000080)
|
||||||
|
|
||||||
|
/* The OROM Support RST Caching of Volumes */
|
||||||
|
#define MPB_ATTRIB_NVM __cpu_to_le32(0x02000000)
|
||||||
|
@@ -89,6 +91,7 @@
|
||||||
|
MPB_ATTRIB_RAID10 | \
|
||||||
|
MPB_ATTRIB_RAID5 | \
|
||||||
|
MPB_ATTRIB_EXP_STRIPE_SIZE | \
|
||||||
|
+ MPB_ATTRIB_RAID10_EXT | \
|
||||||
|
MPB_ATTRIB_BBM)
|
||||||
|
|
||||||
|
/* Define attributes that are unused but not harmful */
|
||||||
|
@@ -5552,6 +5555,8 @@ static void imsm_update_version_info(struct intel_super *super)
|
||||||
|
break;
|
||||||
|
case IMSM_T_RAID10:
|
||||||
|
mpb->attributes |= MPB_ATTRIB_RAID10;
|
||||||
|
+ if (map->num_members > 4)
|
||||||
|
+ mpb->attributes |= MPB_ATTRIB_RAID10_EXT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
153
0058-imsm-simplify-imsm_check_attributes.patch
Normal file
153
0058-imsm-simplify-imsm_check_attributes.patch
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
From e0e56f4b2ed514f5049eb96b4ff8f7fdf30a4c49 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:19 +0200
|
||||||
|
Subject: [PATCH 58/69] imsm: simplify imsm_check_attributes()
|
||||||
|
|
||||||
|
imsm_check_attributes() is too complex for that it really does.
|
||||||
|
|
||||||
|
Remove repeating code and simplify the function.
|
||||||
|
Fix function calls.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
super-intel.c | 106 ++++++++------------------------------------------
|
||||||
|
1 file changed, 16 insertions(+), 90 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index 2d309316..d60915e8 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -2135,91 +2135,18 @@ void convert_from_4k(struct intel_super *super)
|
||||||
|
mpb->check_sum = __gen_imsm_checksum(mpb);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/*******************************************************************************
|
||||||
|
- * function: imsm_check_attributes
|
||||||
|
- * Description: Function checks if features represented by attributes flags
|
||||||
|
- * are supported by mdadm.
|
||||||
|
- * Parameters:
|
||||||
|
- * attributes - Attributes read from metadata
|
||||||
|
- * Returns:
|
||||||
|
- * 0 - passed attributes contains unsupported features flags
|
||||||
|
- * 1 - all features are supported
|
||||||
|
- ******************************************************************************/
|
||||||
|
-static int imsm_check_attributes(__u32 attributes)
|
||||||
|
+/**
|
||||||
|
+ * imsm_check_attributes() - Check if features represented by attributes flags are supported.
|
||||||
|
+ *
|
||||||
|
+ * @attributes: attributes read from metadata.
|
||||||
|
+ * Returns: true if all features are supported, false otherwise.
|
||||||
|
+ */
|
||||||
|
+static bool imsm_check_attributes(__u32 attributes)
|
||||||
|
{
|
||||||
|
- int ret_val = 1;
|
||||||
|
- __u32 not_supported = MPB_ATTRIB_SUPPORTED^0xffffffff;
|
||||||
|
-
|
||||||
|
- not_supported &= ~MPB_ATTRIB_IGNORED;
|
||||||
|
-
|
||||||
|
- not_supported &= attributes;
|
||||||
|
- if (not_supported) {
|
||||||
|
- pr_err("(IMSM): Unsupported attributes : %x\n",
|
||||||
|
- (unsigned)__le32_to_cpu(not_supported));
|
||||||
|
- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY \n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_2TB) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_2TB\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_2TB;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAID0) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAID0\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAID0;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAID1) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAID1\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAID1;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAID10) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAID10\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAID10;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAID1E) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAID1E\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAID1E;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAID5) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAID5\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAID5;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_RAIDCNG) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_RAIDCNG\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_RAIDCNG;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_BBM) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_BBM\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_BBM;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY (== MPB_ATTRIB_LEGACY)\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_EXP_STRIPE_SIZE) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_EXP_STRIP_SIZE\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_EXP_STRIPE_SIZE;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_2TB_DISK) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_2TB_DISK\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_2TB_DISK;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_NEVER_USE2) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_NEVER_USE2\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_NEVER_USE2;
|
||||||
|
- }
|
||||||
|
- if (not_supported & MPB_ATTRIB_NEVER_USE) {
|
||||||
|
- dprintf("\t\tMPB_ATTRIB_NEVER_USE\n");
|
||||||
|
- not_supported ^= MPB_ATTRIB_NEVER_USE;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (not_supported)
|
||||||
|
- dprintf("(IMSM): Unknown attributes : %x\n", not_supported);
|
||||||
|
-
|
||||||
|
- ret_val = 0;
|
||||||
|
- }
|
||||||
|
+ if ((attributes & (MPB_ATTRIB_SUPPORTED | MPB_ATTRIB_IGNORED)) == attributes)
|
||||||
|
+ return true;
|
||||||
|
|
||||||
|
- return ret_val;
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map);
|
||||||
|
@@ -2247,11 +2174,10 @@ static void examine_super_imsm(struct supertype *st, char *homehost)
|
||||||
|
creation_time = __le64_to_cpu(mpb->creation_time);
|
||||||
|
printf(" Creation Time : %.24s\n",
|
||||||
|
creation_time ? ctime(&creation_time) : "Unknown");
|
||||||
|
- printf(" Attributes : ");
|
||||||
|
- if (imsm_check_attributes(mpb->attributes))
|
||||||
|
- printf("All supported\n");
|
||||||
|
- else
|
||||||
|
- printf("not supported\n");
|
||||||
|
+
|
||||||
|
+ printf(" Attributes : %08x (%s)\n", mpb->attributes,
|
||||||
|
+ imsm_check_attributes(mpb->attributes) ? "supported" : "not supported");
|
||||||
|
+
|
||||||
|
getinfo_super_imsm(st, &info, NULL);
|
||||||
|
fname_from_uuid(&info, nbuf);
|
||||||
|
printf(" UUID : %s\n", nbuf + 5);
|
||||||
|
@@ -8182,9 +8108,9 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
||||||
|
int current_vol = super->current_vol;
|
||||||
|
|
||||||
|
/* do not assemble arrays when not all attributes are supported */
|
||||||
|
- if (imsm_check_attributes(mpb->attributes) == 0) {
|
||||||
|
+ if (imsm_check_attributes(mpb->attributes) == false) {
|
||||||
|
sb_errors = 1;
|
||||||
|
- pr_err("Unsupported attributes in IMSM metadata.Arrays activation is blocked.\n");
|
||||||
|
+ pr_err("Unsupported attributes in IMSM metadata. Arrays activation is blocked.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* count spare devices, not used in maps
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
168
0059-imsm-support-RAID-10-with-more-than-4-drives.patch
Normal file
168
0059-imsm-support-RAID-10-with-more-than-4-drives.patch
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
From 44463edeb303a464c4a44fcea184b267aeb53302 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Date: Mon, 29 Apr 2024 15:07:20 +0200
|
||||||
|
Subject: [PATCH 59/69] imsm: support RAID 10 with more than 4 drives
|
||||||
|
|
||||||
|
VROC UEFI driver does not support RAID 10 with more than 4 drives.
|
||||||
|
Add user prompts if such layout is being created and for R0->R10
|
||||||
|
reshapes.
|
||||||
|
|
||||||
|
Refactor ask() function:
|
||||||
|
- simplify the code,
|
||||||
|
- remove dialog reattempts,
|
||||||
|
- do no pass '?' sign on function calls,
|
||||||
|
- highlight default option on output.
|
||||||
|
|
||||||
|
This patch completes adding support for R10D4+ to IMSM.
|
||||||
|
|
||||||
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Create.c | 9 ++++++++-
|
||||||
|
super-intel.c | 14 ++++++++++++--
|
||||||
|
util.c | 39 +++++++++++++++++++++++++--------------
|
||||||
|
3 files changed, 45 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Create.c b/Create.c
|
||||||
|
index d94253b1..d033eb68 100644
|
||||||
|
--- a/Create.c
|
||||||
|
+++ b/Create.c
|
||||||
|
@@ -965,6 +965,13 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (st->ss == &super_imsm && s->level == 10 && s->raiddisks > 4) {
|
||||||
|
+ /* Print no matter runstop was specifed */
|
||||||
|
+ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n");
|
||||||
|
+ pr_err("Array won't be suitable as boot device.\n");
|
||||||
|
+ warn = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!have_container && s->level > 0 && ((maxsize-s->size)*100 > maxsize)) {
|
||||||
|
if (c->runstop != 1 || c->verbose >= 0)
|
||||||
|
pr_err("largest drive (%s) exceeds size (%lluK) by more than 1%%\n",
|
||||||
|
@@ -984,7 +991,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
|
||||||
|
|
||||||
|
if (warn) {
|
||||||
|
if (c->runstop!= 1) {
|
||||||
|
- if (!ask("Continue creating array? ")) {
|
||||||
|
+ if (!ask("Continue creating array")) {
|
||||||
|
pr_err("create aborted.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
diff --git a/super-intel.c b/super-intel.c
|
||||||
|
index d60915e8..2b8b6fda 100644
|
||||||
|
--- a/super-intel.c
|
||||||
|
+++ b/super-intel.c
|
||||||
|
@@ -523,6 +523,7 @@ enum imsm_reshape_type {
|
||||||
|
CH_TAKEOVER,
|
||||||
|
CH_MIGRATION,
|
||||||
|
CH_ARRAY_SIZE,
|
||||||
|
+ CH_ABORT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* definition of messages passed to imsm_process_update */
|
||||||
|
@@ -11898,7 +11899,7 @@ success:
|
||||||
|
****************************************************************************/
|
||||||
|
enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
struct geo_params *geo,
|
||||||
|
- int direction)
|
||||||
|
+ int direction, struct context *c)
|
||||||
|
{
|
||||||
|
struct mdinfo info;
|
||||||
|
int change = -1;
|
||||||
|
@@ -11925,6 +11926,14 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||||
|
check_devs = 1;
|
||||||
|
raid_disks += 1; /* parity disk added */
|
||||||
|
} else if (geo->level == IMSM_T_RAID10) {
|
||||||
|
+ if (geo->level == IMSM_T_RAID10 && geo->raid_disks > 2 &&
|
||||||
|
+ !c->force) {
|
||||||
|
+ pr_err("Warning! VROC UEFI driver does not support RAID10 in requested layout.\n");
|
||||||
|
+ pr_err("Array won't be suitable as boot device.\n");
|
||||||
|
+ pr_err("Note: You can omit this check with \"--force\"\n");
|
||||||
|
+ if (ask("Do you want to continue") < 1)
|
||||||
|
+ return CH_ABORT;
|
||||||
|
+ }
|
||||||
|
change = CH_TAKEOVER;
|
||||||
|
check_devs = 1;
|
||||||
|
raid_disks *= 2; /* mirrors added */
|
||||||
|
@@ -12219,7 +12228,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct
|
||||||
|
goto exit_imsm_reshape_super;
|
||||||
|
}
|
||||||
|
super->current_vol = dev->index;
|
||||||
|
- change = imsm_analyze_change(st, &geo, shape->direction);
|
||||||
|
+ change = imsm_analyze_change(st, &geo, shape->direction, c);
|
||||||
|
switch (change) {
|
||||||
|
case CH_TAKEOVER:
|
||||||
|
ret_val = imsm_takeover(st, &geo);
|
||||||
|
@@ -12262,6 +12271,7 @@ static int imsm_reshape_super(struct supertype *st, struct shape *shape, struct
|
||||||
|
free(u);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
+ case CH_ABORT:
|
||||||
|
default:
|
||||||
|
ret_val = 1;
|
||||||
|
}
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 9e837045..4fbf11c4 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -725,23 +725,33 @@ int stat_is_blkdev(char *devname, dev_t *rdev)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * ask() - prompt user for "yes/no" dialog.
|
||||||
|
+ * @mesg: message to be printed, without '?' sign.
|
||||||
|
+ * Returns: 1 if 'Y/y', 0 otherwise.
|
||||||
|
+ *
|
||||||
|
+ * The default value is 'N/n', thus the caps on "N" on prompt.
|
||||||
|
+ */
|
||||||
|
int ask(char *mesg)
|
||||||
|
{
|
||||||
|
- char *add = "";
|
||||||
|
- int i;
|
||||||
|
- for (i = 0; i < 5; i++) {
|
||||||
|
- char buf[100];
|
||||||
|
- fprintf(stderr, "%s%s", mesg, add);
|
||||||
|
- fflush(stderr);
|
||||||
|
- if (fgets(buf, 100, stdin)==NULL)
|
||||||
|
- return 0;
|
||||||
|
- if (buf[0]=='y' || buf[0]=='Y')
|
||||||
|
- return 1;
|
||||||
|
- if (buf[0]=='n' || buf[0]=='N')
|
||||||
|
- return 0;
|
||||||
|
- add = "(y/n) ";
|
||||||
|
+ char buf[3] = {0};
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "%s [y/N]? ", mesg);
|
||||||
|
+ fflush(stderr);
|
||||||
|
+ if (fgets(buf, 3, stdin) == NULL)
|
||||||
|
+ return 0;
|
||||||
|
+ if (strlen(buf) == 1) {
|
||||||
|
+ pr_err("assuming no.\n");
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
- pr_err("assuming 'no'\n");
|
||||||
|
+ if (buf[1] != '\n')
|
||||||
|
+ goto bad_option;
|
||||||
|
+ if (toupper(buf[0]) == 'Y')
|
||||||
|
+ return 1;
|
||||||
|
+ if (toupper(buf[0]) == 'N')
|
||||||
|
+ return 0;
|
||||||
|
+bad_option:
|
||||||
|
+ pr_err("bad option.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1868,6 +1878,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info)
|
||||||
|
|
||||||
|
if (st->ss->external)
|
||||||
|
return sysfs_set_array(info);
|
||||||
|
+
|
||||||
|
memset(&inf, 0, sizeof(inf));
|
||||||
|
inf.major_version = info->array.major_version;
|
||||||
|
inf.minor_version = info->array.minor_version;
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
41
0060-tests-01r5fail-enhance.patch
Normal file
41
0060-tests-01r5fail-enhance.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
From d399c494c6364a6b6d0f965c08443fdc79d1e248 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Thu, 18 Apr 2024 18:23:19 +0800
|
||||||
|
Subject: [PATCH 60/69] tests/01r5fail enhance
|
||||||
|
|
||||||
|
After removing dev0, the recovery starts because it already has a spare
|
||||||
|
disk. It's good to check recovery. But it's not right to check recovery
|
||||||
|
after adding dev3. Because the recovery may finish. It depends on the
|
||||||
|
recovery performance of the testing machine. If the recovery finishes,
|
||||||
|
it will fail. But dev3 is only added as a spare disk, we can't expect
|
||||||
|
there is a recovery happens.
|
||||||
|
|
||||||
|
So remove the codes about adding dev3.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
tests/01r5fail | 6 +-----
|
||||||
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/01r5fail b/tests/01r5fail
|
||||||
|
index 873dba58..c210d6e7 100644
|
||||||
|
--- a/tests/01r5fail
|
||||||
|
+++ b/tests/01r5fail
|
||||||
|
@@ -17,11 +17,7 @@ check wait
|
||||||
|
mdadm $md0 --fail $dev0
|
||||||
|
mdadm $md0 --remove $dev3 $dev0
|
||||||
|
check recovery
|
||||||
|
-check state _UUU
|
||||||
|
-
|
||||||
|
-mdadm $md0 -a $dev3
|
||||||
|
-check recovery
|
||||||
|
check wait
|
||||||
|
check state UUUU
|
||||||
|
|
||||||
|
-mdadm -S $md0
|
||||||
|
\ No newline at end of file
|
||||||
|
+mdadm -S $md0
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
32
0061-tests-01r5integ.broken.patch
Normal file
32
0061-tests-01r5integ.broken.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From a20cb3872c02241e4f0f7cc26933a43bac7d1cbb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Thu, 18 Apr 2024 18:23:20 +0800
|
||||||
|
Subject: [PATCH 61/69] tests/01r5integ.broken
|
||||||
|
|
||||||
|
01r5integ can be run successfully 152 times without error with
|
||||||
|
kernel 6.9.0-rc4 and mdadm - v4.3-51-g52bead95. So remove this
|
||||||
|
one broken case.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
tests/01r5integ.broken | 7 -------
|
||||||
|
1 file changed, 7 deletions(-)
|
||||||
|
delete mode 100644 tests/01r5integ.broken
|
||||||
|
|
||||||
|
diff --git a/tests/01r5integ.broken b/tests/01r5integ.broken
|
||||||
|
deleted file mode 100644
|
||||||
|
index 20737637..00000000
|
||||||
|
--- a/tests/01r5integ.broken
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,7 +0,0 @@
|
||||||
|
-fails rarely
|
||||||
|
-
|
||||||
|
-Fails about 1 in every 30 runs with a sha mismatch error:
|
||||||
|
-
|
||||||
|
- c49ab26e1b01def7874af9b8a6d6d0c29fdfafe6 /dev/md0 does not match
|
||||||
|
- 15dc2f73262f811ada53c65e505ceec9cf025cb9 /dev/md0 with /dev/loop3
|
||||||
|
- missing
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
31
0062-tests-01raid6integ.broken-can-be-removed.patch
Normal file
31
0062-tests-01raid6integ.broken-can-be-removed.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
From 896948b14ad26f15590269dce50ac4896284dc29 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Xiao Ni <xni@redhat.com>
|
||||||
|
Date: Thu, 18 Apr 2024 18:23:21 +0800
|
||||||
|
Subject: [PATCH 62/69] tests/01raid6integ.broken can be removed
|
||||||
|
|
||||||
|
01raid6integ can be run successfully with kernel 6.9.0-rc3.
|
||||||
|
So remove 01raid6integ.broken.
|
||||||
|
|
||||||
|
Signed-off-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
tests/01raid6integ.broken | 7 -------
|
||||||
|
1 file changed, 7 deletions(-)
|
||||||
|
delete mode 100644 tests/01raid6integ.broken
|
||||||
|
|
||||||
|
diff --git a/tests/01raid6integ.broken b/tests/01raid6integ.broken
|
||||||
|
deleted file mode 100644
|
||||||
|
index 1df735f0..00000000
|
||||||
|
--- a/tests/01raid6integ.broken
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,7 +0,0 @@
|
||||||
|
-fails infrequently
|
||||||
|
-
|
||||||
|
-Fails about 1 in 5 with a sha mismatch:
|
||||||
|
-
|
||||||
|
- 8286c2bc045ae2cfe9f8b7ae3a898fa25db6926f /dev/md0 does not match
|
||||||
|
- a083a0738b58caab37fd568b91b177035ded37df /dev/md0 with /dev/loop2 and
|
||||||
|
- /dev/loop3 missing
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
38
0063-Makefile-Move-pie-to-LDFLAGS.patch
Normal file
38
0063-Makefile-Move-pie-to-LDFLAGS.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 893a55831e5abbcd15b171db66fa1f389fb61506 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||||
|
Date: Tue, 7 May 2024 19:32:16 +0200
|
||||||
|
Subject: [PATCH 63/69] Makefile: Move -pie to LDFLAGS
|
||||||
|
|
||||||
|
Move -pie from LDLIBS to LDFLAGS and make LDFLAGS configurable to allow
|
||||||
|
the user to drop it by setting their own LDFLAGS (e.g. PIE could be
|
||||||
|
enabled or disabled by the buildsystem such as buildroot).
|
||||||
|
|
||||||
|
Suggested-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Makefile | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 7c221a89..adac7905 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -132,12 +132,12 @@ CFLAGS += -DUSE_PTHREADS
|
||||||
|
MON_LDFLAGS += -pthread
|
||||||
|
endif
|
||||||
|
|
||||||
|
-LDFLAGS = -Wl,-z,now,-z,noexecstack
|
||||||
|
+LDFLAGS ?= -pie -Wl,-z,now,-z,noexecstack
|
||||||
|
|
||||||
|
# If you want a static binary, you might uncomment these
|
||||||
|
# LDFLAGS += -static
|
||||||
|
# STRIP = -s
|
||||||
|
-LDLIBS = -ldl -pie
|
||||||
|
+LDLIBS = -ldl
|
||||||
|
|
||||||
|
# To explicitly disable libudev, set -DNO_LIBUDEV in CXFLAGS
|
||||||
|
ifeq (, $(findstring -DNO_LIBUDEV, $(CXFLAGS)))
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
30
0064-tests-23rdev-lifetime-fix-a-typo.patch
Normal file
30
0064-tests-23rdev-lifetime-fix-a-typo.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From a0174749426f49a04f11ae0e728cb0a681bfa465 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Date: Thu, 9 May 2024 09:10:59 +0800
|
||||||
|
Subject: [PATCH 64/69] tests/23rdev-lifetime: fix a typo
|
||||||
|
|
||||||
|
"pill" was wrong, while it should be "kill", test will still pass while
|
||||||
|
test thread will not be cleaned up.
|
||||||
|
|
||||||
|
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
tests/23rdev-lifetime | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/tests/23rdev-lifetime b/tests/23rdev-lifetime
|
||||||
|
index 1750b0db..03b61de4 100644
|
||||||
|
--- a/tests/23rdev-lifetime
|
||||||
|
+++ b/tests/23rdev-lifetime
|
||||||
|
@@ -4,7 +4,7 @@ pid=""
|
||||||
|
runtime=2
|
||||||
|
|
||||||
|
clean_up_test() {
|
||||||
|
- pill -9 $pid
|
||||||
|
+ kill -9 $pid
|
||||||
|
echo clear > /sys/block/md0/md/array_state
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
55
0065-util.c-change-devnm-to-const-in-mdmon-functions.patch
Normal file
55
0065-util.c-change-devnm-to-const-in-mdmon-functions.patch
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
From b0f4e8e30f38d83f7e3f53d01d72d4cb3b4d42d7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
|
||||||
|
Date: Tue, 7 May 2024 05:38:55 +0200
|
||||||
|
Subject: [PATCH 65/69] util.c: change devnm to const in mdmon functions
|
||||||
|
|
||||||
|
Devnm shall not be changed inside mdmon_running()
|
||||||
|
and mdmon_pid() functions, change this parameter to const.
|
||||||
|
|
||||||
|
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
mdadm.h | 4 ++--
|
||||||
|
util.c | 4 ++--
|
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 2ff3e463..1ba541fc 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1768,8 +1768,8 @@ extern int is_subarray_active(char *subarray, char *devname);
|
||||||
|
extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet);
|
||||||
|
extern struct superswitch *version_to_superswitch(char *vers);
|
||||||
|
|
||||||
|
-extern int mdmon_running(char *devnm);
|
||||||
|
-extern int mdmon_pid(char *devnm);
|
||||||
|
+extern int mdmon_running(const char *devnm);
|
||||||
|
+extern int mdmon_pid(const char *devnm);
|
||||||
|
extern int check_env(char *name);
|
||||||
|
extern __u32 random32(void);
|
||||||
|
extern void random_uuid(__u8 *buf);
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index 4fbf11c4..e2b490e1 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -1902,7 +1902,7 @@ unsigned long long min_recovery_start(struct mdinfo *array)
|
||||||
|
return recovery_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int mdmon_pid(char *devnm)
|
||||||
|
+int mdmon_pid(const char *devnm)
|
||||||
|
{
|
||||||
|
char path[100];
|
||||||
|
char pid[10];
|
||||||
|
@@ -1922,7 +1922,7 @@ int mdmon_pid(char *devnm)
|
||||||
|
return atoi(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int mdmon_running(char *devnm)
|
||||||
|
+int mdmon_running(const char *devnm)
|
||||||
|
{
|
||||||
|
int pid = mdmon_pid(devnm);
|
||||||
|
if (pid <= 0)
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
121
0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch
Normal file
121
0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
From aa1cc5815d2b14a8b47add18cfaa8264e19c10ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
|
||||||
|
Date: Tue, 7 May 2024 05:38:56 +0200
|
||||||
|
Subject: [PATCH 66/69] Wait for mdmon when it is stared via systemd
|
||||||
|
|
||||||
|
When mdmon is being started it may need few seconds to start.
|
||||||
|
For now, we didn't wait for it. Introduce wait_for_mdmon()
|
||||||
|
function, which waits up to 5 seconds for mdmon to start completely.
|
||||||
|
|
||||||
|
Signed-off-by: Kinga Stefaniuk <kinga.stefaniuk@intel.com>
|
||||||
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
||||||
|
---
|
||||||
|
Assemble.c | 4 ++--
|
||||||
|
Grow.c | 7 ++++---
|
||||||
|
mdadm.h | 2 ++
|
||||||
|
util.c | 29 +++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 37 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Assemble.c b/Assemble.c
|
||||||
|
index f5e9ab1f..83dced19 100644
|
||||||
|
--- a/Assemble.c
|
||||||
|
+++ b/Assemble.c
|
||||||
|
@@ -2173,8 +2173,8 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||||
|
if (!mdmon_running(st->container_devnm))
|
||||||
|
start_mdmon(st->container_devnm);
|
||||||
|
ping_monitor(st->container_devnm);
|
||||||
|
- if (mdmon_running(st->container_devnm) &&
|
||||||
|
- st->update_tail == NULL)
|
||||||
|
+ if (wait_for_mdmon(st->container_devnm) == MDADM_STATUS_SUCCESS &&
|
||||||
|
+ !st->update_tail)
|
||||||
|
st->update_tail = &st->updates;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/Grow.c b/Grow.c
|
||||||
|
index 87ed9214..1923c27c 100644
|
||||||
|
--- a/Grow.c
|
||||||
|
+++ b/Grow.c
|
||||||
|
@@ -2134,7 +2134,7 @@ int Grow_reshape(char *devname, int fd,
|
||||||
|
if (!mdmon_running(st->container_devnm))
|
||||||
|
start_mdmon(st->container_devnm);
|
||||||
|
ping_monitor(container);
|
||||||
|
- if (mdmon_running(st->container_devnm) == false) {
|
||||||
|
+ if (wait_for_mdmon(st->container_devnm) != MDADM_STATUS_SUCCESS) {
|
||||||
|
pr_err("No mdmon found. Grow cannot continue.\n");
|
||||||
|
goto release;
|
||||||
|
}
|
||||||
|
@@ -3218,7 +3218,8 @@ static int reshape_array(char *container, int fd, char *devname,
|
||||||
|
if (!mdmon_running(container))
|
||||||
|
start_mdmon(container);
|
||||||
|
ping_monitor(container);
|
||||||
|
- if (mdmon_running(container) && st->update_tail == NULL)
|
||||||
|
+ if (wait_for_mdmon(container) == MDADM_STATUS_SUCCESS &&
|
||||||
|
+ !st->update_tail)
|
||||||
|
st->update_tail = &st->updates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -5173,7 +5174,7 @@ int Grow_continue_command(char *devname, int fd, struct context *c)
|
||||||
|
start_mdmon(container);
|
||||||
|
ping_monitor(container);
|
||||||
|
|
||||||
|
- if (mdmon_running(container) == false) {
|
||||||
|
+ if (wait_for_mdmon(container) != MDADM_STATUS_SUCCESS) {
|
||||||
|
pr_err("No mdmon found. Grow cannot continue.\n");
|
||||||
|
ret_val = 1;
|
||||||
|
goto Grow_continue_command_exit;
|
||||||
|
diff --git a/mdadm.h b/mdadm.h
|
||||||
|
index 1ba541fc..b71d7b32 100644
|
||||||
|
--- a/mdadm.h
|
||||||
|
+++ b/mdadm.h
|
||||||
|
@@ -1770,6 +1770,8 @@ extern struct superswitch *version_to_superswitch(char *vers);
|
||||||
|
|
||||||
|
extern int mdmon_running(const char *devnm);
|
||||||
|
extern int mdmon_pid(const char *devnm);
|
||||||
|
+extern mdadm_status_t wait_for_mdmon(const char *devnm);
|
||||||
|
+
|
||||||
|
extern int check_env(char *name);
|
||||||
|
extern __u32 random32(void);
|
||||||
|
extern void random_uuid(__u8 *buf);
|
||||||
|
diff --git a/util.c b/util.c
|
||||||
|
index e2b490e1..bf79742f 100644
|
||||||
|
--- a/util.c
|
||||||
|
+++ b/util.c
|
||||||
|
@@ -1932,6 +1932,35 @@ int mdmon_running(const char *devnm)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * wait_for_mdmon() - Waits for mdmon within specified time.
|
||||||
|
+ * @devnm: Device for which mdmon should start.
|
||||||
|
+ *
|
||||||
|
+ * Function waits for mdmon to start. It may need few seconds
|
||||||
|
+ * to start, we set timeout to 5, it should be sufficient.
|
||||||
|
+ * Do not wait if mdmon has been started.
|
||||||
|
+ *
|
||||||
|
+ * Return: MDADM_STATUS_SUCCESS if mdmon is running, error code otherwise.
|
||||||
|
+ */
|
||||||
|
+mdadm_status_t wait_for_mdmon(const char *devnm)
|
||||||
|
+{
|
||||||
|
+ const time_t mdmon_timeout = 5;
|
||||||
|
+ time_t start_time = time(0);
|
||||||
|
+
|
||||||
|
+ if (mdmon_running(devnm))
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+
|
||||||
|
+ pr_info("Waiting for mdmon to start\n");
|
||||||
|
+ while (time(0) - start_time < mdmon_timeout) {
|
||||||
|
+ sleep_for(0, MSEC_TO_NSEC(200), true);
|
||||||
|
+ if (mdmon_running(devnm))
|
||||||
|
+ return MDADM_STATUS_SUCCESS;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ pr_err("Timeout waiting for mdmon\n");
|
||||||
|
+ return MDADM_STATUS_ERROR;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int start_mdmon(char *devnm)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
62
0069-mdadm-Fix-compilation-for-32-bit-arch.patch
Normal file
62
0069-mdadm-Fix-compilation-for-32-bit-arch.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
From c5879860eac64ddd7bec4ba50c9adbfebcbf1d2e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
Date: Wed, 15 May 2024 13:26:28 +0200
|
||||||
|
Subject: [PATCH 69/69] mdadm: Fix compilation for 32-bit arch
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Casting void pointer to __u64 works for 64-bit arch but fails to compile
|
||||||
|
on 32-bit arch like i686.
|
||||||
|
|
||||||
|
Fail on i686 platform:
|
||||||
|
drive_encryption.c: In function ‘nvme_security_recv_ioctl’:
|
||||||
|
drive_encryption.c:236:25: error: cast from pointer to integer of
|
||||||
|
different size [-Werror=pointer-to-int-cast]
|
||||||
|
236 | nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
| ^
|
||||||
|
drive_encryption.c: In function ‘nvme_identify_ioctl’:
|
||||||
|
drive_encryption.c:271:25: error: cast from pointer to integer of
|
||||||
|
different size [-Werror=pointer-to-int-cast]
|
||||||
|
271 | nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
| ^
|
||||||
|
cc1: all warnings being treated as errors
|
||||||
|
make: *** [Makefile:211: drive_encryption.o] Error 1
|
||||||
|
|
||||||
|
This change adds cast void pointer to uintptr_t first to ensure that
|
||||||
|
proper pointer size is used for casting from pointer type. Then is safe to
|
||||||
|
cast it to __u64 because it is tracked as u_int, regardless it is 32-bit
|
||||||
|
or 64-bit arch.
|
||||||
|
|
||||||
|
Reported-by: Xiao Ni <xni@redhat.com>
|
||||||
|
Fixes: cc48406887b3 ("Add reading Opal NVMe encryption information")
|
||||||
|
Signed-off-by: Blazej Kucman <blazej.kucman@intel.com>
|
||||||
|
---
|
||||||
|
drive_encryption.c | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/drive_encryption.c b/drive_encryption.c
|
||||||
|
index 27da9621..a4ad799f 100644
|
||||||
|
--- a/drive_encryption.c
|
||||||
|
+++ b/drive_encryption.c
|
||||||
|
@@ -233,7 +233,7 @@ nvme_security_recv_ioctl(int disk_fd, __u8 sec_protocol, __u16 comm_id, void *re
|
||||||
|
nvme_cmd.cdw10 = sec_protocol << 24 | comm_id << 8;
|
||||||
|
nvme_cmd.cdw11 = buf_size;
|
||||||
|
nvme_cmd.data_len = buf_size;
|
||||||
|
- nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
+ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer;
|
||||||
|
|
||||||
|
status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
|
||||||
|
if (status != 0) {
|
||||||
|
@@ -268,7 +268,7 @@ nvme_identify_ioctl(int disk_fd, void *response_buffer, size_t buf_size, const i
|
||||||
|
nvme_cmd.opcode = NVME_IDENTIFY;
|
||||||
|
nvme_cmd.cdw10 = NVME_IDENTIFY_CONTROLLER_DATA;
|
||||||
|
nvme_cmd.data_len = buf_size;
|
||||||
|
- nvme_cmd.addr = (__u64)response_buffer;
|
||||||
|
+ nvme_cmd.addr = (__u64)(uintptr_t)response_buffer;
|
||||||
|
|
||||||
|
status = ioctl(disk_fd, NVME_IOCTL_ADMIN_CMD, &nvme_cmd);
|
||||||
|
if (status != 0) {
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
32
mdadm.spec
32
mdadm.spec
@ -1,7 +1,7 @@
|
|||||||
Name: mdadm
|
Name: mdadm
|
||||||
Version: 4.3
|
Version: 4.3
|
||||||
# extraversion is used to define rhel internal version
|
# extraversion is used to define rhel internal version
|
||||||
%define extraversion 1
|
%define extraversion 2
|
||||||
Release: %{extraversion}%{?dist}
|
Release: %{extraversion}%{?dist}
|
||||||
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
||||||
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||||||
@ -60,6 +60,32 @@ Patch037: 0038-mdadm-Fix-native-detail-export.patch
|
|||||||
Patch038: 0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch
|
Patch038: 0039-sysfs-remove-vers-parameter-from-sysfs_set_array.patch
|
||||||
Patch039: 0040-mdadm-fix-grow-segfault-for-IMSM.patch
|
Patch039: 0040-mdadm-fix-grow-segfault-for-IMSM.patch
|
||||||
Patch040: 0041-Remove-all-if-zeros-pt.2.patch
|
Patch040: 0041-Remove-all-if-zeros-pt.2.patch
|
||||||
|
Patch041: 0042-mdadm-Move-pr_vrb-define-to-mdadm.h.patch
|
||||||
|
Patch042: 0043-Add-reading-Opal-NVMe-encryption-information.patch
|
||||||
|
Patch043: 0044-Add-reading-SATA-encryption-information.patch
|
||||||
|
Patch044: 0045-Add-key-ENCRYPTION_NO_VERIFY-to-conf.patch
|
||||||
|
Patch045: 0046-imsm-print-disk-encryption-information.patch
|
||||||
|
Patch046: 0047-imsm-drive-encryption-policy-implementation.patch
|
||||||
|
Patch047: 0048-mdadm-add-CHANGELOG.md.patch
|
||||||
|
Patch048: 0049-mdadm-Add-MAINTAINERS.md.patch
|
||||||
|
Patch049: 0050-mdadm-Add-README.md.patch
|
||||||
|
Patch050: 0051-Create.c-fix-uclibc-build.patch
|
||||||
|
Patch051: 0052-mdadm-pass-struct-context-for-external-reshapes.patch
|
||||||
|
Patch052: 0053-mdadm-use-struct-context-in-reshape_super.patch
|
||||||
|
Patch053: 0054-imsm-add-support-for-literal-RAID-10.patch
|
||||||
|
Patch054: 0055-imsm-refactor-RAID-level-handling.patch
|
||||||
|
Patch055: 0056-imsm-bump-minimal-version.patch
|
||||||
|
Patch056: 0057-imsm-define-RAID_10-attribute.patch
|
||||||
|
Patch057: 0058-imsm-simplify-imsm_check_attributes.patch
|
||||||
|
Patch058: 0059-imsm-support-RAID-10-with-more-than-4-drives.patch
|
||||||
|
Patch059: 0060-tests-01r5fail-enhance.patch
|
||||||
|
Patch060: 0061-tests-01r5integ.broken.patch
|
||||||
|
Patch061: 0062-tests-01raid6integ.broken-can-be-removed.patch
|
||||||
|
Patch062: 0063-Makefile-Move-pie-to-LDFLAGS.patch
|
||||||
|
Patch063: 0064-tests-23rdev-lifetime-fix-a-typo.patch
|
||||||
|
Patch064: 0065-util.c-change-devnm-to-const-in-mdmon-functions.patch
|
||||||
|
Patch065: 0066-Wait-for-mdmon-when-it-is-stared-via-systemd.patch
|
||||||
|
Patch066: 0069-mdadm-Fix-compilation-for-32-bit-arch.patch
|
||||||
|
|
||||||
# Fedora customization patches
|
# Fedora customization patches
|
||||||
|
|
||||||
@ -138,6 +164,10 @@ install -m644 %{SOURCE5} %{buildroot}/etc/libreport/events.d
|
|||||||
/usr/share/mdadm/mdcheck
|
/usr/share/mdadm/mdcheck
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu May 16 2024 Xiao Ni <xni@redhat.com> 4.3-2
|
||||||
|
- Update to latest upstream
|
||||||
|
- Resolves RHEL-36424
|
||||||
|
|
||||||
* Fri Mar 29 2024 Xiao Ni <xni@redhat.com> 4.3-1
|
* Fri Mar 29 2024 Xiao Ni <xni@redhat.com> 4.3-1
|
||||||
- Update to 4.3 and to latest upstream
|
- Update to 4.3 and to latest upstream
|
||||||
- Resolves RHEL-30529
|
- Resolves RHEL-30529
|
||||||
|
Loading…
Reference in New Issue
Block a user