linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Adam Kwolek <adam.kwolek@intel.com>
To: neilb@suse.de
Cc: linux-raid@vger.kernel.org, dan.j.williams@intel.com,
	ed.ciechanowski@intel.com
Subject: [PATCH 05/10] Add spares to raid0 array using takeover
Date: Thu, 02 Dec 2010 09:19:20 +0100	[thread overview]
Message-ID: <20101202081920.4639.78609.stgit@gklab-170-024.igk.intel.com> (raw)
In-Reply-To: <20101202080818.4639.38119.stgit@gklab-170-024.igk.intel.com>

Spares are used by Online Capacity Expansion to expand array.
To run expansion on raid0, spares have to be added to raid0 volume also.
Raid0 cannot have spares (no mdmon runs for raid0 array).
To do this, takeover to raid5 (and back) is used. mdmon runs temporary for raid5 and spare drives can be added to container.

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
---

 Manage.c |  120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 119 insertions(+), 1 deletions(-)

diff --git a/Manage.c b/Manage.c
index a203ec9..8c04ba9 100644
--- a/Manage.c
+++ b/Manage.c
@@ -31,6 +31,103 @@
 #define START_MD     		_IO (MD_MAJOR, 2)
 #define STOP_MD      		_IO (MD_MAJOR, 3)
 
+
+void takeover5to0(struct mdinfo *sra)
+{
+	char *c;
+	int err;
+
+	dprintf("Takeover Raid5->Raid0.\n");
+
+	if (sra == NULL)
+		return;
+
+	c = map_num(pers, 0);
+	if (c == NULL)
+		return;
+
+	err = sysfs_set_str(sra, NULL, "level", c);
+
+	if (err)
+		fprintf(stderr,
+			Name ": %s: could not set level "
+			"to %s for external super.\n",
+			sra->sys_name, c);
+	sysfs_free(sra);
+}
+
+struct mdinfo *takeover0to5(int fd)
+{
+	struct mdinfo *ret_val = NULL;
+	int devnum;
+	struct mdinfo *sra = NULL;
+	struct mdstat_ent *mdstat = NULL;
+	struct mdstat_ent *m;
+	int dev_fd = -1;
+
+	dprintf("Takeover Raid0->Raid5.\n");
+	devnum = fd2devnum(fd);
+	if (mdmon_running(devnum)) {
+		dprintf("mdmon is runnig for this container - takeover is not required\n");
+		return ret_val;
+	}
+
+	mdstat = mdstat_read(0, 0);
+	for (m=mdstat; m; m=m->next) {
+		if (m->metadata_version &&
+		    strncmp(m->metadata_version, "external:", 9)==0 &&
+		    is_subarray(m->metadata_version+9) &&
+		    devname2devnum(m->metadata_version+10) == devnum) {
+			if (strncmp(m->level, "raid0", 5) == 0) {
+				char *p = NULL;
+				char dev_name[PATH_MAX];
+				int err;
+
+				sprintf(dev_name, "/dev/md%i", m->devnum);
+				dev_fd = open_mddev(dev_name , 1);
+				if (dev_fd < 0)
+					continue;
+
+				sra = sysfs_read(dev_fd, 0, GET_VERSION|GET_LEVEL);
+				if (!sra)
+					break;
+
+				err = sysfs_set_str(sra, NULL, "level", "raid5");
+				if (err) {
+					fprintf(stderr, Name": %s: could not set level to "
+						"raid5 for external super.\n", sra->sys_name);
+					break;
+				}
+
+				/* return to this raid level and do not release
+				*/
+				ret_val = sra;
+				sra = NULL;
+
+				/* if after takeover mdmon is not running,
+				 * start it
+				 */
+				if (!mdmon_running(devnum))
+					start_mdmon(devnum);
+				p = devnum2devname(devnum);
+				if (p) {
+					ping_monitor(p);
+					free(p);
+				}
+				sleep(1);
+				break;
+			}
+		}
+	}
+
+	sysfs_free(sra);
+	free_mdstat(mdstat);
+	if (dev_fd >= 0)
+		close(dev_fd);
+
+	return ret_val;
+}
+
 int Manage_ro(char *devname, int fd, int readonly)
 {
 	/* switch to readonly or rw
@@ -832,6 +929,7 @@ int Manage_subdevs(char *devname, int fd,
 				struct mdinfo *sra;
 				int container_fd;
 				int devnum = fd2devnum(fd);
+				char *devname = NULL;
 
 				container_fd = open_dev_excl(devnum);
 				if (container_fd < 0) {
@@ -840,10 +938,17 @@ int Manage_subdevs(char *devname, int fd,
 						dv->devname);
 					return 1;
 				}
+				/* Raid 0 add spare via takeover
+				*/
+				struct mdinfo *return_raid0_sra = NULL;
+				/* try to perform takeover if needed
+				*/
+				return_raid0_sra = takeover0to5(container_fd);
 
 				if (!mdmon_running(devnum)) {
 					fprintf(stderr, Name ": add failed for %s: mdmon not running\n",
 						dv->devname);
+					takeover5to0(return_raid0_sra);
 					close(container_fd);
 					return 1;
 				}
@@ -852,7 +957,13 @@ int Manage_subdevs(char *devname, int fd,
 				if (!sra) {
 					fprintf(stderr, Name ": add failed for %s: sysfs_read failed\n",
 						dv->devname);
+					takeover5to0(return_raid0_sra);
 					close(container_fd);
+					devname = devnum2devname(devnum);
+					if (devname) {
+						ping_monitor(devname);
+						free(devname);
+					}
 					return 1;
 				}
 				sra->array.level = LEVEL_CONTAINER;
@@ -864,12 +975,19 @@ int Manage_subdevs(char *devname, int fd,
 				if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
 					fprintf(stderr, Name ": add new device to external metadata"
 						" failed for %s\n", dv->devname);
+					takeover5to0(return_raid0_sra);
 					close(container_fd);
+					sysfs_free(sra);
 					return 1;
 				}
-				ping_monitor(devnum2devname(devnum));
+				takeover5to0(return_raid0_sra);
 				sysfs_free(sra);
 				close(container_fd);
+				devname = devnum2devname(devnum);
+				if (devname) {
+					ping_monitor(devname);
+					free(devname);
+				}
 			} else if (ioctl(fd, ADD_NEW_DISK, &disc)) {
 				fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
 					dv->devname, j, strerror(errno));


  parent reply	other threads:[~2010-12-02  8:19 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-02  8:18 [PATCH 00/10] Pre-migration patch series Adam Kwolek
2010-12-02  8:18 ` [PATCH 01/10] FIX: Cannot exit monitor after takeover Adam Kwolek
2010-12-02  8:18 ` [PATCH 02/10] FIX: Problem with removing array " Adam Kwolek
2010-12-03  3:46   ` Neil Brown
2010-12-02  8:19 ` [PATCH 03/10] FIX: Add error code for raid_disks set Adam Kwolek
2010-12-02 18:56   ` Dan Williams
2010-12-02  8:19 ` [PATCH 04/10] Add support to skip slot configuration Adam Kwolek
2010-12-02  8:19 ` Adam Kwolek [this message]
2010-12-03  3:52   ` [PATCH 05/10] Add spares to raid0 array using takeover Neil Brown
2010-12-02  8:19 ` [PATCH 06/10] FIX: open backup file for reshape as function Adam Kwolek
2010-12-03  4:01   ` Neil Brown
2010-12-02  8:19 ` [PATCH 07/10] FIX: Do not use layout for raid4 and raid0 while geo map computing Adam Kwolek
2010-12-02  8:19 ` [PATCH 08/10] FIX: sync_completed_fd handler has to be closed Adam Kwolek
2010-12-02  8:19 ` [PATCH 09/10] FIX: Honor !reshape state on wait_reshape() entry Adam Kwolek
2010-12-03  4:11   ` Neil Brown
2010-12-02  8:19 ` [PATCH 10/10] FIX: wait_backup() sometimes hungs Adam Kwolek
2010-12-03  4:16   ` Neil Brown
2010-12-03  7:45     ` Kwolek, Adam
2010-12-03 10:35       ` Neil Brown
2010-12-03  4:19 ` [PATCH 00/10] Pre-migration patch series Neil Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101202081920.4639.78609.stgit@gklab-170-024.igk.intel.com \
    --to=adam.kwolek@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=ed.ciechanowski@intel.com \
    --cc=linux-raid@vger.kernel.org \
    --cc=neilb@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).