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>
This commit is contained in:
Neil Brown 2005-12-05 05:52:50 +00:00
parent d9d4e4698f
commit 8b0dabea07
6 changed files with 42 additions and 15 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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",

View File

@ -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;

View File

@ -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);

23
util.c
View File

@ -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 };