}
}
+const int uuid_match_any[4] = { ~0, ~0, ~0, ~0 };
int same_uuid(int a[4], int b[4], int swapuuid)
{
+ if (memcmp(a, uuid_match_any, sizeof(int[4])) == 0 ||
+ memcmp(b, uuid_match_any, sizeof(int[4])) == 0)
+ return 1;
+
if (swapuuid) {
/* parse uuids are hostendian.
* uuid's from some superblocks are big-ending
char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep)
{
- int i;
+ int i, j;
+ int id;
char uuid[16];
char *c = buf;
strcpy(c, "UUID-");
c += strlen(c);
copy_uuid(uuid, info->uuid, st->ss->swapuuid);
- for (i=0; i<16; i++) {
- if (i && (i&3)==0)
+ for (i = 0; i < 4; i++) {
+ id = uuid[i];
+ if (i)
*c++ = sep;
- sprintf(c,"%02x", (unsigned char)uuid[i]);
- c+= 2;
+ for (j = 3; j >= 0; j--) {
+ sprintf(c,"%02x", (unsigned char) uuid[j+4*i]);
+ c+= 2;
+ }
}
return buf;
}
if (strncmp(d, "/d",2)==0)
d += 2, type=1; /* /dev/md/dN{pM} */
else if (strncmp(d, "/md_d", 5)==0)
- d += 5, type=1; /* /dev/md_dNpM */
+ d += 5, type=1; /* /dev/md_dN{pM} */
else if (strncmp(d, "/md", 3)==0)
d += 3, type=-1; /* /dev/mdN */
else if (d-dev > 3 && strncmp(d-2, "md/", 3)==0)
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 buf;
}
+
+void print_r10_layout(int layout)
+{
+ int near = layout & 255;
+ int far = (layout >> 8) & 255;
+ int offset = (layout&0x10000);
+ char *sep = "";
+
+ if (near != 1) {
+ printf("%s near=%d", sep, near);
+ sep = ",";
+ }
+ if (far != 1)
+ printf("%s %s=%d", sep, offset?"offset":"far", far);
+ if (near*far == 1)
+ printf("NO REDUNDANCY");
+}
#endif
unsigned long long calc_array_size(int level, int raid_disks, int layout,
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;