int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)
{
struct stat st;
+
if (S_ISLNK(stb->st_mode)) {
- stat(name, &st);
+ if (stat(name, &st) != 0)
+ return 0;
stb = &st;
}
return fd;
}
+int open_dev(int devnum)
+{
+ char buf[20];
+
+ sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
+ return dev_open(buf, O_RDWR);
+}
+
int open_dev_excl(int devnum)
{
char buf[20];
return -1;
}
+int same_dev(char *one, char *two)
+{
+ struct stat st1, st2;
+ if (stat(one, &st1) != 0)
+ return 0;
+ if (stat(two, &st2) != 0)
+ return 0;
+ if ((st1.st_mode & S_IFMT) != S_IFBLK)
+ return 0;
+ if ((st2.st_mode & S_IFMT) != S_IFBLK)
+ return 0;
+ return st1.st_rdev == st2.st_rdev;
+}
+
+void wait_for(char *dev)
+{
+ int i;
+
+ for (i=0 ; i<25 ; i++) {
+ struct stat stb;
+ if (stat(dev, &stb) == 0)
+ return;
+ usleep(200000);
+ }
+}
+
struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL };
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
int stat2devnum(struct stat *st)
{
+ char path[30];
+ char link[200];
+ char *cp;
+ int n;
+
if ((S_IFMT & st->st_mode) == S_IFBLK) {
if (major(st->st_rdev) == MD_MAJOR)
return minor(st->st_rdev);
- else
- return -1- (minor(st->st_rdev)>>6);
+ else if (major(st->st_rdev) == get_mdp_major())
+ return -1- (minor(st->st_rdev)>>MdpMinorShift);
+
+ /* must be an extended-minor partition. Look at the
+ * /sys/dev/block/%d:%d link which must look like
+ * ../../block/mdXXX/mdXXXpYY
+ */
+ sprintf(path, "/sys/dev/block/%d:%d", major(st->st_rdev),
+ minor(st->st_rdev));
+ n = readlink(path, link, sizeof(link)-1);
+ if (n <= 0)
+ return NoMdDev;
+ link[n] = 0;
+ cp = strrchr(link, '/');
+ if (cp) *cp = 0;
+ cp = strchr(link, '/');
+ if (cp && strncmp(cp, "/md", 3) == 0)
+ return devname2devnum(cp+1);
}
- return -1;
+ return NoMdDev;
}
struct stat stb;
if (fstat(fd, &stb) == 0)
return stat2devnum(&stb);
- return -1;
+ return NoMdDev;
}
int mdmon_running(int devnum)
NULL
};
- if (env_no_mdmon())
+ if (check_env("MDADM_NO_MDMON"))
return 0;
len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf));
for (i=0; paths[i]; i++)
if (paths[i][0])
execl(paths[i], "mdmon",
- map_dev(dev2major(devnum),
- dev2minor(devnum),
- 1), NULL);
+ devnum2devname(devnum),
+ NULL);
exit(1);
case -1: fprintf(stderr, Name ": cannot run mdmon. "
"Array remains readonly\n");
return 0;
}
-int env_no_mdmon(void)
+int check_env(char *name)
{
- char *val = getenv("MDADM_NO_MDMON");
+ char *val = getenv(name);
if (val && atoi(val) == 1)
return 1;
*st->update_tail = mu;
st->update_tail = &mu->next;
}
-
-struct superswitch *find_metadata_methods(char *vers)
-{
- if (strcmp(vers, "ddf") == 0)
- return &super_ddf;
- if (strcmp(vers, "imsm") == 0)
- return &super_imsm;
- return NULL;
-}
#endif /* MDASSEMBLE */
#ifdef __TINYC__