From b6e15d73b19d963de7412560cc651e3b6d6a5428 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Thu, 20 Nov 2008 14:51:42 +1100
Subject: [PATCH] mdmon: pass symbolic name to mdmon instead of device name.

Now that names in /dev are usually created (eventually) by udev,
it isn't really safe to rely in finding a name in /dev to pass to
mdmon to identify which array to monitor.
And it isn't really necessary to have a name in /dev.
So just pass the symbolic name, e.g. md127 or md123.

Change util.c to pass that name, and change mdmon to process the
name sensibly.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 mdadm.h   |    2 +-
 mdmon.c   |   17 +++++++++++++----
 monitor.c |    2 +-
 util.c    |   13 ++++++++++---
 4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/mdadm.h b/mdadm.h
index 9d819f9..2772650 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -634,7 +634,6 @@ struct supertype {
 			*  external:/md0/12
 			*/
 	int devcnt;
-	char *device_name; /* e.g. /dev/md/whatever */
 
 	struct mdinfo *devs;
 
@@ -761,6 +760,7 @@ extern int check_raid(int fd, char *name);
 
 extern int get_mdp_major(void);
 extern int dev_open(char *dev, int flags);
+extern int open_dev(int devnum);
 extern int open_dev_excl(int devnum);
 extern int is_standard(char *dev, int *nump);
 extern int same_dev(char *one, char *two);
diff --git a/mdmon.c b/mdmon.c
index 5ee8346..73c244a 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -287,6 +287,8 @@ int main(int argc, char *argv[])
 	int ignore;
 	char *container_name = NULL;
 	char *switchroot = NULL;
+	int devnum;
+	char *devname;
 
 	switch (argc) {
 	case 2:
@@ -304,7 +306,14 @@ int main(int argc, char *argv[])
 		usage();
 	}
 
-	mdfd = open(container_name, O_RDWR);
+	devnum = devname2devnum(container_name);
+	devname = devnum2devname(devnum);
+	if (strcmp(container_name, devname) != 0) {
+		fprintf(stderr, "mdmon: %s is not a valid md device name\n",
+			container_name);
+		exit(1);
+	}
+	mdfd = open_dev(devnum);
 	if (mdfd < 0) {
 		fprintf(stderr, "mdmon: %s: %s\n", container_name,
 			strerror(errno));
@@ -342,9 +351,8 @@ int main(int argc, char *argv[])
 		pfd[0] = pfd[1] = -1;
 
 	container = malloc(sizeof(*container));
-	container->devnum = fd2devnum(mdfd);
-	container->devname = devnum2devname(container->devnum);
-	container->device_name = container_name;
+	container->devnum = devnum;
+	container->devname = devname;
 	container->arrays = NULL;
 
 	if (!container->devname) {
@@ -462,6 +470,7 @@ int main(int argc, char *argv[])
 			container_name);
 		exit(3);
 	}
+	close(mdfd);
 
 	/* Ok, this is close enough.  We can say goodbye to our parent now.
 	 */
diff --git a/monitor.c b/monitor.c
index 15791f4..5c17910 100644
--- a/monitor.c
+++ b/monitor.c
@@ -469,7 +469,7 @@ static int wait_and_act(struct supertype *container, int nowait)
 		 * problem as there are no active arrays, there is
 		 * nothing that we need to be ready to do.
 		 */
-		int fd = open(container->device_name, O_RDONLY|O_EXCL);
+		int fd = open_dev_excl(container->devnum);
 		if (fd >= 0 || errno != EBUSY) {
 			/* OK, we are safe to leave */
 			if (sigterm && !dirty_arrays)
diff --git a/util.c b/util.c
index 2b4f902..d7597fa 100644
--- a/util.c
+++ b/util.c
@@ -813,6 +813,14 @@ int dev_open(char *dev, int flags)
 	return fd;
 }
 
+int open_dev(int devnum)
+{
+	char buf[20];
+
+	sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
+	return dev_open(buf, O_RDWR);
+}
+
 int open_dev_excl(int devnum)
 {
 	char buf[20];
@@ -1261,9 +1269,8 @@ int start_mdmon(int devnum)
 		for (i=0; paths[i]; i++)
 			if (paths[i][0])
 				execl(paths[i], "mdmon",
-				      map_dev(dev2major(devnum),
-					      dev2minor(devnum),
-					      1), NULL);
+				      devnum2devname(devnum),
+				      NULL);
 		exit(1);
 	case -1: fprintf(stderr, Name ": cannot run mdmon. "
 			 "Array remains readonly\n");
-- 
1.5.6.5