summaryrefslogtreecommitdiffstats
path: root/Create.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-05-15 16:47:41 +1000
committerNeil Brown <neilb@suse.de>2008-05-15 16:47:41 +1000
commit17f25ca6fb71221f4fa7891c0037f88d26dbc67c (patch)
treee233a0ca2461dbd4d27e0d69c90466b06ffc75ec /Create.c
parent2270232245dc189807e6ca36835b44146377fc37 (diff)
downloadmdadm-17f25ca6fb71221f4fa7891c0037f88d26dbc67c.tar.gz
mdadm-17f25ca6fb71221f4fa7891c0037f88d26dbc67c.tar.xz
mdadm-17f25ca6fb71221f4fa7891c0037f88d26dbc67c.zip
Add 'container' level and ->validate_geometry method.
These will be used for ddf.
Diffstat (limited to 'Create.c')
-rw-r--r--Create.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/Create.c b/Create.c
index 8407579..d423585 100644
--- a/Create.c
+++ b/Create.c
@@ -182,6 +182,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
case 1:
case LEVEL_FAULTY:
case LEVEL_MULTIPATH:
+ case LEVEL_CONTAINER:
if (chunk) {
chunk = 0;
if (verbose > 0)
@@ -193,13 +194,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
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)
@@ -219,11 +224,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
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)
@@ -231,17 +231,22 @@ int Create(struct supertype *st, char *mddev, int mdfd,
}
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 ||
@@ -250,14 +255,19 @@ int Create(struct supertype *st, char *mddev, int mdfd,
" %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 */
@@ -268,7 +278,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
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;
@@ -581,7 +592,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
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, &param)) {
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",