#include <dirent.h>
#include <signal.h>
+int __offroot;
+
/*
* following taken from linux/blkpg.h because they aren't
* anywhere else and it isn't safe to #include linux/ * stuff.
* 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);
}
}
if (*c)
- s = 0;
+ s = -1;
return s;
}
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
struct mdu_array_info_s array;
struct mdu_disk_info_s disk;
int avail_disks = 0;
- int i;
+ int i, rv;
char *avail;
if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 ||
avail[disk.raid_disk] = 1;
}
/* This is used on an active array, so assume it is clean */
- return enough(array.level, array.raid_disks, array.layout,
- 1,
- avail, avail_disks);
+ rv = enough(array.level, array.raid_disks, array.layout,
+ 1, avail);
+ free(avail);
+ return rv;
}
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;
}
char *dev = verstr+1;
subarray = strchr(dev, '/');
- if (subarray)
+ if (subarray) {
*subarray++ = '\0';
- subarray = strdup(subarray);
+ subarray = strdup(subarray);
+ }
container = devname2devnum(dev);
if (sra)
sysfs_free(sra);
{
struct GPT gpt;
unsigned char empty_gpt_entry[16]= {0};
- struct GPT_part_entry part;
+ struct GPT_part_entry *part;
+ char buf[512];
unsigned long long curr_part_end;
unsigned all_partitions, entry_size;
unsigned part_nr;
/* sanity checks */
if (all_partitions > 1024 ||
- entry_size > 512)
+ entry_size > sizeof(buf))
return -1;
+ part = (struct GPT_part_entry *)buf;
+
for (part_nr=0; part_nr < all_partitions; part_nr++) {
/* read partition entry */
- if (read(fd, &part, entry_size) != (ssize_t)entry_size)
+ if (read(fd, buf, entry_size) != (ssize_t)entry_size)
return 0;
/* is this valid partition? */
- if (memcmp(part.type_guid, empty_gpt_entry, 16) != 0) {
+ if (memcmp(part->type_guid, empty_gpt_entry, 16) != 0) {
/* check the last lba for the current partition */
- curr_part_end = __le64_to_cpu(part.ending_lba);
+ curr_part_end = __le64_to_cpu(part->ending_lba);
if (curr_part_end > *endofpart)
*endofpart = curr_part_end;
}
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. "
"Array remains readonly\n");