X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=util.c;h=d0765a6dabad4c678fc9ec7ca7dfc069d28802b6;hp=6985a7076204f6b11cf2b617594d968025ca8307;hb=72d566f68d495261608a900b2d8cb8d037cd9178;hpb=aabe020dd2465c9a4df6e72f35f7a986bd7c5327 diff --git a/util.c b/util.c index 6985a707..d0765a6d 100644 --- a/util.c +++ b/util.c @@ -32,6 +32,8 @@ #include #include +int __offroot; + /* * following taken from linux/blkpg.h because they aren't * anywhere else and it isn't safe to #include linux/ * stuff. @@ -192,6 +194,7 @@ long long parse_size(char *size) * followed by 'K', 'M', or 'G'. * Without a suffix, K is assumed. * Number returned is in sectors (half-K) + * -1 returned on error. */ char *c; long long s = strtoll(size, &c, 10); @@ -213,7 +216,7 @@ long long parse_size(char *size) } } if (*c) - s = 0; + s = -1; return s; } @@ -241,7 +244,7 @@ int parse_layout_faulty(char *layout) { /* Parse the layout string for 'faulty' */ int ln = strcspn(layout, "0123456789"); - char *m = strdup(layout); + char *m = xstrdup(layout); int mode; m[ln] = 0; mode = map_name(faultylayout, m); @@ -309,10 +312,15 @@ int test_partition_from_id(dev_t id) return rv; } -int enough(int level, int raid_disks, int layout, int clean, - char *avail, int avail_disks) +int enough(int level, int raid_disks, int layout, int clean, char *avail) { int copies, first; + int i; + int avail_disks = 0; + + for (i = 0; i < raid_disks; i++) + avail_disks += !!avail[i]; + switch (level) { case 10: /* This is the tricky one - we need to check @@ -369,8 +377,8 @@ int enough_fd(int fd) if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 || array.raid_disks <= 0) return 0; - avail = calloc(array.raid_disks, 1); - for (i=0; i < 1024 && array.nr_disks > 0; i++) { + avail = xcalloc(array.raid_disks, 1); + for (i=0; i < MAX_DISKS && array.nr_disks > 0; i++) { disk.number = i; if (ioctl(fd, GET_DISK_INFO, &disk) != 0) continue; @@ -387,7 +395,7 @@ int enough_fd(int fd) } /* This is used on an active array, so assume it is clean */ rv = enough(array.level, array.raid_disks, array.layout, - 1, avail, avail_disks); + 1, avail); free(avail); return rv; } @@ -497,7 +505,7 @@ int check_ext2(int fd, char *name) mtime = sb[44]|(sb[45]|(sb[46]|sb[47]<<8)<<8)<<8; bsize = sb[24]|(sb[25]|(sb[26]|sb[27]<<8)<<8)<<8; size = sb[4]|(sb[5]|(sb[6]|sb[7]<<8)<<8)<<8; - fprintf(stderr, Name ": %s appears to contain an ext2fs file system\n", + pr_err("%s appears to contain an ext2fs file system\n", name); fprintf(stderr," size=%dK mtime=%s", size*(1<ignore_hw_compat = 1; st->ss->load_super(st, fd, name); /* Looks like a raid array .. */ - fprintf(stderr, Name ": %s appears to be part of a raid array:\n", + pr_err("%s appears to be part of a raid array:\n", name); st->ss->getinfo_super(st, &info, NULL); st->ss->free_super(st); @@ -567,7 +575,7 @@ int ask(char *mesg) return 0; add = "(y/n) "; } - fprintf(stderr, Name ": assuming 'no'\n"); + pr_err("assuming 'no'\n"); return 0; } #endif /* MDASSEMBLE */ @@ -704,6 +712,8 @@ void print_r10_layout(int layout) unsigned long long calc_array_size(int level, int raid_disks, int layout, int chunksize, unsigned long long devsize) { + if (level == 1) + return devsize; devsize &= ~(unsigned long long)((chunksize>>9)-1); return get_data_disks(level, layout, raid_disks) * devsize; } @@ -959,9 +969,10 @@ struct supertype *super_by_fd(int fd, char **subarrayp) char *dev = verstr+1; subarray = strchr(dev, '/'); - if (subarray) + if (subarray) { *subarray++ = '\0'; - subarray = strdup(subarray); + subarray = xstrdup(subarray); + } container = devname2devnum(dev); if (sra) sysfs_free(sra); @@ -1013,10 +1024,7 @@ struct supertype *dup_super(struct supertype *orig) if (!orig) return orig; - st = malloc(sizeof(*st)); - if (!st) - return st; - memset(st, 0, sizeof(*st)); + st = xcalloc(1, sizeof(*st)); st->ss = orig->ss; st->max_devs = orig->max_devs; st->minor_version = orig->minor_version; @@ -1036,8 +1044,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type) int bestsuper = -1; int i; - st = malloc(sizeof(*st)); - memset(st, 0, sizeof(*st)); + st = xcalloc(1, sizeof(*st)); st->container_dev = NoMdDev; for (i=0 ; superlist[i]; i++) { @@ -1095,7 +1102,7 @@ int get_dev_size(int fd, char *dname, unsigned long long *sizep) ldsize <<= 9; } else { if (dname) - fprintf(stderr, Name ": Cannot get size of %s: %s\b", + pr_err("Cannot get size of %s: %s\b", dname, strerror(errno)); return 0; } @@ -1237,22 +1244,19 @@ int check_partitions(int fd, char *dname, unsigned long long freesize, /* There appears to be a partition table here */ if (freesize == 0) { /* partitions will not be visible in new device */ - fprintf(stderr, - Name ": partition table exists on %s but will be lost or\n" - " meaningless after creating array\n", - dname); + pr_err("partition table exists on %s but will be lost or\n" + " meaningless after creating array\n", + dname); return 1; } else if (endofpart > freesize) { /* last partition overlaps metadata */ - fprintf(stderr, - Name ": metadata will over-write last partition on %s.\n", - dname); + pr_err("metadata will over-write last partition on %s.\n", + dname); return 1; } else if (size && endofpart > size) { /* partitions will be truncated in new device */ - fprintf(stderr, - Name ": array size is too small to cover all partitions on %s.\n", - dname); + pr_err("array size is too small to cover all partitions on %s.\n", + dname); return 1; } } @@ -1264,7 +1268,7 @@ void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk) int d; ioctl(mdfd, GET_ARRAY_INFO, ainf); - for (d = 0 ; d < 1024 ; d++) { + for (d = 0 ; d < MAX_DISKS ; d++) { if (ioctl(mdfd, GET_DISK_INFO, disk) == 0 && (disk->major || disk->minor)) return; @@ -1378,7 +1382,7 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet) fd = open(dev, O_RDWR|O_EXCL); if (fd < 0) { if (!quiet) - fprintf(stderr, Name ": Couldn't open %s, aborting\n", + pr_err("Couldn't open %s, aborting\n", dev); return -1; } @@ -1386,51 +1390,49 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet) st->devnum = fd2devnum(fd); if (st->devnum == NoMdDev) { if (!quiet) - fprintf(stderr, - Name ": Failed to determine device number for %s\n", - dev); + pr_err("Failed to determine device number for %s\n", + dev); goto close_fd; } mdi = sysfs_read(fd, st->devnum, GET_VERSION|GET_LEVEL); if (!mdi) { if (!quiet) - fprintf(stderr, Name ": Failed to read sysfs for %s\n", + pr_err("Failed to read sysfs for %s\n", dev); goto close_fd; } if (mdi->array.level != UnSet) { if (!quiet) - fprintf(stderr, Name ": %s is not a container\n", dev); + pr_err("%s is not a container\n", dev); goto free_sysfs; } st->ss = version_to_superswitch(mdi->text_version); if (!st->ss) { if (!quiet) - fprintf(stderr, - Name ": Operation not supported for %s metadata\n", - mdi->text_version); + pr_err("Operation not supported for %s metadata\n", + mdi->text_version); goto free_sysfs; } st->devname = devnum2devname(st->devnum); if (!st->devname) { if (!quiet) - fprintf(stderr, Name ": Failed to allocate device name\n"); + pr_err("Failed to allocate device name\n"); goto free_sysfs; } if (!st->ss->load_container) { if (!quiet) - fprintf(stderr, Name ": %s is not a container\n", dev); + pr_err("%s is not a container\n", dev); goto free_name; } if (st->ss->load_container(st, fd, NULL)) { if (!quiet) - fprintf(stderr, Name ": Failed to load metadata for %s\n", + pr_err("Failed to load metadata for %s\n", dev); goto free_name; } @@ -1438,7 +1440,7 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet) info = st->ss->container_content(st, subarray); if (!info) { if (!quiet) - fprintf(stderr, Name ": Failed to find subarray-%s in %s\n", + pr_err("Failed to find subarray-%s in %s\n", subarray, dev); goto free_super; } @@ -1482,7 +1484,7 @@ int add_disk(int mdfd, struct supertype *st, if (sd2 == info) break; if (sd2 == NULL) { - sd2 = malloc(sizeof(*sd2)); + sd2 = xmalloc(sizeof(*sd2)); *sd2 = *info; sd2->next = sra->devs; sra->devs = sd2; @@ -1622,12 +1624,19 @@ int start_mdmon(int devnum) skipped = 0; for (i=0; paths[i]; i++) - if (paths[i][0]) - execl(paths[i], "mdmon", - devnum2devname(devnum), - NULL); + if (paths[i][0]) { + if (__offroot) { + execl(paths[i], "mdmon", "--offroot", + devnum2devname(devnum), + NULL); + } else { + execl(paths[i], "mdmon", + devnum2devname(devnum), + NULL); + } + } exit(1); - case -1: fprintf(stderr, Name ": cannot run mdmon. " + case -1: pr_err("cannot run mdmon. " "Array remains readonly\n"); return -1; default: /* parent - good */ @@ -1691,7 +1700,7 @@ int flush_metadata_updates(struct supertype *st) void append_metadata_update(struct supertype *st, void *buf, int len) { - struct metadata_update *mu = malloc(sizeof(*mu)); + struct metadata_update *mu = xmalloc(sizeof(*mu)); mu->buf = buf; mu->len = len; @@ -1713,7 +1722,7 @@ int experimental(void) if (check_env("MDADM_EXPERIMENTAL")) return 1; else { - fprintf(stderr, Name ": To use this feature MDADM_EXPERIMENTAL" + pr_err("To use this feature MDADM_EXPERIMENTAL" " environment variable has to be defined.\n"); return 0; } @@ -1779,3 +1788,43 @@ struct mdinfo *container_choose_spares(struct supertype *st, } return disks; } + +void *xmalloc(size_t len) +{ + void *rv = malloc(len); + char *msg; + if (rv) + return rv; + msg = Name ": memory allocation failure - aborting\n"; + exit(4+!!write(2, msg, strlen(msg))); +} + +void *xrealloc(void *ptr, size_t len) +{ + void *rv = realloc(ptr, len); + char *msg; + if (rv) + return rv; + msg = Name ": memory allocation failure - aborting\n"; + exit(4+!!write(2, msg, strlen(msg))); +} + +void *xcalloc(size_t num, size_t size) +{ + void *rv = calloc(num, size); + char *msg; + if (rv) + return rv; + msg = Name ": memory allocation failure - aborting\n"; + exit(4+!!write(2, msg, strlen(msg))); +} + +char *xstrdup(const char *str) +{ + char *rv = strdup(str); + char *msg; + if (rv) + return rv; + msg = Name ": memory allocation failure - aborting\n"; + exit(4+!!write(2, msg, strlen(msg))); +}