From 8b0dabea0762e2cd786c1539845823ecd914657a Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 5 Dec 2005 05:52:50 +0000 Subject: [PATCH] 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 --- Assemble.c | 10 +++++----- ChangeLog | 2 ++ Examine.c | 4 ++-- config.c | 17 ++++++++++------- mdadm.h | 1 + util.c | 23 ++++++++++++++++++++++- 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Assemble.c b/Assemble.c index ae06f572..d251500d 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 c7612a67..76cc6eaf 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 fa120a53..e07b27e0 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 a5d5edd2..b4445154 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 2abb0f0c..97831b49 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 e702b8d2..9204d531 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 }; -- 2.39.2