/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2001-2002 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
{
void *super;
struct mdinfo info;
- struct mddev_ident_s ident;
time_t crtime;
char *level;
struct supertype *st = guess_super(fd);
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
- st->ss->getinfo_super(&info, &ident, super);
+ st->ss->getinfo_super(&info, super);
free(super);
crtime = info.array.ctime;
level = map_num(pers, info.array.level);
#ifdef UCLIBC
int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
{
+ return 0;
}
-char *map_dev(int major, int minor)
+char *map_dev(int major, int minor, int create)
{
#if 0
fprintf(stderr, "Warning - fail to map %d,%d to a device name\n",
}
int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, int flag, struct FTW *s), int nopenfd, int flags)
{
- ftw(path, add_dev_1, nopenfd);
+ return ftw(path, add_dev_1, nopenfd);
}
#endif
int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
{
- if ((stb->st_mode&S_IFMT)== S_IFBLK) {
- char *n = strdup(name);
- struct devmap *dm = malloc(sizeof(*dm));
- if (dm) {
- dm->major = major(stb->st_rdev);
- dm->minor = minor(stb->st_rdev);
- dm->name = n;
- dm->next = devlist;
- devlist = dm;
+ struct stat st;
+ if (S_ISLNK(stb->st_mode)) {
+ stat(name, &st);
+ stb = &st;
}
- }
- return 0;
+
+ if ((stb->st_mode&S_IFMT)== S_IFBLK) {
+ char *n = strdup(name);
+ struct devmap *dm = malloc(sizeof(*dm));
+ if (strncmp(n, "/dev/./", 7)==0)
+ strcpy(n+4, name+6);
+ if (dm) {
+ dm->major = major(stb->st_rdev);
+ dm->minor = minor(stb->st_rdev);
+ dm->name = n;
+ dm->next = devlist;
+ devlist = dm;
+ }
+ }
+ return 0;
}
/*
* deliberately so prefer it over a standard name.
* This applies only to names for MD devices.
*/
-char *map_dev(int major, int minor)
+char *map_dev(int major, int minor, int create)
{
struct devmap *p;
char *std = NULL, *nonstd=NULL;
+ int did_check = 0;
+ retry:
if (!devlist_ready) {
- nftw("/dev", add_dev, 10, FTW_PHYS);
+ char *dev = "/dev";
+ struct stat stb;
+ if (lstat(dev, &stb)==0 &&
+ S_ISLNK(stb.st_mode))
+ dev = "/dev/.";
+ nftw(dev, add_dev, 10, FTW_PHYS);
devlist_ready=1;
+ did_check = 1;
}
for (p=devlist; p; p=p->next)
nonstd = p->name;
}
}
+ if (!std && !nonstd && !did_check) {
+ devlist_ready = 0;
+ goto retry;
+ }
+ if (create && !std && !nonstd) {
+ static char buf[30];
+ snprintf(buf, sizeof(buf), "%d:%d", major, minor);
+ nonstd = buf;
+ }
+
return nonstd ? nonstd : std;
}
&& (stb.st_rdev == rdev))
return devname;
}
- dn = map_dev(major(rdev), minor(rdev));
+ dn = map_dev(major(rdev), minor(rdev), 0);
if (dn)
return dn;
snprintf(devname, sizeof(devname), "/dev/.tmp.md%d", dev);
rv = ss->load_super(st, fd, &sbp, NULL);
if (rv == 0) {
struct mdinfo info;
- struct mddev_ident_s ident;
- ss->getinfo_super(&info, &ident, sbp);
+ ss->getinfo_super(&info, sbp);
if (bestsuper == -1 ||
besttime < info.array.ctime) {
bestsuper = i;