File 0114-re-add-make-re-add-try-to-write-sysfs-node-first.patch of Package mdadm.5365

From 9465f1705853ec47d95f31a332fb2e91f865cdaa Mon Sep 17 00:00:00 2001
From: Guoqing Jiang <gqjiang@suse.com>
Date: Wed, 7 Oct 2015 10:06:54 +0800
Subject: [PATCH 168/359] re-add: make re-add try to write sysfs node first
References: bsc#1081910

If sysfs node existed, we should try to write "re-add" to it.

Signed-off-by: Guoqing Jiang <gqjiang@suse.com>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Coly Li <colyli@suse.de>

---
 Manage.c | 13 +++++++++++++
 mdadm.h  |  1 +
 sysfs.c  |  6 ++++++
 3 files changed, 20 insertions(+)

diff --git a/Manage.c b/Manage.c
index b5450dd..2df303d 100644
--- a/Manage.c
+++ b/Manage.c
@@ -1309,6 +1309,7 @@ int Manage_subdevs(char *devname, int fd,
 	int sysfd = -1;
 	int count = 0; /* number of actions taken */
 	struct mdinfo info;
+	struct mdinfo devinfo;
 	int frozen = 0;
 	int busy = 0;
 	int raid_slot = -1;
@@ -1517,6 +1518,18 @@ int Manage_subdevs(char *devname, int fd,
 				pr_err("Cannot add disks to a \'member\' array, perform this operation on the parent container\n");
 				goto abort;
 			}
+
+			/* Let's first try to write re-add to sysfs */
+			if (rdev != 0 &&
+			    (dv->disposition == 'A' || dv->disposition == 'F')) {
+				sysfs_init_dev(&devinfo, rdev);
+				if (sysfs_set_str(&info, &devinfo, "state", "re-add") == 0) {
+					pr_err("re-add %s to %s succeed\n",
+						dv->devname, info.sys_name);
+					break;
+				}
+			}
+
 			if (dv->disposition == 'F')
 				/* Need to remove first */
 				ioctl(fd, HOT_REMOVE_DISK, rdev);
diff --git a/mdadm.h b/mdadm.h
index 6bdaa37..5633663 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -539,6 +539,7 @@ enum sysfs_read_flags {
  */
 extern int sysfs_open(char *devnm, char *devname, char *attr);
 extern void sysfs_init(struct mdinfo *mdi, int fd, char *devnm);
+extern void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid);
 extern void sysfs_free(struct mdinfo *sra);
 extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options);
 extern int sysfs_attr_match(const char *attr, const char *str);
diff --git a/sysfs.c b/sysfs.c
index 7268470..f1fd610 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -74,6 +74,12 @@ int sysfs_open(char *devnm, char *devname, char *attr)
 	return fd;
 }
 
+void sysfs_init_dev(struct mdinfo *mdi, unsigned long devid)
+{
+	snprintf(mdi->sys_name,
+		 sizeof(mdi->sys_name), "dev-%s", devid2kname(devid));
+}
+
 void sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
 {
 	mdi->sys_name[0] = 0;
-- 
2.16.1

openSUSE Build Service is sponsored by