X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=util.c;h=2543971026656ac8afca07c30d3d2f983a4a55a0;hp=b2fbec7a91c7f3f2059c66b6ed0488d156b73ca7;hb=148acb7baaa810b68d55df4c1784d6bd0dfd1b78;hpb=bf68e9d9ab185121b6004fc81b531bce8348726d diff --git a/util.c b/util.c index b2fbec7a..25439710 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2006 Neil Brown + * Copyright (C) 2001-2009 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Neil Brown - * Email: - * Paper: Neil Brown - * School of Computer Science and Engineering - * The University of New South Wales - * Sydney, 2052 - * Australia + * Email: */ #include "mdadm.h" @@ -511,14 +506,13 @@ int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, /* * Find a block device with the right major/minor number. * If we find multiple names, choose the shortest. - * If we find a non-standard name, it is probably there - * deliberately so prefer it over a standard name. + * If we find a name in /dev/md/, we prefer that. * This applies only to names for MD devices. */ char *map_dev(int major, int minor, int create) { struct devmap *p; - char *std = NULL, *nonstd=NULL; + char *regular = NULL, *preferred=NULL; int did_check = 0; if (major == 0 && minor == 0) @@ -545,27 +539,27 @@ char *map_dev(int major, int minor, int create) for (p=devlist; p; p=p->next) if (p->major == major && p->minor == minor) { - if (is_standard(p->name, NULL)) { - if (std == NULL || - strlen(p->name) < strlen(std)) - std = p->name; + if (strncmp(p->name, "/dev/md/",8) == 0) { + if (preferred == NULL || + strlen(p->name) < strlen(preferred)) + preferred = p->name; } else { - if (nonstd == NULL || - strlen(p->name) < strlen(nonstd)) - nonstd = p->name; + if (regular == NULL || + strlen(p->name) < strlen(regular)) + regular = p->name; } } - if (!std && !nonstd && !did_check) { + if (!regular && !preferred && !did_check) { devlist_ready = 0; goto retry; } - if (create && !std && !nonstd) { + if (create && !regular && !preferred) { static char buf[30]; snprintf(buf, sizeof(buf), "%d:%d", major, minor); - nonstd = buf; + regular = buf; } - return nonstd ? nonstd : std; + return preferred ? preferred : regular; } unsigned long calc_csum(void *super, int bytes) @@ -765,7 +759,7 @@ int find_free_devnum(int use_partitions) { int devnum; for (devnum = 127; devnum != 128; - devnum = devnum ? devnum-1 : (1<<22)-1) { + devnum = devnum ? devnum-1 : (1<<20)-1) { char *dn; int _devnum; @@ -813,6 +807,14 @@ int dev_open(char *dev, int flags) 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]; @@ -844,13 +846,20 @@ int same_dev(char *one, char *two) return st1.st_rdev == st2.st_rdev; } -void wait_for(char *dev) +void wait_for(char *dev, int fd) { int i; + struct stat stb_want; + + if (fstat(fd, &stb_want) != 0 || + (stb_want.st_mode & S_IFMT) != S_IFBLK) + return; for (i=0 ; i<25 ; i++) { struct stat stb; - if (stat(dev, &stb) == 0) + if (stat(dev, &stb) == 0 && + (stb.st_mode & S_IFMT) == S_IFBLK && + (stb.st_rdev == stb_want.st_rdev)) return; usleep(200000); } @@ -901,7 +910,10 @@ struct supertype *super_by_fd(int fd) if (sra) sysfs_free(sra); sra = sysfs_read(-1, devnum, GET_VERSION); - verstr = sra->text_version ? : "-no-metadata-"; + if (sra && sra->text_version[0]) + verstr = sra->text_version; + else + verstr = "-no-metadata-"; } for (i = 0; st == NULL && superlist[i] ; i++) @@ -1077,7 +1089,8 @@ int add_disk(int mdfd, struct supertype *st, int rv; #ifndef MDASSEMBLE if (st->ss->external) { - rv = sysfs_add_disk(sra, info); + rv = sysfs_add_disk(sra, info, + info->disk.state & (1<devs; sd2; sd2=sd2->next) @@ -1261,9 +1274,8 @@ int start_mdmon(int devnum) 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"); @@ -1286,6 +1298,17 @@ int check_env(char *name) return 0; } +__u32 random32(void) +{ + __u32 rv; + int rfd = open("/dev/urandom", O_RDONLY); + if (rfd < 0 || read(rfd, &rv, 4) != 4) + rv = random(); + if (rfd >= 0) + close(rfd); + return rv; +} + #ifndef MDASSEMBLE int flush_metadata_updates(struct supertype *st) {