These will be used for ddf.
case 1:
case LEVEL_FAULTY:
case LEVEL_MULTIPATH:
+ case LEVEL_CONTAINER:
if (chunk) {
chunk = 0;
if (verbose > 0)
return 1;
}
+ if (st && ! st->ss->validate_geometry(st, level, layout, raiddisks,
+ chunk, size, NULL, NULL))
+ return 1;
+
/* now look at the subdevs */
info.array.active_disks = 0;
info.array.working_disks = 0;
dnum = 0;
for (dv=devlist; dv; dv=dv->next, dnum++) {
char *dname = dv->devname;
- unsigned long long ldsize, freesize;
+ unsigned long long freesize;
int fd;
if (strcasecmp(dname, "missing")==0) {
if (first_missing > dnum)
fail=1;
continue;
}
- if (!get_dev_size(fd, dname, &ldsize)) {
- fail = 1;
- close(fd);
- continue;
- }
if (st == NULL) {
struct createinfo *ci = conf_get_create_info();
if (ci)
}
if (st == NULL) {
/* Need to choose a default metadata, which is different
- * depending on the sizes of devices
+ * depending on geometry of array.
*/
int i;
char *name = "default";
- if (level >= 1 && ldsize > (0x7fffffffULL<<10))
- name = "default/large";
- for(i=0; !st && superlist[i]; i++)
+ for(i=0; !st && superlist[i]; i++) {
st = superlist[i]->match_metadata_desc(name);
+ if (st && !st->ss->validate_geometry
+ (st, level, layout, raiddisks,
+ chunk, size, dname, &freesize))
+ st = NULL;
+ }
if (!st) {
- fprintf(stderr, Name ": internal error - no default metadata style\n");
+ fprintf(stderr, Name ": device %s not suitable "
+ "for any style of array\n",
+ dname);
exit(2);
}
if (st->ss->major != 0 ||
" %d.%d metadata\n",
st->ss->major,
st->minor_version);
- }
- freesize = st->ss->avail_size(st, ldsize >> 9);
- if (freesize == 0) {
- fprintf(stderr, Name ": %s is too small: %luK\n",
- dname, (unsigned long)(ldsize>>10));
- fail = 1;
- close(fd);
- continue;
+ } else {
+ if (!st->ss->validate_geometry(st, level, layout,
+ raiddisks,
+ chunk, size, dname,
+ &freesize)) {
+
+ fprintf(stderr,
+ Name ": %s is not suitable for "
+ "this array.\n",
+ dname);
+ fail = 1;
+ continue;
+ }
}
freesize /= 2; /* convert to K */
if (size && freesize < size) {
fprintf(stderr, Name ": %s is smaller that given size."
- " %lluK < %lluK + superblock\n", dname, freesize, size);
+ " %lluK < %lluK + metadata\n",
+ dname, freesize, size);
fail = 1;
close(fd);
continue;
st->ss->free_super(st);
/* param is not actually used */
- if (runstop == 1 || subdevs >= raiddisks) {
+ if (level == LEVEL_CONTAINER)
+ /* No need to start */
+ ;
+ else if (runstop == 1 || subdevs >= raiddisks) {
mdu_param_t param;
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
{ "raid10", 10},
{ "10", 10},
{ "faulty", LEVEL_FAULTY},
+ { "container", LEVEL_CONTAINER},
{ NULL, 0}
};
void (*locate_bitmap)(struct supertype *st, int fd);
int (*write_bitmap)(struct supertype *st, int fd);
void (*free_super)(struct supertype *st);
+ int (*validate_geometry)(struct supertype *st, int level, int layout,
+ int raiddisks,
+ int chunk, unsigned long long size,
+ char *subdev, unsigned long long *freesize);
int major;
int swapuuid; /* true if uuid is bigending rather than hostendian */
} super0, super1, *superlist[];
#define LEVEL_LINEAR (-1)
#define LEVEL_FAULTY (-5)
+/* kernel module doesn't know about these */
+#define LEVEL_CONTAINER (-100)
+
/* faulty stuff */
st->sb = NULL;
}
+static int validate_geometry0(struct supertype *st, int level,
+ int layout, int raiddisks,
+ int chunk, unsigned long long size,
+ char *subdev, unsigned long long *freesize)
+{
+ unsigned long long ldsize;
+ int fd;
+
+ if (level == LEVEL_CONTAINER)
+ return 0;
+ if (raiddisks > MD_SB_DISKS)
+ return 0;
+ if (size > (0x7fffffffULL<<10))
+ return 0;
+ if (!subdev)
+ return 1;
+
+ fd = open(subdev, O_RDONLY|O_EXCL, 0);
+ if (fd < 0) {
+ fprintf(stderr, Name ": Cannot open %s: %s\n",
+ subdev, strerror(errno));
+ return 0;
+ }
+ if (!get_dev_size(fd, subdev, &ldsize)) {
+ close(fd);
+ return 0;
+ }
+ close(fd);
+
+ if (ldsize < MD_RESERVED_SECTORS * 512)
+ return 0;
+ if (size > (0x7fffffffULL<<10))
+ return 0;
+ *freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
+ return 1;
+}
+
struct superswitch super0 = {
#ifndef MDASSEMBLE
.examine_super = examine_super0,
.locate_bitmap = locate_bitmap0,
.write_bitmap = write_bitmap0,
.free_super = free_super0,
+ .validate_geometry = validate_geometry0,
.major = 0,
.swapuuid = 0,
};
return st;
}
if (strcmp(arg, "1") == 0 ||
- strcmp(arg, "default/large") == 0) {
+ strcmp(arg, "default") == 0) {
st->minor_version = -1;
return st;
}
st->sb = NULL;
}
+static int validate_geometry1(struct supertype *st, int level,
+ int layout, int raiddisks,
+ int chunk, unsigned long long size,
+ char *subdev, unsigned long long *freesize)
+{
+ unsigned long long ldsize;
+ int fd;
+
+ if (level == LEVEL_CONTAINER)
+ return 0;
+ if (!subdev)
+ return 1;
+
+ fd = open(subdev, O_RDONLY|O_EXCL, 0);
+ if (fd < 0) {
+ fprintf(stderr, Name ": Cannot open %s: %s\n",
+ subdev, strerror(errno));
+ return 0;
+ }
+ if (!get_dev_size(fd, subdev, &ldsize)) {
+ close(fd);
+ return 0;
+ }
+ close(fd);
+
+ *freesize = avail_size1(st, ldsize >> 9);
+ return 1;
+}
+
struct superswitch super1 = {
#ifndef MDASSEMBLE
.examine_super = examine_super1,
.locate_bitmap = locate_bitmap1,
.write_bitmap = write_bitmap1,
.free_super = free_super1,
+ .validate_geometry = validate_geometry1,
.major = 1,
#if __BYTE_ORDER == BIG_ENDIAN
.swapuuid = 0,