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",
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);
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);
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;
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);
- 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.
* 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;
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",
while (fgets(buf, 1024, f)) {
int major, minor;
char *name, *mp;
+ mddev_dev_t d;
+
buf[1023] = '\0';
if (buf[0] != ' ')
continue;
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;
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);
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 };