[PATCH 1/1] mdadm: load md_mod first

Xiao Ni <[email protected]>
Newsgroups gmane.linux.raid
Message-ID <[email protected]>
Load md_mod first before setting module parameter legacy_async_del_gendisk
Everything works well if md_mod is built in kernel. If not, create and
assemble will fail.

Fixes: d354d314db86 ("mdadm: Create array with sync del gendisk mode")
Signed-off-by: Xiao Ni <[email protected]>
---
 mdadm.h  |  2 +-
 mdopen.c | 30 ++++++------------------------
 util.c   | 35 +++++++++++++++++++++++++++++++++--
 3 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/mdadm.h b/mdadm.h
index b63dded31a17..9b7052dabee4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -860,7 +860,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets,
 			   unsigned long long start, unsigned long long length,
 			   char *src_buf);
 extern bool sysfs_is_libata_allow_tpm_enabled(const int verbose);
-extern bool init_md_mod_param(void);
+extern bool init_md_mod(void);
 
 #ifndef Sendmail
 #define Sendmail "/usr/lib/sendmail -t"
diff --git a/mdopen.c b/mdopen.c
index b685603d6de5..9af0284b6914 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -38,33 +38,15 @@ int create_named_array(char *devnm)
 	};
 
 	fd = open(new_array_file, O_WRONLY);
-	if (fd < 0 && errno == ENOENT) {
-		char buf[PATH_MAX] = {0};
-		char *env_ptr;
-
-		env_ptr = getenv("PATH");
-		/*
-		 * When called by udev worker context, path of modprobe
-		 * might not be in env PATH. Set sbin paths into PATH
-		 * env to avoid potential failure when run modprobe here.
-		 */
-		if (env_ptr)
-			snprintf(buf, PATH_MAX - 1, "%s:%s", env_ptr,
-				 "/sbin:/usr/sbin:/usr/local/sbin");
-		else
-			snprintf(buf, PATH_MAX - 1, "%s",
-				 "/sbin:/usr/sbin:/usr/local/sbin");
-
-		setenv("PATH", buf, 1);
-
-		if (system("modprobe md_mod") == 0)
-			fd = open(new_array_file, O_WRONLY);
-	}
 	if (fd >= 0) {
 		n = write(fd, devnm, strlen(devnm));
 		close(fd);
+	} else {
+		pr_err("Fail to open %s\n", new_array_file);
+		return 0;
 	}
-	if (fd < 0 || n != (int)strlen(devnm)) {
+
+	if (n != (int)strlen(devnm)) {
 		pr_err("Fail to create %s when using %s, fallback to creation via node\n",
 			devnm, new_array_file);
 		return 0;
@@ -148,7 +130,7 @@ int create_mddev(char *dev, char *name, int trustworthy,
 	char devnm[32];
 	char cbuf[400];
 
-	if (!init_md_mod_param()) {
+	if (!init_md_mod()) {
 		pr_err("init md module parameters fail\n");
 		return -1;
 	}
diff --git a/util.c b/util.c
index 146f38fddd82..cdc55435a707 100644
--- a/util.c
+++ b/util.c
@@ -2583,10 +2583,41 @@ bool set_md_mod_parameter(const char *name, const char *value)
 	return ret;
 }
 
-/* Init kernel md_mod parameters here if needed */
-bool init_md_mod_param(void)
+/* Init kernel md_mod and parameters here if needed */
+bool init_md_mod(void)
 {
 	bool ret = true;
+	char module_path[32];
+	FILE *fp;
+
+	snprintf(module_path, sizeof(module_path), "/sys/module/md_mod");
+	fp = fopen(module_path, "r");
+	if (fp == NULL) {
+
+		char buf[PATH_MAX] = {0};
+		char *env_ptr;
+
+		env_ptr = getenv("PATH");
+		/*
+		 * When called by udev worker context, path of modprobe
+		 * might not be in env PATH. Set sbin paths into PATH
+		 * env to avoid potential failure when run modprobe here.
+		 */
+		if (env_ptr)
+			snprintf(buf, PATH_MAX - 1, "%s:%s", env_ptr,
+				 "/sbin:/usr/sbin:/usr/local/sbin");
+		else
+			snprintf(buf, PATH_MAX - 1, "%s",
+				 "/sbin:/usr/sbin:/usr/local/sbin");
+
+		setenv("PATH", buf, 1);
+
+		if (system("modprobe md_mod") != 0) {
+			pr_err("Can't load kernel module md_mod\n");
+			return false;
+		}
+	} else
+		fclose(fp);
 
 	/*
 	 * In kernel 9e59d609763f calls del_gendisk in sync way. So device
-- 
2.32.0 (Apple Git-132)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.