summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2005-12-05 05:52:50 +0000
committerNeil Brown <neilb@suse.de>2005-12-05 05:52:50 +0000
commit8b0dabea0762e2cd786c1539845823ecd914657a (patch)
tree0a6b3a8c089910f963fa180c47996343fdef43e9
parentd9d4e4698f11b937c42f1c983aca57fd50038a73 (diff)
downloadmdadm-8b0dabea0762e2cd786c1539845823ecd914657a.tar.gz
mdadm-8b0dabea0762e2cd786c1539845823ecd914657a.tar.xz
mdadm-8b0dabea0762e2cd786c1539845823ecd914657a.zip
Allow scanning of devices listed in /proc/partitions independant of /dev
If a device found in /proc/partitions isn't listed in /dev, then mknod a temporary name and open that. Signed-off-by: Neil Brown <neilb@suse.de>
-rw-r--r--Assemble.c10
-rw-r--r--ChangeLog2
-rw-r--r--Examine.c4
-rw-r--r--config.c17
-rw-r--r--mdadm.h1
-rw-r--r--util.c23
6 files changed, 42 insertions, 15 deletions
diff --git a/Assemble.c b/Assemble.c
index ae06f57..d251500 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -195,7 +195,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
super = NULL;
}
- dfd = open(devname, O_RDONLY|O_EXCL, 0);
+ dfd = dev_open(devname, O_RDONLY|O_EXCL);
if (dfd < 0) {
if ((inargv && verbose >= 0) || verbose > 0)
fprintf(stderr, Name ": cannot open device %s: %s\n",
@@ -287,7 +287,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
st->ss->update_super(&info, super, update, devname, verbose);
- dfd = open(devname, O_RDWR|O_EXCL, 0);
+ dfd = dev_open(devname, O_RDWR|O_EXCL);
if (dfd < 0)
fprintf(stderr, Name ": Cannot open %s for superblock update\n",
devname);
@@ -418,7 +418,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
devices[chosen_drive].devname, devices[chosen_drive].raid_disk,
(int)(devices[chosen_drive].events),
(int)(devices[most_recent].events));
- fd = open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
+ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
if (fd < 0) {
fprintf(stderr, Name ": Couldn't open %s for write - not updating\n",
devices[chosen_drive].devname);
@@ -468,7 +468,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (!devices[j].uptodate)
continue;
chosen_drive = j;
- if ((fd=open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
+ if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
fprintf(stderr, Name ": Cannot open %s: %s\n",
devices[j].devname, strerror(errno));
return 1;
@@ -534,7 +534,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (change) {
int fd;
- fd = open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
+ fd = dev_open(devices[chosen_drive].devname, O_RDWR|O_EXCL);
if (fd < 0) {
fprintf(stderr, Name ": Could open %s for write - cannot Assemble array.\n",
devices[chosen_drive].devname);
diff --git a/ChangeLog b/ChangeLog
index c7612a6..76cc6ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@ Changes Prior to this release
- Support little-endian (Rather than hostendian) bitmaps.
- Return correct error code from 'mdadm -S'
- Remove extra blank line from 'mdadm -Eb' output.
+ - Allow scanning of devices listed in /proc/partitions even
+ if they don't appear in /dev.
Changes Prior to 2.1 release
- Fix assembling of raid10 array when devices are missing.
diff --git a/Examine.c b/Examine.c
index fa120a5..e07b27e 100644
--- a/Examine.c
+++ b/Examine.c
@@ -51,7 +51,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust, struct su
* utime, state etc
*
* If (brief) gather devices for same array and just print a mdadm.conf line including devices=
- * if devlist==NULL, use conf_get_devs(
+ * if devlist==NULL, use conf_get_devs()
*/
int fd;
void *super = NULL;
@@ -71,7 +71,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust, struct su
for (; devlist ; devlist=devlist->next) {
struct supertype *st = forcest;
- fd = open(devlist->devname, O_RDONLY);
+ fd = dev_open(devlist->devname, O_RDONLY);
if (fd < 0) {
if (!scan)
fprintf(stderr,Name ": cannot open %s: %s\n",
diff --git a/config.c b/config.c
index a5d5edd..b444515 100644
--- a/config.c
+++ b/config.c
@@ -214,6 +214,8 @@ mddev_dev_t load_partitions(void)
while (fgets(buf, 1024, f)) {
int major, minor;
char *name, *mp;
+ mddev_dev_t d;
+
buf[1023] = '\0';
if (buf[0] != ' ')
continue;
@@ -223,14 +225,15 @@ mddev_dev_t load_partitions(void)
minor = strtoul(mp, NULL, 10);
name = map_dev(major, minor);
- if (name) {
- mddev_dev_t d;
-
- d = malloc(sizeof(*d));
- d->devname = strdup(name);
- d->next = rv;
- rv = d;
+ if (!name) {
+ snprintf(buf, 1024, "%d:%d", major, minor);
+ name = buf;
}
+
+ d = malloc(sizeof(*d));
+ d->devname = strdup(name);
+ d->next = rv;
+ rv = d;
}
fclose(f);
return rv;
diff --git a/mdadm.h b/mdadm.h
index 2abb0f0..97831b4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -278,6 +278,7 @@ extern int check_reiser(int fd, char *name);
extern int check_raid(int fd, char *name);
extern int get_mdp_major(void);
+extern int dev_open(char *dev, int flags);
extern int is_standard(char *dev, int *nump);
diff --git a/util.c b/util.c
index e702b8d..9204d53 100644
--- a/util.c
+++ b/util.c
@@ -589,7 +589,28 @@ void put_md_name(char *name)
unlink(name);
}
-
+int dev_open(char *dev, int flags)
+{
+ /* like 'open', but if 'dev' matches %d:%d, create a temp
+ * block device and open that
+ */
+ char *e;
+ int fd = -1;
+ char devname[32];
+ int major = strtoul(dev, &e, 0);
+ int minor;
+ if (e > dev && *e == ':' && e[1] &&
+ (minor = strtoul(e+1, &e, 0)) >= 0 &&
+ *e == 0) {
+ snprintf(devname, sizeof(devname), "/dev/.tmp.md.%d:%d", major, minor);
+ if (mknod(devname, S_IFBLK|0600, makedev(major, minor))==0) {
+ fd = open(devname, flags);
+ unlink(devname);
+ }
+ } else
+ fd = open(dev, flags);
+ return fd;
+}
struct superswitch *superlist[] = { &super0, &super1, NULL };