X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;ds=sidebyside;f=util.c;h=1736d70791c8ce5d145f6c01516384f4c19adb30;hb=a7d307da935631f8b9f7bbae16db297d30dc21b9;hp=4c0494236dfd6a97bf0d838d083346cf95c467ae;hpb=9968e376a17dd6d815473f05843b1f257b2babd5;p=thirdparty%2Fmdadm.git diff --git a/util.c b/util.c index 4c049423..1736d707 100644 --- a/util.c +++ b/util.c @@ -222,8 +222,13 @@ int enough(int level, int raid_disks, int layout, int clean, } } +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 @@ -427,7 +432,7 @@ int is_standard(char *dev, int *nump) 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) @@ -635,6 +640,23 @@ char *human_size_brief(long long bytes) ); 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, @@ -806,6 +828,20 @@ int open_dev_excl(int devnum) 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; +} + struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL }; #if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) @@ -1094,13 +1130,34 @@ int devname2devnum(char *name) 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; } @@ -1109,7 +1166,7 @@ int fd2devnum(int fd) struct stat stb; if (fstat(fd, &stb) == 0) return stat2devnum(&stb); - return -1; + return NoMdDev; } int mdmon_running(int devnum) @@ -1166,7 +1223,7 @@ int start_mdmon(int devnum) NULL }; - if (env_no_mdmon()) + if (check_env("MDADM_NO_MDMON")) return 0; len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf)); @@ -1205,9 +1262,9 @@ int start_mdmon(int devnum) 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;