X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=util.c;h=05be64c6add692959d89e94ab00cd83963d2aa02;hp=f09fd843c9aa8bec32aeb0e39da7e6c47e9ba5c2;hb=d23534e4646313a67296b295666d165a87bb2c92;hpb=8320878543bb5e49b5acb24fa919ff11be485c61 diff --git a/util.c b/util.c index f09fd843..05be64c6 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" @@ -154,6 +149,73 @@ int get_linux_version() return (a*1000000)+(b*1000)+c; } +#ifndef MDASSEMBLE +long long parse_size(char *size) +{ + /* parse 'size' which should be a number optionally + * followed by 'K', 'M', or 'G'. + * Without a suffix, K is assumed. + * Number returned is in sectors (half-K) + */ + char *c; + long long s = strtoll(size, &c, 10); + if (s > 0) { + switch (*c) { + case 'K': + c++; + default: + s *= 2; + break; + case 'M': + c++; + s *= 1024 * 2; + break; + case 'G': + c++; + s *= 1024 * 1024 * 2; + break; + } + } + if (*c) + s = 0; + return s; +} + +int parse_layout_10(char *layout) +{ + int copies, rv; + char *cp; + /* Parse the layout string for raid10 */ + /* 'f', 'o' or 'n' followed by a number <= raid_disks */ + if ((layout[0] != 'n' && layout[0] != 'f' && layout[0] != 'o') || + (copies = strtoul(layout+1, &cp, 10)) < 1 || + copies > 200 || + *cp) + return -1; + if (layout[0] == 'n') + rv = 256 + copies; + else if (layout[0] == 'o') + rv = 0x10000 + (copies<<8) + 1; + else + rv = 1 + (copies<<8); + return rv; +} + +int parse_layout_faulty(char *layout) +{ + /* Parse the layout string for 'faulty' */ + int ln = strcspn(layout, "0123456789"); + char *m = strdup(layout); + int mode; + m[ln] = 0; + mode = map_name(faultylayout, m); + if (mode == UnSet) + return -1; + + return mode | (atoi(layout+ln)<< ModeShift); +} +#endif + void remove_partitions(int fd) { /* remove partitions from this block devices. @@ -199,9 +261,9 @@ int enough(int level, int raid_disks, int layout, int clean, } while (first != 0); return 1; - case -4: + case LEVEL_MULTIPATH: return avail_disks>= 1; - case -1: + case LEVEL_LINEAR: case 0: return avail_disks == raid_disks; case 1: @@ -274,17 +336,15 @@ void copy_uuid(void *a, int b[4], int swapuuid) memcpy(a, b, 16); } -char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep) +char *__fname_from_uuid(int id[4], int swap, char *buf, char sep) { 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); + copy_uuid(uuid, id, swap); for (i = 0; i < 4; i++) { - id = uuid[i]; if (i) *c++ = sep; for (j = 3; j >= 0; j--) { @@ -293,6 +353,12 @@ char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char } } return buf; + +} + +char *fname_from_uuid(struct supertype *st, struct mdinfo *info, char *buf, char sep) +{ + return __fname_from_uuid(info->uuid, st->ss->swapuuid, buf, sep); } #ifndef MDASSEMBLE @@ -868,6 +934,8 @@ void wait_for(char *dev, int fd) return; usleep(200000); } + if (i == 25) + dprintf("%s: timeout waiting for %s\n", __func__, dev); } struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL }; @@ -1094,8 +1162,11 @@ int add_disk(int mdfd, struct supertype *st, int rv; #ifndef MDASSEMBLE if (st->ss->external) { - rv = sysfs_add_disk(sra, info, - info->disk.state & (1<disk.state & (1<recovery_start = MaxSector; + else + info->recovery_start = 0; + rv = sysfs_add_disk(sra, info); if (! rv) { struct mdinfo *sd2; for (sd2 = sra->devs; sd2; sd2=sd2->next) @@ -1142,7 +1213,7 @@ int set_array_info(int mdfd, struct supertype *st, struct mdinfo *info) char *devnum2devname(int num) { char name[100]; - if (num > 0) + if (num >= 0) sprintf(name, "md%d", num); else sprintf(name, "md_d%d", -1-num); @@ -1303,6 +1374,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) {